//! 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};
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)
{
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() {
error_var
);
- let many = if let Ok(snippet) = self.tcx().sess.source_map().span_to_snippet(span) {
- if "'static" == &named.to_string() && snippet.starts_with("impl ") {
- diag.span_suggestion(
- span,
- "add explicit unnamed lifetime `'_` to the return type to constrain it",
- format!("{} + '_", snippet),
- Applicability::Unspecified,
- );
- true
- } else {
- false
- }
- } else {
- false
- };
- if many {
- diag.span_label(
- span,
- "`impl Trait` types can only capture lifetimes that they reference"
- );
- } else {
- diag.span_label(span, format!("lifetime `{}` required", named));
- }
+ diag.span_label(span, format!("lifetime `{}` required", named));
diag.span_suggestion(
new_ty_span,
- &format!("{}add explicit lifetime `{}` to {}",
- if many {
- "otherwise, "
- } else {
- ""
- },
- named,
- span_label_var,
- ),
+ &format!("add explicit lifetime `{}` to {}", named, span_label_var),
new_ty.to_string(),
Applicability::Unspecified,
);
}
});
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];
}
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);
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
-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 }
- | ^^^^^^^^^ `impl Trait` types can only capture lifetimes that they reference
-help: add explicit unnamed lifetime `'_` to the return type to constrain it
+ | --------- ^ ...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 }
| ^^^^^^^^^^^^^^
-help: otherwise, add explicit lifetime `'static` to the type of `x`
- |
-LL | fn elided(x: &'static i32) -> impl Copy { x }
- | ^^^^^^^^^^^^
error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
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`.
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() {}
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> {