Skip to content

Commit fcb9dd5

Browse files
committed
Emit single error for + use<'_> and don't suggest use<'static>
``` error[E0106]: missing lifetime specifier --> $DIR/bad-lifetimes.rs:1:39 | LL | fn no_elided_lt() -> impl Sized + use<'_> {} | ^^ expected named lifetime parameter | help: consider introducing a named lifetime parameter | LL | fn no_elided_lt<'a>() -> impl Sized + use<'a> {} | ++++ ~~ ``` Fix #134194.
1 parent 7a0cde9 commit fcb9dd5

File tree

5 files changed

+36
-22
lines changed

5 files changed

+36
-22
lines changed

Diff for: compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -699,10 +699,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
699699
LifetimeName::Param(def_id) => {
700700
self.resolve_lifetime_ref(def_id, lt);
701701
}
702-
LifetimeName::Error => {}
703-
LifetimeName::ImplicitObjectLifetimeDefault
704-
| LifetimeName::Infer
705-
| LifetimeName::Static => {
702+
LifetimeName::Infer | LifetimeName::Error => {
703+
// We don't check for explicit `'_` lifetimes because we'll already have an
704+
// explicit error from late resolution explaining `use<'_>` is invalid.
705+
}
706+
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Static => {
706707
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
707708
span: lt.ident.span,
708709
kind: "lifetime",

Diff for: compiler/rustc_resolve/src/late.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,18 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
11171117

11181118
fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
11191119
match arg {
1120+
PreciseCapturingArg::Lifetime(lt) if lt.ident.name == kw::UnderscoreLifetime => {
1121+
// We account for `+ use<'_>` explicitly to avoid providing an invalid suggestion
1122+
// for `+ use<'static>`.
1123+
let outer_failures = take(&mut self.diag_metadata.current_elision_failures);
1124+
visit::walk_precise_capturing_arg(self, arg);
1125+
let elision_failures =
1126+
replace(&mut self.diag_metadata.current_elision_failures, outer_failures);
1127+
if !elision_failures.is_empty() {
1128+
self.report_missing_lifetime_specifiers(elision_failures, None, true);
1129+
}
1130+
return;
1131+
}
11201132
// Lower the lifetime regularly; we'll resolve the lifetime and check
11211133
// it's a parameter later on in HIR lowering.
11221134
PreciseCapturingArg::Lifetime(_) => {}
@@ -1877,7 +1889,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18771889
}
18781890
}
18791891
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1880-
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
1892+
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None, false);
18811893
}
18821894

18831895
#[instrument(level = "debug", skip(self))]
@@ -2097,7 +2109,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
20972109
LifetimeElisionCandidate::Ignore,
20982110
);
20992111
}
2100-
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
2112+
self.report_missing_lifetime_specifiers(
2113+
vec![missing_lifetime],
2114+
None,
2115+
false,
2116+
);
21012117
break;
21022118
}
21032119
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
@@ -2220,7 +2236,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22202236
replace(&mut self.diag_metadata.current_elision_failures, outer_failures);
22212237
if !elision_failures.is_empty() {
22222238
let Err(failure_info) = elision_lifetime else { bug!() };
2223-
self.report_missing_lifetime_specifiers(elision_failures, Some(failure_info));
2239+
self.report_missing_lifetime_specifiers(elision_failures, Some(failure_info), false);
22242240
}
22252241
}
22262242

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
30323032
&mut self,
30333033
lifetime_refs: Vec<MissingLifetime>,
30343034
function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>,
3035+
in_precise_capture: bool,
30353036
) -> ErrorGuaranteed {
30363037
let num_lifetimes: usize = lifetime_refs.iter().map(|lt| lt.count).sum();
30373038
let spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect();
@@ -3047,6 +3048,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
30473048
&mut err,
30483049
lifetime_refs,
30493050
function_param_lifetimes,
3051+
in_precise_capture,
30503052
);
30513053
err.emit()
30523054
}
@@ -3056,6 +3058,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
30563058
err: &mut Diag<'_>,
30573059
lifetime_refs: Vec<MissingLifetime>,
30583060
function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>,
3061+
in_precise_capture: bool,
30593062
) {
30603063
for &lt in &lifetime_refs {
30613064
err.span_label(
@@ -3118,7 +3121,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
31183121
}
31193122
}
31203123

3121-
if num_params == 0 {
3124+
if in_precise_capture {
3125+
err.note("`use<...>` precise captures list require a named lifetime");
3126+
} else if num_params == 0 {
31223127
err.help(
31233128
"this function's return type contains a borrowed value, but there is no value \
31243129
for it to be borrowed from",

Diff for: tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
fn no_elided_lt() -> impl Sized + use<'_> {}
22
//~^ ERROR missing lifetime specifier
3-
//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_`
43

54
fn static_lt() -> impl Sized + use<'static> {}
65
//~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static`

Diff for: tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr

+6-13
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,26 @@ error[E0106]: missing lifetime specifier
44
LL | fn no_elided_lt() -> impl Sized + use<'_> {}
55
| ^^ expected named lifetime parameter
66
|
7-
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8-
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
7+
help: consider introducing a named lifetime parameter
98
|
10-
LL | fn no_elided_lt() -> impl Sized + use<'static> {}
11-
| ~~~~~~~
9+
LL | fn no_elided_lt<'a>() -> impl Sized + use<'a> {}
10+
| ++++ ~~
1211

1312
error[E0261]: use of undeclared lifetime name `'missing`
14-
--> $DIR/bad-lifetimes.rs:8:37
13+
--> $DIR/bad-lifetimes.rs:7:37
1514
|
1615
LL | fn missing_lt() -> impl Sized + use<'missing> {}
1716
| - ^^^^^^^^ undeclared lifetime
1817
| |
1918
| help: consider introducing lifetime `'missing` here: `<'missing>`
2019

21-
error: expected lifetime parameter in `use<...>` precise captures list, found `'_`
22-
--> $DIR/bad-lifetimes.rs:1:39
23-
|
24-
LL | fn no_elided_lt() -> impl Sized + use<'_> {}
25-
| ^^
26-
2720
error: expected lifetime parameter in `use<...>` precise captures list, found `'static`
28-
--> $DIR/bad-lifetimes.rs:5:36
21+
--> $DIR/bad-lifetimes.rs:4:36
2922
|
3023
LL | fn static_lt() -> impl Sized + use<'static> {}
3124
| ^^^^^^^
3225

33-
error: aborting due to 4 previous errors
26+
error: aborting due to 3 previous errors
3427

3528
Some errors have detailed explanations: E0106, E0261.
3629
For more information about an error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)