Skip to content

Commit

Permalink
Rollup merge of #115882 - aliemjay:diag-name-region-1, r=compiler-errors
Browse files Browse the repository at this point in the history
improve the suggestion of `generic_bound_failure`

- Fixes #115375
- suggest the bound in the correct scope: trait or impl header vs assoc item. See `tests/ui/suggestions/lifetimes/type-param-bound-scope.rs`
- don't suggest a lifetime name that conflicts with the other late-bound regions of the function:
```rust
type Inv<'a> = *mut &'a ();
fn check_bound<'a, T: 'a>(_: T, _: Inv<'a>) {}
fn test<'a, T>(_: &'a str, t: T, lt: Inv<'_>) { // suggests a new name `'a`
    check_bound(t, lt); //~ ERROR
}
```
  • Loading branch information
matthiaskrgr committed Oct 9, 2023
2 parents 7ed044c + a883063 commit 389747c
Show file tree
Hide file tree
Showing 82 changed files with 1,172 additions and 737 deletions.
508 changes: 198 additions & 310 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs

Large diffs are not rendered by default.

25 changes: 15 additions & 10 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,24 +1057,29 @@ impl<'tcx> TyCtxt<'tcx> {
}

/// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = match *region {
ty::ReFree(ref free_region) => {
(free_region.scope.expect_local(), free_region.bound_region)
pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = loop {
let def_id = match region.kind() {
ty::ReFree(fr) => fr.bound_region.get_id()?.as_local()?,
ty::ReEarlyBound(ebr) => ebr.def_id.expect_local(),
_ => return None, // not a free region
};
let scope = self.local_parent(def_id);
if self.def_kind(scope) == DefKind::OpaqueTy {
// Lifetime params of opaque types are synthetic and thus irrelevant to
// diagnostics. Map them back to their origin!
region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
continue;
}
ty::ReEarlyBound(ref ebr) => (
self.local_parent(ebr.def_id.expect_local()),
ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name),
),
_ => return None, // not a free region
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
};

let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
Some(Node::Item(..) | Node::TraitItem(..)) => false,
Some(Node::ImplItem(..)) => {
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
}
_ => return None,
_ => false,
};

Some(FreeRegionInfo {
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/associated-inherent-types/regionck-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regionck-1.rs:9:30
|
LL | type NoTyOutliv<'a, T> = &'a T;
| ^^^^^- help: consider adding a where clause: `where T: 'a`
| |
| ...so that the reference type `&'a T` does not outlive the data it points at
| -- ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
| |
| the parameter type `T` must be valid for the lifetime `'a` as defined here...
|
help: consider adding an explicit lifetime bound
|
LL | type NoTyOutliv<'a, T: 'a> = &'a T;
| ++++

error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
--> $DIR/regionck-1.rs:10:31
Expand Down
34 changes: 14 additions & 20 deletions tests/ui/async-await/in-trait/async-generics-and-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,29 @@ error[E0311]: the parameter type `U` may not live long enough
--> $DIR/async-generics-and-bounds.rs:12:5
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `U` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
|
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
help: consider adding an explicit lifetime bound
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:5
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a;
| ++++ ++ ++ +++++++

error[E0311]: the parameter type `T` may not live long enough
--> $DIR/async-generics-and-bounds.rs:12:5
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `T` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
|
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
help: consider adding an explicit lifetime bound
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:5
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a;
| ++++ ++ ++ +++++++

error: aborting due to 2 previous errors

Expand Down
34 changes: 14 additions & 20 deletions tests/ui/async-await/in-trait/async-generics.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,29 @@ error[E0311]: the parameter type `U` may not live long enough
--> $DIR/async-generics.rs:9:5
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `U` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
|
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
--> $DIR/async-generics.rs:9:18
help: consider adding an explicit lifetime bound
|
LL | async fn foo(&self) -> &(T, U);
| ^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:5
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a;
| ++++ ++ ++ +++++++++++

error[E0311]: the parameter type `T` may not live long enough
--> $DIR/async-generics.rs:9:5
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
| | |
| | the parameter type `T` must be valid for the anonymous lifetime as defined here...
| ...so that the reference type `&(T, U)` does not outlive the data it points at
|
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
--> $DIR/async-generics.rs:9:18
help: consider adding an explicit lifetime bound
|
LL | async fn foo(&self) -> &(T, U);
| ^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:5
|
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a;
| ++++ ++ ++ +++++++++++

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/builtin-superkinds-self-type.rs:10:16
|
LL | impl <T: Sync> Foo for T { }
| ^^^ ...so that the type `T` will meet its required lifetime bounds...
| ^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/builtin-superkinds-self-type.rs:6:24
|
LL | trait Foo : Sized+Sync+'static {
| ^^^^^^^
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | impl <T: Sync + 'static> Foo for T { }
| +++++++++
Expand Down
7 changes: 5 additions & 2 deletions tests/ui/coercion/issue-53475.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue-53475.rs:10:1
|
LL | impl<T> CoerceUnsized<Foo<dyn Any>> for Foo<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | impl<T: 'static> CoerceUnsized<Foo<dyn Any>> for Foo<T> {}
| +++++++++
Expand Down
14 changes: 10 additions & 4 deletions tests/ui/consts/issue-102117.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue-102117.rs:19:26
|
LL | type_id: TypeId::of::<T>(),
| ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| ^^^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | pub fn new<T: 'static>() -> &'static Self {
| +++++++++
Expand All @@ -13,10 +16,13 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue-102117.rs:19:26
|
LL | type_id: TypeId::of::<T>(),
| ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| ^^^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | pub fn new<T: 'static>() -> &'static Self {
| +++++++++
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0311.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#![allow(warnings)]

fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
with_restriction::<T>(x) //~ ERROR E0311
}

Expand Down
20 changes: 6 additions & 14 deletions tests/ui/error-codes/E0311.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/E0311.rs:6:5
|
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/E0311.rs:5:25
|
LL | fn no_restriction<T>(x: &()) -> &() {
| ^^^
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/E0311.rs:6:5
|
| --- the parameter type `T` must be valid for the anonymous lifetime defined here...
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
| +++ ++++ ++
LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
| +++ ++++ ++ ++

error: aborting due to previous error

Expand Down
6 changes: 4 additions & 2 deletions tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ error[E0309]: the parameter type `T` may not live long enough
--> $DIR/implied-bounds-unnorm-associated-type-5.rs:6:13
|
LL | impl<'a, T> Trait<'a> for T {
| ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
| -- ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
| |
| the parameter type `T` must be valid for the lifetime `'a` as defined here...
|
note: ...that is required by this bound
--> $DIR/implied-bounds-unnorm-associated-type-5.rs:1:18
|
LL | trait Trait<'a>: 'a {
| ^^
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | impl<'a, T: 'a> Trait<'a> for T {
| ++++
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/generic-associated-types/issue-84931.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ error[E0309]: the parameter type `T` may not live long enough
--> $DIR/issue-84931.rs:14:21
|
LL | type Item<'a> = &'a mut T;
| ^^^^^^^^^- help: consider adding a where clause: `where T: 'a`
| |
| ...so that the reference type `&'a mut T` does not outlive the data it points at
| -- ^^^^^^^^^ ...so that the reference type `&'a mut T` does not outlive the data it points at
| |
| the parameter type `T` must be valid for the lifetime `'a` as defined here...
|
help: consider adding an explicit lifetime bound
|
LL | type Item<'a> = &'a mut T where T: 'a;
| +++++++++++

error: aborting due to previous error

Expand Down
7 changes: 5 additions & 2 deletions tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,12 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:43:5
|
LL | x
| ^ ...so that the type `T` will meet its required lifetime bounds
| ^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | fn ty_param_wont_outlive_static<T:Debug + 'static>(x: T) -> impl Debug + 'static {
| +++++++++
Expand Down
7 changes: 5 additions & 2 deletions tests/ui/impl-trait/type_parameters_captured.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/type_parameters_captured.rs:8:5
|
LL | x
| ^ ...so that the type `T` will meet its required lifetime bounds
| ^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | fn foo<T: 'static>(x: T) -> impl Any + 'static {
| +++++++++
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/unactionable_diagnostic.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn foo<'x, P>(
}

pub fn bar<'t, T: 't>(
//~^ HELP: consider adding an explicit lifetime bound...
//~^ HELP: consider adding an explicit lifetime bound
post: T,
x: &'t Foo,
) -> &'t impl Trait {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/unactionable_diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn foo<'x, P>(
}

pub fn bar<'t, T>(
//~^ HELP: consider adding an explicit lifetime bound...
//~^ HELP: consider adding an explicit lifetime bound
post: T,
x: &'t Foo,
) -> &'t impl Trait {
Expand Down
5 changes: 4 additions & 1 deletion tests/ui/impl-trait/unactionable_diagnostic.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/unactionable_diagnostic.rs:21:5
|
LL | pub fn bar<'t, T>(
| -- the parameter type `T` must be valid for the lifetime `'t` as defined here...
...
LL | foo(post, x)
| ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
help: consider adding an explicit lifetime bound
|
LL | pub fn bar<'t, T: 't>(
| ++++
Expand Down
Loading

0 comments on commit 389747c

Please sign in to comment.