Skip to content

Commit 4d483f5

Browse files
Detect cases when user written object assoc bound differs from elaborated non-self-referential bound
1 parent f5be3ca commit 4d483f5

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
22
use rustc_errors::codes::*;
33
use rustc_errors::struct_span_code_err;
44
use rustc_hir as hir;
@@ -62,6 +62,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
6262

6363
let mut trait_bounds = vec![];
6464
let mut projection_bounds = vec![];
65+
let mut uwu = FxHashMap::default();
66+
6567
for (pred, span) in bounds.clauses() {
6668
let bound_pred = pred.kind();
6769
match bound_pred.skip_binder() {
@@ -71,6 +73,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7173
}
7274
ty::ClauseKind::Projection(proj) => {
7375
projection_bounds.push((bound_pred.rebind(proj), span));
76+
uwu.insert(proj.def_id(), (bound_pred.rebind(proj.term), span));
7477
}
7578
ty::ClauseKind::TypeOutlives(_) => {
7679
// Do nothing, we deal with regions separately
@@ -176,6 +179,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
176179
projection_bounds.push((pred, original_span));
177180
}
178181

182+
if !references_self
183+
&& let Some(&(user_written, span)) = uwu.get(&pred.projection_def_id())
184+
{
185+
let user_written = tcx.anonymize_bound_vars(user_written);
186+
let elaborated =
187+
tcx.anonymize_bound_vars(pred.map_bound(|pred| pred.term));
188+
if user_written != elaborated {
189+
self.dcx().span_err(
190+
span,
191+
format!("expected {user_written}, found {elaborated}"),
192+
);
193+
}
194+
}
195+
179196
self.check_elaborated_projection_mentions_input_lifetimes(
180197
pred,
181198
original_span,
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: expected u32, found i32
2+
--> $DIR/associated-types-overridden-binding-2.rs:6:29
3+
|
4+
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
5+
| ^^^^^^^^^^
6+
17
error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `i32`, but it yields `u32`
28
--> $DIR/associated-types-overridden-binding-2.rs:6:43
39
|
@@ -6,6 +12,6 @@ LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
612
|
713
= note: required for the cast from `&std::vec::IntoIter<u32>` to `&dyn Iterator<Item = u32, Item = i32>`
814

9-
error: aborting due to 1 previous error
15+
error: aborting due to 2 previous errors
1016

1117
For more information about this error, try `rustc --explain E0271`.

tests/ui/associated-types/associated-types-overridden-binding.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ note: required by a bound in `I32Iterator`
2222
LL | trait I32Iterator = Iterator<Item = i32>;
2323
| ^^^^^^^^^^ required by this bound in `I32Iterator`
2424

25-
error: aborting due to 2 previous errors
25+
error: expected u32, found i32
26+
--> $DIR/associated-types-overridden-binding.rs:10:29
27+
|
28+
LL | let _: &dyn I32Iterator<Item = u32>;
29+
| ^^^^^^^^^^
30+
31+
error: aborting due to 3 previous errors
2632

2733
For more information about this error, try `rustc --explain E0284`.

tests/ui/traits/object/pretty.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
error: expected u16, found u8
2+
--> $DIR/pretty.rs:28:34
3+
|
4+
LL | fn dyn_fixed_multi(x: &dyn Fixed<Assoc = u16>) { x }
5+
| ^^^^^^^^^^^
6+
7+
error: expected &'a u8, found for<'a> &'a u8
8+
--> $DIR/pretty.rs:36:62
9+
|
10+
LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x }
11+
| ^^^^^^^^^^^^
12+
113
warning: unnecessary associated type bound for dyn-incompatible associated type
214
--> $DIR/pretty.rs:41:35
315
|
@@ -161,6 +173,6 @@ LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
161173
= note: expected unit type `()`
162174
found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
163175

164-
error: aborting due to 14 previous errors; 1 warning emitted
176+
error: aborting due to 16 previous errors; 1 warning emitted
165177

166178
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)