Rollup merge of #58919 - estebank:impl-trait-return-lifetime, r=pnkfelix
Suggest using anonymous lifetime in `impl Trait` return Fix #48467. r? @nikomatsakis
This commit is contained in:
commit
0d01fbaeb8
6 changed files with 48 additions and 19 deletions
|
|
@ -1,6 +1,7 @@
|
|||
//! Error Reporting for Anonymous Region Lifetime Errors
|
||||
//! where one region is named and the other is anonymous.
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::hir::{FunctionRetTy, TyKind};
|
||||
use crate::ty;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
|
||||
|
|
@ -11,9 +12,10 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
|||
let (span, sub, sup) = self.get_regions();
|
||||
|
||||
debug!(
|
||||
"try_report_named_anon_conflict(sub={:?}, sup={:?})",
|
||||
"try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})",
|
||||
sub,
|
||||
sup
|
||||
sup,
|
||||
self.error,
|
||||
);
|
||||
|
||||
// Determine whether the sub and sup consist of one named region ('a)
|
||||
|
|
@ -84,6 +86,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
|||
{
|
||||
return None;
|
||||
}
|
||||
if let FunctionRetTy::Return(ty) = &fndecl.output {
|
||||
if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.node, sub) {
|
||||
// This is an impl Trait return that evaluates de need of 'static.
|
||||
// We handle this case better in `static_impl_trait`.
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (error_var, span_label_var) = if let Some(simple_ident) = arg.pat.simple_ident() {
|
||||
|
|
@ -103,13 +112,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
|
|||
error_var
|
||||
);
|
||||
|
||||
diag.span_label(span, format!("lifetime `{}` required", named));
|
||||
diag.span_suggestion(
|
||||
new_ty_span,
|
||||
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
|
||||
new_ty.to_string(),
|
||||
Applicability::Unspecified,
|
||||
)
|
||||
.span_label(span, format!("lifetime `{}` required", named));
|
||||
new_ty_span,
|
||||
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
|
||||
new_ty.to_string(),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
|
||||
Some(diag)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
});
|
||||
if let Some(i) = best_choice {
|
||||
if let Some(next) = categorized_path.get(i + 1) {
|
||||
if categorized_path[i].0 == ConstraintCategory::Return
|
||||
&& next.0 == ConstraintCategory::OpaqueType
|
||||
{
|
||||
// The return expression is being influenced by the return type being
|
||||
// impl Trait, point at the return type and not the return expr.
|
||||
return *next;
|
||||
}
|
||||
}
|
||||
return categorized_path[i];
|
||||
}
|
||||
|
||||
|
|
@ -240,6 +249,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
self.provides_universal_region(r, fr, outlived_fr)
|
||||
});
|
||||
|
||||
debug!("report_error: category={:?} {:?}", category, span);
|
||||
// Check if we can use one of the "nice region errors".
|
||||
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
|
||||
let tables = infcx.tcx.typeck_tables_of(mir_def_id);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
fn elided(x: &i32) -> impl Copy { x }
|
||||
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
|
||||
//~^ ERROR cannot infer an appropriate lifetime
|
||||
|
||||
fn explicit<'a>(x: &'a i32) -> impl Copy { x }
|
||||
//~^ ERROR cannot infer an appropriate lifetime
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
error[E0621]: explicit lifetime required in the type of `x`
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:3:23
|
||||
error: cannot infer an appropriate lifetime
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:3:35
|
||||
|
|
||||
LL | fn elided(x: &i32) -> impl Copy { x }
|
||||
| ---- ^^^^^^^^^ lifetime `'static` required
|
||||
| |
|
||||
| help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
|
||||
| --------- ^ ...but this borrow...
|
||||
| |
|
||||
| this return type evaluates to the `'static` lifetime...
|
||||
|
|
||||
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:3:1
|
||||
|
|
||||
LL | fn elided(x: &i32) -> impl Copy { x }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
|
||||
|
|
||||
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot infer an appropriate lifetime
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
|
||||
|
|
@ -67,5 +77,5 @@ LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
|
|||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors occurred: E0310, E0621, E0623.
|
||||
Some errors occurred: E0310, E0623.
|
||||
For more information about an error, try `rustc --explain E0310`.
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ trait Foo<'a> {
|
|||
impl<'a, T> Foo<'a> for T { }
|
||||
|
||||
fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
||||
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
|
||||
x
|
||||
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0621]: explicit lifetime required in the type of `x`
|
||||
--> $DIR/impl-trait-captures.rs:11:5
|
||||
--> $DIR/impl-trait-captures.rs:10:25
|
||||
|
|
||||
LL | x
|
||||
| ^ lifetime `ReEarlyBound(0, 'a)` required
|
||||
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
||||
| ^^^^^^^^^^^^ lifetime `ReEarlyBound(0, 'a)` required
|
||||
help: add explicit lifetime `ReEarlyBound(0, 'a)` to the type of `x`
|
||||
|
|
||||
LL | fn foo<'a, T>(x: &ReEarlyBound(0, 'a) T) -> impl Foo<'a> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue