Skip to content

Commit c54c8cb

Browse files
committed
Auto merge of #106582 - compiler-errors:better-spans-on-bad-tys, r=lcnr
Improve spans of non-WF implied bound types Fixes #60980
2 parents 2e677c0 + e77e8eb commit c54c8cb

18 files changed

+89
-127
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+25-40
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,22 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
9797
let infcx = &tcx.infer_ctxt().build();
9898
let ocx = ObligationCtxt::new(infcx);
9999

100-
let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id);
101-
102100
let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };
103101

104102
if !tcx.features().trivial_bounds {
105103
wfcx.check_false_global_bounds()
106104
}
107105
f(&mut wfcx);
106+
107+
let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id);
108+
let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
109+
108110
let errors = wfcx.select_all_or_error();
109111
if !errors.is_empty() {
110112
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
111113
return;
112114
}
113115

114-
let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
115116
let outlives_environment =
116117
OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
117118

@@ -1489,54 +1490,38 @@ fn check_fn_or_method<'tcx>(
14891490
def_id: LocalDefId,
14901491
) {
14911492
let tcx = wfcx.tcx();
1492-
let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
1493+
let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
14931494

14941495
// Normalize the input and output types one at a time, using a different
14951496
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
14961497
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
14971498
// for each type, preventing the HIR wf check from generating
14981499
// a nice error message.
1499-
let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
1500-
inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
1501-
wfcx.normalize(
1502-
span,
1503-
Some(WellFormedLoc::Param {
1504-
function: def_id,
1505-
// Note that the `param_idx` of the output type is
1506-
// one greater than the index of the last input type.
1507-
param_idx: i.try_into().unwrap(),
1508-
}),
1509-
ty,
1510-
)
1511-
}));
1512-
// Manually call `normalize_associated_types_in` on the other types
1513-
// in `FnSig`. This ensures that if the types of these fields
1514-
// ever change to include projections, we will start normalizing
1515-
// them automatically.
1516-
let sig = ty::FnSig {
1517-
inputs_and_output,
1518-
c_variadic: wfcx.normalize(span, None, c_variadic),
1519-
unsafety: wfcx.normalize(span, None, unsafety),
1520-
abi: wfcx.normalize(span, None, abi),
1521-
};
1500+
let arg_span =
1501+
|idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
1502+
1503+
sig.inputs_and_output =
1504+
tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
1505+
wfcx.normalize(
1506+
arg_span(idx),
1507+
Some(WellFormedLoc::Param {
1508+
function: def_id,
1509+
// Note that the `param_idx` of the output type is
1510+
// one greater than the index of the last input type.
1511+
param_idx: idx.try_into().unwrap(),
1512+
}),
1513+
ty,
1514+
)
1515+
}));
15221516

1523-
for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
1517+
for (idx, ty) in sig.inputs_and_output.iter().enumerate() {
15241518
wfcx.register_wf_obligation(
1525-
ty.span,
1526-
Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }),
1527-
input_ty.into(),
1519+
arg_span(idx),
1520+
Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
1521+
ty.into(),
15281522
);
15291523
}
15301524

1531-
wfcx.register_wf_obligation(
1532-
hir_decl.output.span(),
1533-
Some(WellFormedLoc::Param {
1534-
function: def_id,
1535-
param_idx: sig.inputs().len().try_into().unwrap(),
1536-
}),
1537-
sig.output().into(),
1538-
);
1539-
15401525
check_where_clauses(wfcx, span, def_id);
15411526

15421527
check_return_position_impl_trait_in_trait_bounds(

src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `Self: Get` is not satisfied
2-
--> $DIR/associated-types-for-unimpl-trait.rs:10:5
2+
--> $DIR/associated-types-for-unimpl-trait.rs:10:40
33
|
44
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
5+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
66
|
77
help: consider further restricting `Self`
88
|

src/test/ui/associated-types/associated-types-no-suitable-bound.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `T: Get` is not satisfied
2-
--> $DIR/associated-types-no-suitable-bound.rs:11:5
2+
--> $DIR/associated-types-no-suitable-bound.rs:11:21
33
|
44
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
5+
| ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
66
|
77
help: consider restricting type parameter `T`
88
|

src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `Self: Get` is not satisfied
2-
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
2+
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
33
|
44
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
5+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
66
|
77
help: consider further restricting `Self`
88
|

src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0277]: the trait bound `(T, U): Get` is not satisfied
2-
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
2+
--> $DIR/associated-types-no-suitable-supertrait.rs:22:40
33
|
44
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
5+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
66

77
error[E0277]: the trait bound `Self: Get` is not satisfied
8-
--> $DIR/associated-types-no-suitable-supertrait.rs:17:5
8+
--> $DIR/associated-types-no-suitable-supertrait.rs:17:40
99
|
1010
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
11+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
1212
|
1313
help: consider further restricting `Self`
1414
|

src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `Self: Get` is not satisfied
2-
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5
2+
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
33
|
44
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
5+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
66
|
77
help: consider further restricting `Self`
88
|

src/test/ui/associated-types/issue-59324.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ pub trait ThriftService<Bug: NotFoo>:
1515
{
1616
fn get_service(
1717
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
18-
//~| ERROR the trait bound `Bug: Foo` is not satisfied
1918
&self,
2019
) -> Self::AssocType;
20+
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
2121
}
2222

2323
fn with_factory<H>(factory: dyn ThriftService<()>) {}

src/test/ui/associated-types/issue-59324.stderr

+6-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | |
2020
LL | |
2121
LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
2222
... |
23-
LL | | ) -> Self::AssocType;
23+
LL | |
2424
LL | | }
2525
| |_^ the trait `Foo` is not implemented for `Bug`
2626
|
@@ -34,7 +34,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
3434
|
3535
LL | / fn get_service(
3636
LL | |
37-
LL | |
3837
LL | | &self,
3938
LL | | ) -> Self::AssocType;
4039
| |_________________________^ the trait `Foo` is not implemented for `Bug`
@@ -45,20 +44,16 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
4544
| +++++
4645

4746
error[E0277]: the trait bound `(): Foo` is not satisfied
48-
--> $DIR/issue-59324.rs:23:1
47+
--> $DIR/issue-59324.rs:23:29
4948
|
5049
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
50+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
5251

5352
error[E0277]: the trait bound `Bug: Foo` is not satisfied
54-
--> $DIR/issue-59324.rs:16:5
53+
--> $DIR/issue-59324.rs:19:10
5554
|
56-
LL | / fn get_service(
57-
LL | |
58-
LL | |
59-
LL | | &self,
60-
LL | | ) -> Self::AssocType;
61-
| |_________________________^ the trait `Foo` is not implemented for `Bug`
55+
LL | ) -> Self::AssocType;
56+
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
6257
|
6358
help: consider further restricting this bound
6459
|

src/test/ui/issues/issue-18611.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
error[E0277]: the trait bound `isize: HasState` is not satisfied
2-
--> $DIR/issue-18611.rs:1:1
2+
--> $DIR/issue-18611.rs:1:18
33
|
4-
LL | / fn add_state(op: <isize as HasState>::State) {
5-
LL | |
6-
LL | | }
7-
| |_^ the trait `HasState` is not implemented for `isize`
4+
LL | fn add_state(op: <isize as HasState>::State) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
86

97
error: aborting due to previous error
108

src/test/ui/issues/issue-20831-debruijn.stderr

+6-18
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
2-
--> $DIR/issue-20831-debruijn.rs:28:5
2+
--> $DIR/issue-20831-debruijn.rs:28:33
33
|
4-
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
5-
LL | | // Not obvious, but there is an implicit lifetime here -------^
6-
LL | |
7-
LL | | //
8-
... |
9-
LL | | self.sub = t;
10-
LL | | }
11-
| |_____^
4+
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
126
|
137
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
148
--> $DIR/issue-20831-debruijn.rs:28:58
@@ -21,16 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
2115
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
2216
| ^^
2317
note: ...so that the types are compatible
24-
--> $DIR/issue-20831-debruijn.rs:28:5
18+
--> $DIR/issue-20831-debruijn.rs:28:33
2519
|
26-
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
27-
LL | | // Not obvious, but there is an implicit lifetime here -------^
28-
LL | |
29-
LL | | //
30-
... |
31-
LL | | self.sub = t;
32-
LL | | }
33-
| |_____^
20+
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3422
= note: expected `<MyStruct<'a> as Publisher<'_>>`
3523
found `<MyStruct<'_> as Publisher<'_>>`
3624

src/test/ui/issues/issue-35570.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
2+
--> $DIR/issue-35570.rs:8:40
3+
|
4+
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
6+
17
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
28
--> $DIR/issue-35570.rs:8:1
39
|
@@ -8,12 +14,6 @@ LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)};
814
LL | | }
915
| |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
1016

11-
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
12-
--> $DIR/issue-35570.rs:8:40
13-
|
14-
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
15-
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
16-
1717
error: aborting due to 2 previous errors
1818

1919
For more information about this error, try `rustc --explain E0277`.

src/test/ui/nll/normalization-bounds-error.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
2-
--> $DIR/normalization-bounds-error.rs:12:1
2+
--> $DIR/normalization-bounds-error.rs:12:31
33
|
44
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
88
--> $DIR/normalization-bounds-error.rs:12:14
@@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
1515
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
1616
| ^^
1717
note: ...so that the types are compatible
18-
--> $DIR/normalization-bounds-error.rs:12:1
18+
--> $DIR/normalization-bounds-error.rs:12:31
1919
|
2020
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2222
= note: expected `Visitor<'d>`
2323
found `Visitor<'_>`
2424

src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
2-
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
2+
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
33
|
4-
LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
5-
LL | |
6-
LL | |
7-
LL | | {
8-
LL | | }
9-
| |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
4+
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
106
|
117
help: consider restricting type parameter `T`
128
|
139
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
1410
| ++++++++++++++++++++++++
1511

1612
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
17-
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
13+
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
1814
|
19-
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
20-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
15+
LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
16+
LL | |
17+
LL | |
18+
LL | | {
19+
LL | | }
20+
| |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
2121
|
2222
help: consider restricting type parameter `T`
2323
|

src/test/ui/specialization/min_specialization/issue-79224.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ impl ToString for Cow<'_, str> {
1515
}
1616
}
1717

18-
impl<B: ?Sized> Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
19-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
18+
impl<B: ?Sized> Display for Cow<'_, B> {
19+
//~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
20+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21+
//~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
2022
write!(f, "foo")
2123
}
2224
}

src/test/ui/specialization/min_specialization/issue-79224.stderr

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
error[E0277]: the trait bound `B: Clone` is not satisfied
2-
--> $DIR/issue-79224.rs:18:1
2+
--> $DIR/issue-79224.rs:18:17
33
|
4-
LL | / impl<B: ?Sized> Display for Cow<'_, B> {
5-
LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6-
LL | | write!(f, "foo")
7-
LL | | }
8-
LL | | }
9-
| |_^ the trait `Clone` is not implemented for `B`
4+
LL | impl<B: ?Sized> Display for Cow<'_, B> {
5+
| ^^^^^^^ the trait `Clone` is not implemented for `B`
106
|
117
= note: required for `B` to implement `ToOwned`
128
help: consider further restricting this bound
@@ -15,12 +11,10 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
1511
| +++++++++++++++++++
1612

1713
error[E0277]: the trait bound `B: Clone` is not satisfied
18-
--> $DIR/issue-79224.rs:19:5
14+
--> $DIR/issue-79224.rs:20:12
1915
|
20-
LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21-
LL | | write!(f, "foo")
22-
LL | | }
23-
| |_____^ the trait `Clone` is not implemented for `B`
16+
LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17+
| ^^^^^ the trait `Clone` is not implemented for `B`
2418
|
2519
= note: required for `B` to implement `ToOwned`
2620
help: consider further restricting this bound

0 commit comments

Comments
 (0)