8000 Add information to higher-ranked lifetimes conflicts error messages by lqd · Pull Request #57901 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Add information to higher-ranked lifetimes conflicts error messages #57901

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

Merged
merged 16 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
identify when implemented for "some specific lifetime"
  • Loading branch information
nikomatsakis authored and lqd committed Jan 27, 2019
commit ec6405bccd8b1f0933a3604bdd86c43707350275
247 changes: 120 additions & 127 deletions src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
2D0F
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
sub_placeholder @ ty::RePlaceholder(_),
_,
sup_placeholder @ ty::RePlaceholder(_),
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
Some(sub_placeholder),
Some(sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
Some(sub_placeholder),
Some(sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::SubSupConflict(
vid,
Expand All @@ -58,19 +54,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
sub_placeholder @ ty::RePlaceholder(_),
_,
_,
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
Some(sub_placeholder),
None,
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
Some(sub_placeholder),
None,
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::SubSupConflict(
vid,
Expand All @@ -82,19 +74,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
_,
_,
sup_placeholder @ ty::RePlaceholder(_),
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::SubSupConflict(
vid,
Expand All @@ -106,19 +94,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sup_placeholder @ ty::RePlaceholder(_),
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(TypeTrace {
Expand All @@ -127,19 +111,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
}),
sub_region @ ty::RePlaceholder(_),
sup_region @ ty::RePlaceholder(_),
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
None,
cause,
Some(*sub_region),
Some(*sup_region),
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
None,
cause,
Some(*sub_region),
Some(*sup_region),
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(TypeTrace {
Expand All @@ -148,19 +128,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
}),
sub_region @ ty::RePlaceholder(_),
sup_region,
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(sup_region),
cause,
Some(*sub_region),
None,
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(sup_region),
cause,
Some(*sub_region),
None,
expected.def_id,
expected.substs,
found.substs,
)),

Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(TypeTrace {
Expand All @@ -169,19 +145,15 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
}),
sub_region,
sup_region @ ty::RePlaceholder(_),
))
if expected.def_id == found.def_id =>
{
Some(self.try_report_placeholders_trait(
Some(sub_region),
cause,
None,
Some(*sup_region),
expected.def_id,
expected.substs,
found.substs,
))
}
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
Some(sub_region),
cause,
None,
Some(*sup_region),
expected.def_id,
expected.substs,
found.substs,
)),

_ => None,
}
Expand All @@ -206,14 +178,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
expected_substs: &'tcx Substs<'tcx>,
actual_substs: &'tcx Substs<'tcx>,
) -> ErrorReported {
debug!("try_report_placeholders_trait(\
vid={:?}, \
sub_placeholder={:?}, \
sup_placeholder={:?}, \
trait_def_id={:?}, \
expected_substs={:?}, \
actual_substs={:?})",
vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs);
debug!(
"try_report_placeholders_trait(\
vid={:?}, \
sub_placeholder={:?}, \
sup_placeholder={:?}, \
trait_def_id={:?}, \
expected_substs={:?}, \
actual_substs={:?})",
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()),
Expand All @@ -233,18 +207,14 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
_ => (),
}

let expected_trait_ref = self.infcx.resolve_type_vars_if_possible(
&ty::TraitRef {
def_id: trait_def_id,
substs: expected_substs,
}
);
let actual_trait_ref = self.infcx.resolve_type_vars_if_possible(
&ty::TraitRef {
def_id: trait_def_id,
substs: actual_substs,
}
);
let expected_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
def_id: trait_def_id,
substs: expected_substs,
});
let actual_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
def_id: trait_def_id,
substs: actual_substs,
});

// Search the expected and actual trait references to see (a)
// whether the sub/sup placeholders appear in them (sometimes
Expand Down Expand Up @@ -285,19 +255,28 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
.tcx()
.any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid);

debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid);
debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid);
debug!(
"try_report_placeholders_trait: actual_has_vid={:?}",
actual_has_vid
);
debug!(
"try_report_placeholders_trait: expected_has_vid={:?}",
expected_has_vid
);
debug!("try_report_placeholders_trait: has_sub={:?}", has_sub);
debug!("try_report_placeholders_trait: has_sup={:?}", has_sup);
debug!("try_report_placeholders_trait: self_ty_has_vid={:?}", self_ty_has_vid);
debug!(
"try_report_placeholders_trait: self_ty_has_vid={:?}",
self_ty_has_vid
);

RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || {
RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
match (has_sub, has_sup) {
(Some(n1), Some(n2)) => {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any two lifetimes `'{}` and `'{}`",
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
std::cmp::min(n1, n2),
Expand All @@ -307,40 +286,54 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
(Some(n), _) | (_, Some(n)) => {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any lifetime `'{}`",
for any lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
}
(None, None) => {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
));
}
(None, None) => RegionHighlightMode::maybe_highlighting_region(
vid,
expected_has_vid,
|| {
if let Some(n) = expected_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for some specific lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
} else {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
));
}
},
),
}
})
});

RegionHighlightMode::maybe_highlighting_region(
vid,
actual_has_vid.or(expected_has_vid),
actual_has_vid,
|| match actual_has_vid {
Some(n) => {
if self_ty_has_vid {
err.note(&format!(
"but `{}` is actually implemented for the type `{}`, \
for the specific lifetime `'{}`",
for the specific lifetime `'{}`",
actual_trait_ref,
actual_trait_ref.self_ty(),
n
));
} else {
err.note(&format!(
"but `{}` is actually implemented for the type `{}`, \
for some lifetime `'{}`",
for some lifetime `'{}`",
actual_trait_ref,
actual_trait_ref.self_ty(),
n
Expand All @@ -355,7 +348,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
actual_trait_ref.self_ty(),
));
}
}
},
);

err.emit();
Expand Down
15 changes: 3 additions & 12 deletions src/test/ui/issues/issue-57362-1.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
error: implementation of `Trait` is not general enough
--> $DIR/issue-57362.rs:20:7
--> $DIR/issue-57362-1.rs:20:7
|
LL | a.f(); //~ ERROR not general enough
| ^
|
= note: `Trait` would have to be implemented for the type `fn(&u8)`
= note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
= note: but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)`

error: implementation of `X` is not general enough
--> $DIR/issue-57362.rs:38:13
|
LL | let x = <fn (&())>::make_g(); //~ ERROR not general enough
| ^^^^^^^^^^^^^^^^^^
|
= note: `X` would have to be implemented for the type `for<'r> fn(&'r ())`
= note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0`

error: aborting due to 2 previous errors
error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/issues/issue-57362-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: implementation of `X` is not general enough
--> $DIR/issue-57362-2.rs:22:13
|
LL | let x = <fn (&())>::make_g(); //~ ERROR not general enough
| ^^^^^^^^^^^^^^^^^^
|
= note: `X` would have to be implemented for the type `for<'r> fn(&'r ())`
= note: but `X` is actually implemented for the type `fn(&'0 ())`, for the specific lifetime `'0`

error: aborting due to previous error

0