File tree Expand file tree Collapse file tree 3 files changed +78
-2
lines changed
compiler/rustc_next_trait_solver/src/solve/normalizes_to Expand file tree Collapse file tree 3 files changed +78
-2
lines changed Original file line number Diff line number Diff line change @@ -238,8 +238,24 @@ where
238
238
// delay a bug because we can have trivially false where clauses, so we
239
239
// treat it as rigid.
240
240
if cx.impl_self_is_guaranteed_unsized(impl_def_id) {
241
- ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
242
- return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
241
+ match ecx.typing_mode() {
242
+ ty::TypingMode::Coherence => {
243
+ return ecx.evaluate_added_goals_and_make_canonical_response(
244
+ Certainty::AMBIGUOUS,
245
+ );
246
+ }
247
+ ty::TypingMode::Analysis { .. }
248
+ | ty::TypingMode::Borrowck { .. }
249
+ | ty::TypingMode::PostBorrowckAnalysis { .. }
250
+ | ty::TypingMode::PostAnalysis => {
251
+ ecx.structurally_instantiate_normalizes_to_term(
252
+ goal,
253
+ goal.predicate.alias,
254
+ );
255
+ return ecx
256
+ .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
257
+ }
258
+ }
243
259
} else {
244
260
return error_response(ecx, cx.delay_bug("missing item"));
245
261
}
Original file line number Diff line number Diff line change
1
+ // Make sure we don't treat missing associated items as rigid
2
+ // during coherence, even if we know they've got an impossible
3
+ // `Sized`-bound. As we check whether the self type is definitely
4
+ // not `Sized` outside of coherence, this check can be incomplete.
5
+ //
6
+ // In this test we only use `impl<T> Overlap<u32> for T` to normalize
7
+ // the field of `MaybeUnsized<T, u32>` when checking whether it's
8
+ // definitely not `Sized`. However, for `MaybeUnsized<u32, u32>` we
9
+ // could also use `impl<U> Overlap<U> for u32` for normalization, which
10
+ // would result in a `Sized` type. cc #139000
11
+
12
+ struct MaybeUnsized<T: Overlap<U>, U>(<T as Overlap<U>>::MaybeUnsized);
13
+
14
+ trait ReqSized {
15
+ type Missing1
16
+ where
17
+ Self: Sized;
18
+ type Missing2
19
+ where
20
+ Self: Sized;
21
+ }
22
+ impl<T> ReqSized for MaybeUnsized<T, u32> {}
23
+
24
+ struct W<T: ?Sized>(T);
25
+ trait Eq<T> {}
26
+ impl<T> Eq<T> for W<T> {}
27
+
28
+ trait RelateReqSized {}
29
+ impl<T: ReqSized> RelateReqSized for T where W<T::Missing1>: Eq<T::Missing2> {}
30
+
31
+ trait Overlap<U> {
32
+ type MaybeUnsized: ?Sized;
33
+ }
34
+ impl<T> Overlap<u32> for T {
35
+ type MaybeUnsized = str;
36
+ }
37
+ impl<U> Overlap<U> for u32
38
+ //~^ ERROR conflicting implementations of trait `Overlap<u32>` for type `u32`
39
+ where
40
+ MaybeUnsized<U, u32>: RelateReqSized,
41
+ {
42
+ type MaybeUnsized = u32;
43
+ }
44
+
45
+ fn main() {}
Original file line number Diff line number Diff line change
1
+ error[E0119]: conflicting implementations of trait `Overlap<u32>` for type `u32`
2
+ --> $DIR/trivial-unsized-projection-in-coherence.rs:37:1
3
+ |
4
+ LL | impl<T> Overlap<u32> for T {
5
+ | -------------------------- first implementation here
6
+ ...
7
+ LL | / impl<U> Overlap<U> for u32
8
+ LL | |
9
+ LL | | where
10
+ LL | | MaybeUnsized<U, u32>: RelateReqSized,
11
+ | |_________________________________________^ conflicting implementation for `u32`
12
+
13
+ error: aborting due to 1 previous error
14
+
15
+ For more information about this error, try `rustc --explain E0119`.
You can’t perform that action at this time.
0 commit comments