Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve spans of non-WF implied bound types #106582

Merged
merged 3 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 25 additions & 40 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,22 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
let infcx = &tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(infcx);

let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id);

let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };

if !tcx.features().trivial_bounds {
wfcx.check_false_global_bounds()
}
f(&mut wfcx);

let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id);
let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);

let errors = wfcx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
return;
}

let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
let outlives_environment =
OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);

Expand Down Expand Up @@ -1489,54 +1490,38 @@ fn check_fn_or_method<'tcx>(
def_id: LocalDefId,
) {
let tcx = wfcx.tcx();
let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);

// Normalize the input and output types one at a time, using a different
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
// for each type, preventing the HIR wf check from generating
// a nice error message.
let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
wfcx.normalize(
span,
Some(WellFormedLoc::Param {
function: def_id,
// Note that the `param_idx` of the output type is
// one greater than the index of the last input type.
param_idx: i.try_into().unwrap(),
}),
ty,
)
}));
// Manually call `normalize_associated_types_in` on the other types
// in `FnSig`. This ensures that if the types of these fields
// ever change to include projections, we will start normalizing
// them automatically.
let sig = ty::FnSig {
inputs_and_output,
c_variadic: wfcx.normalize(span, None, c_variadic),
unsafety: wfcx.normalize(span, None, unsafety),
abi: wfcx.normalize(span, None, abi),
};
let arg_span =
|idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);

sig.inputs_and_output =
tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
wfcx.normalize(
arg_span(idx),
Some(WellFormedLoc::Param {
function: def_id,
// Note that the `param_idx` of the output type is
// one greater than the index of the last input type.
param_idx: idx.try_into().unwrap(),
}),
ty,
)
}));

for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
for (idx, ty) in sig.inputs_and_output.iter().enumerate() {
wfcx.register_wf_obligation(
ty.span,
Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }),
input_ty.into(),
arg_span(idx),
Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
ty.into(),
);
}

wfcx.register_wf_obligation(
hir_decl.output.span(),
Some(WellFormedLoc::Param {
function: def_id,
param_idx: sig.inputs().len().try_into().unwrap(),
}),
sig.output().into(),
);

check_where_clauses(wfcx, span, def_id);

check_return_position_impl_trait_in_trait_bounds(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-for-unimpl-trait.rs:10:5
--> $DIR/associated-types-for-unimpl-trait.rs:10:40
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Get` is not satisfied
--> $DIR/associated-types-no-suitable-bound.rs:11:5
--> $DIR/associated-types-no-suitable-bound.rs:11:21
|
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
| ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error[E0277]: the trait bound `(T, U): Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
--> $DIR/associated-types-no-suitable-supertrait.rs:22:40
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`

error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:17:5
--> $DIR/associated-types-no-suitable-supertrait.rs:17:40
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
|
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
| ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/issue-59324.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ pub trait ThriftService<Bug: NotFoo>:
{
fn get_service(
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
//~| ERROR the trait bound `Bug: Foo` is not satisfied
&self,
) -> Self::AssocType;
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
}

fn with_factory<H>(factory: dyn ThriftService<()>) {}
Expand Down
17 changes: 6 additions & 11 deletions src/test/ui/associated-types/issue-59324.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ LL | |
LL | |
LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
... |
LL | | ) -> Self::AssocType;
LL | |
LL | | }
| |_^ the trait `Foo` is not implemented for `Bug`
|
Expand All @@ -34,7 +34,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
LL | / fn get_service(
LL | |
LL | |
LL | | &self,
LL | | ) -> Self::AssocType;
| |_________________________^ the trait `Foo` is not implemented for `Bug`
Expand All @@ -45,20 +44,16 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++

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

error[E0277]: the trait bound `Bug: Foo` is not satisfied
--> $DIR/issue-59324.rs:16:5
--> $DIR/issue-59324.rs:19:10
|
LL | / fn get_service(
LL | |
LL | |
LL | | &self,
LL | | ) -> Self::AssocType;
| |_________________________^ the trait `Foo` is not implemented for `Bug`
LL | ) -> Self::AssocType;
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
help: consider further restricting this bound
|
Expand Down
8 changes: 3 additions & 5 deletions src/test/ui/issues/issue-18611.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error[E0277]: the trait bound `isize: HasState` is not satisfied
--> $DIR/issue-18611.rs:1:1
--> $DIR/issue-18611.rs:1:18
|
LL | / fn add_state(op: <isize as HasState>::State) {
LL | |
LL | | }
| |_^ the trait `HasState` is not implemented for `isize`
LL | fn add_state(op: <isize as HasState>::State) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`

error: aborting due to previous error

Expand Down
24 changes: 6 additions & 18 deletions src/test/ui/issues/issue-20831-debruijn.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> $DIR/issue-20831-debruijn.rs:28:5
--> $DIR/issue-20831-debruijn.rs:28:33
|
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
LL | | // Not obvious, but there is an implicit lifetime here -------^
LL | |
LL | | //
... |
LL | | self.sub = t;
LL | | }
| |_____^
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> $DIR/issue-20831-debruijn.rs:28:58
Expand All @@ -21,16 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
| ^^
note: ...so that the types are compatible
--> $DIR/issue-20831-debruijn.rs:28:5
--> $DIR/issue-20831-debruijn.rs:28:33
|
LL | / fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
LL | | // Not obvious, but there is an implicit lifetime here -------^
LL | |
LL | | //
... |
LL | | self.sub = t;
LL | | }
| |_____^
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `<MyStruct<'a> as Publisher<'_>>`
found `<MyStruct<'_> as Publisher<'_>>`

Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-35570.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
--> $DIR/issue-35570.rs:8:40
|
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`

error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
--> $DIR/issue-35570.rs:8:1
|
Expand All @@ -8,12 +14,6 @@ LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)};
LL | | }
| |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`

error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
--> $DIR/issue-35570.rs:8:40
|
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
8 changes: 4 additions & 4 deletions src/test/ui/nll/normalization-bounds-error.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
--> $DIR/normalization-bounds-error.rs:12:1
--> $DIR/normalization-bounds-error.rs:12:31
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
--> $DIR/normalization-bounds-error.rs:12:14
Expand All @@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
note: ...so that the types are compatible
--> $DIR/normalization-bounds-error.rs:12:1
--> $DIR/normalization-bounds-error.rs:12:31
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Visitor<'d>`
found `Visitor<'_>`

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
|
LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
LL | |
LL | |
LL | | {
LL | | }
| |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ++++++++++++++++++++++++

error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
LL | |
LL | |
LL | | {
LL | | }
| |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/specialization/min_specialization/issue-79224.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ impl ToString for Cow<'_, str> {
}
}

impl<B: ?Sized> Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
impl<B: ?Sized> Display for Cow<'_, B> {
//~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
write!(f, "foo")
}
}
Expand Down
18 changes: 6 additions & 12 deletions src/test/ui/specialization/min_specialization/issue-79224.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
error[E0277]: the trait bound `B: Clone` is not satisfied
--> $DIR/issue-79224.rs:18:1
--> $DIR/issue-79224.rs:18:17
|
LL | / impl<B: ?Sized> Display for Cow<'_, B> {
LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
LL | | write!(f, "foo")
LL | | }
LL | | }
| |_^ the trait `Clone` is not implemented for `B`
LL | impl<B: ?Sized> Display for Cow<'_, B> {
| ^^^^^^^ the trait `Clone` is not implemented for `B`
|
= note: required for `B` to implement `ToOwned`
help: consider further restricting this bound
Expand All @@ -15,12 +11,10 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
| +++++++++++++++++++

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