mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 06:26:55 +00:00
Make unnormalizable item ambiguous in coherence
This commit is contained in:
parent
830aeb6102
commit
6cd724bb43
@ -238,8 +238,24 @@ where
|
||||
// delay a bug because we can have trivially false where clauses, so we
|
||||
// treat it as rigid.
|
||||
if cx.impl_self_is_guaranteed_unsized(impl_def_id) {
|
||||
ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
|
||||
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
|
||||
match ecx.typing_mode() {
|
||||
ty::TypingMode::Coherence => {
|
||||
return ecx.evaluate_added_goals_and_make_canonical_response(
|
||||
Certainty::AMBIGUOUS,
|
||||
);
|
||||
}
|
||||
ty::TypingMode::Analysis { .. }
|
||||
| ty::TypingMode::Borrowck { .. }
|
||||
| ty::TypingMode::PostBorrowckAnalysis { .. }
|
||||
| ty::TypingMode::PostAnalysis => {
|
||||
ecx.structurally_instantiate_normalizes_to_term(
|
||||
goal,
|
||||
goal.predicate.alias,
|
||||
);
|
||||
return ecx
|
||||
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return error_response(ecx, cx.delay_bug("missing item"));
|
||||
}
|
||||
|
45
tests/ui/traits/trivial-unsized-projection-in-coherence.rs
Normal file
45
tests/ui/traits/trivial-unsized-projection-in-coherence.rs
Normal file
@ -0,0 +1,45 @@
|
||||
// Make sure we don't treat missing associated items as rigid
|
||||
// during coherence, even if we know they've got an impossible
|
||||
// `Sized`-bound. As we check whether the self type is definitely
|
||||
// not `Sized` outside of coherence, this check can be incomplete.
|
||||
//
|
||||
// In this test we only use `impl<T> Overlap<u32> for T` to normalize
|
||||
// the field of `MaybeUnsized<T, u32>` when checking whether it's
|
||||
// definitely not `Sized`. However, for `MaybeUnsized<u32, u32>` we
|
||||
// could also use `impl<U> Overlap<U> for u32` for normalization, which
|
||||
// would result in a `Sized` type. cc #139000
|
||||
|
||||
struct MaybeUnsized<T: Overlap<U>, U>(<T as Overlap<U>>::MaybeUnsized);
|
||||
|
||||
trait ReqSized {
|
||||
type Missing1
|
||||
where
|
||||
Self: Sized;
|
||||
type Missing2
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
impl<T> ReqSized for MaybeUnsized<T, u32> {}
|
||||
|
||||
struct W<T: ?Sized>(T);
|
||||
trait Eq<T> {}
|
||||
impl<T> Eq<T> for W<T> {}
|
||||
|
||||
trait RelateReqSized {}
|
||||
impl<T: ReqSized> RelateReqSized for T where W<T::Missing1>: Eq<T::Missing2> {}
|
||||
|
||||
trait Overlap<U> {
|
||||
type MaybeUnsized: ?Sized;
|
||||
}
|
||||
impl<T> Overlap<u32> for T {
|
||||
type MaybeUnsized = str;
|
||||
}
|
||||
impl<U> Overlap<U> for u32
|
||||
//~^ ERROR conflicting implementations of trait `Overlap<u32>` for type `u32`
|
||||
where
|
||||
MaybeUnsized<U, u32>: RelateReqSized,
|
||||
{
|
||||
type MaybeUnsized = u32;
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,15 @@
|
||||
error[E0119]: conflicting implementations of trait `Overlap<u32>` for type `u32`
|
||||
--> $DIR/trivial-unsized-projection-in-coherence.rs:37:1
|
||||
|
|
||||
LL | impl<T> Overlap<u32> for T {
|
||||
| -------------------------- first implementation here
|
||||
...
|
||||
LL | / impl<U> Overlap<U> for u32
|
||||
LL | |
|
||||
LL | | where
|
||||
LL | | MaybeUnsized<U, u32>: RelateReqSized,
|
||||
| |_________________________________________^ conflicting implementation for `u32`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
Loading…
Reference in New Issue
Block a user