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

Tweak unsatisfied HRTB errors #64085

Merged
merged 1 commit into from
Sep 17, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -192,23 +192,28 @@ impl NiceRegionError<'me, 'tcx> {
vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
);

let mut err = self.tcx().sess.struct_span_err(
cause.span(self.tcx()),
&format!(
"implementation of `{}` is not general enough",
self.tcx().def_path_str(trait_def_id),
),
let span = cause.span(self.tcx());
let msg = format!(
"implementation of `{}` is not general enough",
self.tcx().def_path_str(trait_def_id),
);
let mut err = self.tcx().sess.struct_span_err(span, &msg);
err.span_label(
self.tcx().def_span(trait_def_id),
format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)),
);

match cause.code {
ObligationCauseCode::ItemObligation(def_id) => {
err.note(&format!(
"Due to a where-clause on `{}`,",
self.tcx().def_path_str(def_id),
));
}
_ => (),
}
let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code {
err.span_label(span, "doesn't satisfy where-clause");
err.span_label(
self.tcx().def_span(def_id),
&format!("due to a where-clause on `{}`...", self.tcx().def_path_str(def_id)),
);
true
} else {
err.span_label(span, &msg);
false
};

let expected_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
def_id: trait_def_id,
Expand Down Expand Up @@ -295,6 +300,7 @@ impl NiceRegionError<'me, 'tcx> {
expected_has_vid,
actual_has_vid,
any_self_ty_has_vid,
leading_ellipsis,
);

err
Expand All @@ -318,6 +324,7 @@ impl NiceRegionError<'me, 'tcx> {
expected_has_vid: Option<usize>,
actual_has_vid: Option<usize>,
any_self_ty_has_vid: bool,
leading_ellipsis: bool,
) {
// HACK(eddyb) maybe move this in a more central location.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -392,13 +399,15 @@ impl NiceRegionError<'me, 'tcx> {

let mut note = if passive_voice {
format!(
"`{}` would have to be implemented for the type `{}`",
"{}`{}` would have to be implemented for the type `{}`",
if leading_ellipsis { "..." } else { "" },
expected_trait_ref,
expected_trait_ref.map(|tr| tr.self_ty()),
)
} else {
format!(
"`{}` must implement `{}`",
"{}`{}` must implement `{}`",
if leading_ellipsis { "..." } else { "" },
expected_trait_ref.map(|tr| tr.self_ty()),
expected_trait_ref,
)
Expand All @@ -407,20 +416,20 @@ impl NiceRegionError<'me, 'tcx> {
match (has_sub, has_sup) {
(Some(n1), Some(n2)) => {
let _ = write!(note,
", for any two lifetimes `'{}` and `'{}`",
", for any two lifetimes `'{}` and `'{}`...",
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
);
}
(Some(n), _) | (_, Some(n)) => {
let _ = write!(note,
", for any lifetime `'{}`",
", for any lifetime `'{}`...",
n,
);
}
(None, None) => if let Some(n) = expected_has_vid {
let _ = write!(note,
", for some specific lifetime `'{}`",
", for some specific lifetime `'{}`...",
n,
);
},
Expand All @@ -439,13 +448,13 @@ impl NiceRegionError<'me, 'tcx> {

let mut note = if passive_voice {
format!(
"but `{}` is actually implemented for the type `{}`",
"...but `{}` is actually implemented for the type `{}`",
actual_trait_ref,
actual_trait_ref.map(|tr| tr.self_ty()),
)
} else {
format!(
"but `{}` actually implements `{}`",
"...but `{}` actually implements `{}`",
actual_trait_ref.map(|tr| tr.self_ty()),
actual_trait_ref,
)
Expand Down
18 changes: 12 additions & 6 deletions src/test/ui/generator/auto-trait-regions.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:30:5
|
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen);
| ^^^^^^^^^^
| ^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`
= note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
= note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`...
= note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`

error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:48:5
|
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen);
| ^^^^^^^^^^
| ^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`
= note: but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
= note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`...
= note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`

error: aborting due to 2 previous errors

16 changes: 16 additions & 0 deletions src/test/ui/hrtb/due-to-where-clause.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// ignore-compare-mode-nll
// ^ This code works in nll mode.

fn main() {
test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
}

trait Foo<'a> {}

struct FooS<'a> {
data: &'a mut u32,
}

impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}

fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
17 changes: 17 additions & 0 deletions src/test/ui/hrtb/due-to-where-clause.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error: implementation of `Foo` is not general enough
--> $DIR/due-to-where-clause.rs:5:5
|
LL | test::<FooS>(&mut 42);
| ^^^^^^^^^^^^ doesn't satisfy where-clause
...
LL | trait Foo<'a> {}
| ---------------- trait `Foo` defined here
...
LL | fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
| ------------------------------------------------------------- due to a where-clause on `test`...
|
= note: ...`FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
= note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`

error: aborting due to previous error

9 changes: 6 additions & 3 deletions src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
error: implementation of `Deserialize` is not general enough
--> $DIR/hrtb-cache-issue-54302.rs:19:5
|
LL | trait Deserialize<'de> {}
| ------------------------- trait `Deserialize` defined here
...
LL | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
= note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`

error: aborting due to previous error

14 changes: 10 additions & 4 deletions src/test/ui/hrtb/issue-30786.migrate.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
error: implementation of `Stream` is not general enough
--> $DIR/issue-30786.rs:108:22
|
LL | let map = source.map(|x: &_| x);
| ^^^
LL | / pub trait Stream {
LL | | type Item;
LL | | fn next(self) -> Option<Self::Item>;
LL | | }
| |_- trait `Stream` defined here
...
LL | let map = source.map(|x: &_| x);
| ^^^ implementation of `Stream` is not general enough
|
= note: `Stream` would have to be implemented for the type `&'0 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for any lifetime `'0`
= note: but `Stream` is actually implemented for the type `&'1 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for some specific lifetime `'1`
= note: `Stream` would have to be implemented for the type `&'0 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for any lifetime `'0`...
= note: ...but `Stream` is actually implemented for the type `&'1 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for some specific lifetime `'1`

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/hrtb/issue-30786.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error: higher-ranked subtype error
--> $DIR/issue-30786.rs:112:18
--> $DIR/issue-30786.rs:113:18
|
LL | let filter = map.filter(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: higher-ranked subtype error
--> $DIR/issue-30786.rs:114:17
--> $DIR/issue-30786.rs:115:17
|
LL | let count = filter.count(); // Assert that we still have a valid stream.
| ^^^^^^^^^^^^^^
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/hrtb/issue-30786.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//[nll]compile-flags: -Z borrowck=mir

pub trait Stream {
pub trait Stream { //[migrate]~ NOTE trait `Stream` defined here
type Item;
fn next(self) -> Option<Self::Item>;
}
Expand Down Expand Up @@ -109,6 +109,7 @@ fn main() {
//[migrate]~^ ERROR implementation of `Stream` is not general enough
//[migrate]~| NOTE `Stream` would have to be implemented for the type `&'0 mut Map
//[migrate]~| NOTE but `Stream` is actually implemented for the type `&'1
//[migrate]~| NOTE implementation of `Stream` is not general enough
let filter = map.filter(|x: &_| true);
//[nll]~^ ERROR higher-ranked subtype error
let count = filter.count(); // Assert that we still have a valid stream.
Expand Down
54 changes: 37 additions & 17 deletions src/test/ui/issues/issue-54302-cases.stderr
Original file line number Diff line number Diff line change
@@ -1,38 +1,58 @@
error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:63:5
|
LL | <u32 as RefFoo<u32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`
= note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
LL | / trait Foo<'x, T> {
LL | | fn foo(self) -> &'x T;
LL | | }
| |_- trait `Foo` defined here
...
LL | <u32 as RefFoo<u32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`

error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:69:5
|
LL | <i32 as RefFoo<i32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / trait Foo<'x, T> {
LL | | fn foo(self) -> &'x T;
LL | | }
| |_- trait `Foo` defined here
...
LL | <i32 as RefFoo<i32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`
= note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`
= note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`...
= note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`

error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:75:5
|
LL | <u64 as RefFoo<u64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / trait Foo<'x, T> {
LL | | fn foo(self) -> &'x T;
LL | | }
| |_- trait `Foo` defined here
...
LL | <u64 as RefFoo<u64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`
= note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`
= note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`...
= note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`

error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:81:5
|
LL | <i64 as RefFoo<i64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / trait Foo<'x, T> {
LL | | fn foo(self) -> &'x T;
LL | | }
| |_- trait `Foo` defined here
...
LL | <i64 as RefFoo<i64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
= note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`
= note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`
= note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`...
= note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`

error: aborting due to 4 previous errors

9 changes: 6 additions & 3 deletions src/test/ui/issues/issue-54302.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
error: implementation of `Deserialize` is not general enough
--> $DIR/issue-54302.rs:13:5
|
LL | trait Deserialize<'de> {}
| ------------------------- trait `Deserialize` defined here
...
LL | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
|
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
= note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
= note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`

error: aborting due to previous error

13 changes: 9 additions & 4 deletions src/test/ui/issues/issue-55731.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
error: implementation of `DistributedIteratorMulti` is not general enough
--> $DIR/issue-55731.rs:48:5
|
LL | multi(Map {
| ^^^^^
LL | / trait DistributedIteratorMulti<Source> {
LL | | type Item;
LL | | }
| |_- trait `DistributedIteratorMulti` defined here
...
LL | multi(Map {
| ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
|
= note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`
= note: but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`
= note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`...
= note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`

error: aborting due to previous error