Skip to content

Commit e81e54f

Browse files
committed
Auto merge of #152076 - eggyal:undeclared-object-lifetime, r=<try>
Bind undeclared lifetimes as erroneous bound vars
2 parents 366a1b9 + 08ed1a1 commit e81e54f

File tree

11 files changed

+81
-43
lines changed

11 files changed

+81
-43
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
880880

881881
(hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
882882
}
883-
LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
883+
LifetimeRes::Static { .. } | LifetimeRes::Error { .. } => return None,
884884
res => panic!(
885885
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
886886
res, ident, ident.span
@@ -1933,7 +1933,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19331933
source: LifetimeSource,
19341934
syntax: LifetimeSyntax,
19351935
) -> &'hir hir::Lifetime {
1936-
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1936+
let res =
1937+
self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error { undeclared: None });
19371938
let res = match res {
19381939
LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
19391940
LifetimeRes::Fresh { param, .. } => {
@@ -1949,7 +1950,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19491950
assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
19501951
hir::LifetimeKind::Static
19511952
}
1952-
LifetimeRes::Error => hir::LifetimeKind::Error,
1953+
LifetimeRes::Error { undeclared } => hir::LifetimeKind::Error { undeclared },
19531954
LifetimeRes::ElidedAnchor { .. } => {
19541955
panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
19551956
}
@@ -2016,12 +2017,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20162017
// AST resolution emitted an error on those parameters, so we lower them using
20172018
// `ParamName::Error`.
20182019
let ident = self.lower_ident(param.ident);
2019-
let param_name =
2020-
if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
2021-
ParamName::Error(ident)
2022-
} else {
2023-
ParamName::Plain(ident)
2024-
};
2020+
let param_name = if let Some(LifetimeRes::Error { .. }) =
2021+
self.resolver.get_lifetime_res(param.id)
2022+
{
2023+
ParamName::Error(ident)
2024+
} else {
2025+
ParamName::Plain(ident)
2026+
};
20252027
let kind =
20262028
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
20272029

compiler/rustc_hir/src/def.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ pub enum LifetimeRes {
990990
/// `'static` lifetime.
991991
Static,
992992
/// Resolution failure.
993-
Error,
993+
Error { undeclared: Option<rustc_span::ErrorGuaranteed> },
994994
/// HACK: This is used to recover the NodeId of an elided lifetime.
995995
ElidedAnchor { start: NodeId, end: NodeId },
996996
}

compiler/rustc_hir/src/hir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub enum LifetimeKind {
237237

238238
/// Indicates an error during lowering (usually `'_` in wrong place)
239239
/// that was already reported.
240-
Error,
240+
Error { undeclared: Option<ErrorGuaranteed> },
241241

242242
/// User wrote an anonymous lifetime, either `'_` or nothing (which gets
243243
/// converted to `'_`). The semantics of this lifetime should be inferred
@@ -257,7 +257,7 @@ impl LifetimeKind {
257257
// -- but this is because, as far as the code in the compiler is
258258
// concerned -- `Fresh` variants act equivalently to "some fresh name".
259259
// They correspond to early-bound regions on an impl, in other words.
260-
LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
260+
LifetimeKind::Error { .. } | LifetimeKind::Param(..) | LifetimeKind::Static => false,
261261
}
262262
}
263263
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
663663
LifetimeKind::Param(def_id) => {
664664
self.resolve_lifetime_ref(def_id, lt);
665665
}
666-
LifetimeKind::Error => {}
666+
LifetimeKind::Error { .. } => {}
667667
LifetimeKind::ImplicitObjectLifetimeDefault
668668
| LifetimeKind::Infer
669669
| LifetimeKind::Static => {
@@ -804,7 +804,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
804804
// If the user wrote an explicit name, use that.
805805
self.visit_lifetime(&*lifetime);
806806
}
807-
LifetimeKind::Error => {}
807+
LifetimeKind::Error { .. } => {}
808808
}
809809
}
810810
hir::TyKind::Ref(lifetime_ref, ref mt) => {
@@ -892,7 +892,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
892892
self.resolve_lifetime_ref(param_def_id, lifetime_ref)
893893
}
894894
// If we've already reported an error, just ignore `lifetime_ref`.
895-
hir::LifetimeKind::Error => {}
895+
hir::LifetimeKind::Error { undeclared: None } => {}
896+
hir::LifetimeKind::Error { undeclared: Some(guar) } => {
897+
self.insert_lifetime(lifetime_ref, ResolvedArg::Error(guar))
898+
}
896899
// Those will be resolved by typechecking.
897900
hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Infer => {}
898901
}

compiler/rustc_resolve/src/late.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
17851785
self.emit_non_static_lt_in_const_param_ty_error(lifetime);
17861786
self.record_lifetime_res(
17871787
lifetime.id,
1788-
LifetimeRes::Error,
1788+
LifetimeRes::Error { undeclared: None },
17891789
LifetimeElisionCandidate::Ignore,
17901790
);
17911791
return;
@@ -1794,7 +1794,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
17941794
self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
17951795
self.record_lifetime_res(
17961796
lifetime.id,
1797-
LifetimeRes::Error,
1797+
LifetimeRes::Error { undeclared: None },
17981798
LifetimeElisionCandidate::Ignore,
17991799
);
18001800
return;
@@ -1812,8 +1812,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18121812
let outer_res = lifetime_rib_iter
18131813
.find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer));
18141814

1815-
self.emit_undeclared_lifetime_error(lifetime, outer_res);
1816-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
1815+
let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res);
1816+
self.record_lifetime_res(
1817+
lifetime.id,
1818+
LifetimeRes::Error { undeclared: Some(guar) },
1819+
LifetimeElisionCandidate::Named,
1820+
);
18171821
}
18181822

18191823
#[instrument(level = "debug", skip(self))]
@@ -1953,7 +1957,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19531957
span: lifetime.ident.span,
19541958
});
19551959
};
1956-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1960+
self.record_lifetime_res(
1961+
lifetime.id,
1962+
LifetimeRes::Error { undeclared: None },
1963+
elision_candidate,
1964+
);
19571965
return;
19581966
}
19591967
LifetimeRibKind::Elided(res) => {
@@ -1962,7 +1970,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19621970
}
19631971
LifetimeRibKind::ElisionFailure => {
19641972
self.diag_metadata.current_elision_failures.push(missing_lifetime);
1965-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1973+
self.record_lifetime_res(
1974+
lifetime.id,
1975+
LifetimeRes::Error { undeclared: None },
1976+
elision_candidate,
1977+
);
19661978
return;
19671979
}
19681980
LifetimeRibKind::Item => break,
@@ -1973,7 +1985,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19731985
}
19741986
}
19751987
}
1976-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1988+
self.record_lifetime_res(
1989+
lifetime.id,
1990+
LifetimeRes::Error { undeclared: None },
1991+
elision_candidate,
1992+
);
19771993
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
19781994
}
19791995

@@ -2231,7 +2247,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22312247
for id in node_ids {
22322248
self.record_lifetime_res(
22332249
id,
2234-
LifetimeRes::Error,
2250+
LifetimeRes::Error { undeclared: None },
22352251
LifetimeElisionCandidate::Named,
22362252
);
22372253
}
@@ -2267,7 +2283,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22672283
for id in node_ids {
22682284
self.record_lifetime_res(
22692285
id,
2270-
LifetimeRes::Error,
2286+
LifetimeRes::Error { undeclared: None },
22712287
LifetimeElisionCandidate::Ignore,
22722288
);
22732289
}
@@ -2281,7 +2297,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22812297
for id in node_ids {
22822298
self.record_lifetime_res(
22832299
id,
2284-
LifetimeRes::Error,
2300+
LifetimeRes::Error { undeclared: None },
22852301
LifetimeElisionCandidate::Ignore,
22862302
);
22872303
}
@@ -2329,7 +2345,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
23292345
candidates.push((res, candidate));
23302346
}
23312347
}
2332-
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
2348+
LifetimeRes::Infer | LifetimeRes::Error { .. } | LifetimeRes::ElidedAnchor { .. } => {}
23332349
}
23342350
}
23352351

@@ -3030,7 +3046,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
30303046
{
30313047
diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
30323048
// Record lifetime res, so lowering knows there is something fishy.
3033-
self.record_lifetime_param(param.id, LifetimeRes::Error);
3049+
self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None });
30343050
continue;
30353051
}
30363052

@@ -3042,7 +3058,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
30423058
let rib = match param.kind {
30433059
GenericParamKind::Lifetime => {
30443060
// Record lifetime res, so lowering knows there is something fishy.
3045-
self.record_lifetime_param(param.id, LifetimeRes::Error);
3061+
self.record_lifetime_param(
3062+
param.id,
3063+
LifetimeRes::Error { undeclared: None },
3064+
);
30463065
continue;
30473066
}
30483067
GenericParamKind::Type { .. } => &mut function_type_rib,
@@ -3076,7 +3095,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
30763095
.create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span })
30773096
.emit_unless_delay(is_raw_underscore_lifetime);
30783097
// Record lifetime res, so lowering knows there is something fishy.
3079-
self.record_lifetime_param(param.id, LifetimeRes::Error);
3098+
self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None });
30803099
continue;
30813100
}
30823101

@@ -3086,7 +3105,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
30863105
lifetime: param.ident,
30873106
});
30883107
// Record lifetime res, so lowering knows there is something fishy.
3089-
self.record_lifetime_param(param.id, LifetimeRes::Error);
3108+
self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None });
30903109
continue;
30913110
}
30923111

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3274,7 +3274,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
32743274
&self,
32753275
lifetime_ref: &ast::Lifetime,
32763276
outer_lifetime_ref: Option<Ident>,
3277-
) {
3277+
) -> ErrorGuaranteed {
32783278
debug_assert_ne!(lifetime_ref.ident.name, kw::UnderscoreLifetime);
32793279
let mut err = if let Some(outer) = outer_lifetime_ref {
32803280
struct_span_code_err!(
@@ -3319,7 +3319,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
33193319
);
33203320
}
33213321

3322-
err.emit();
3322+
err.emit()
33233323
}
33243324

33253325
fn suggest_introducing_lifetime(

tests/ui/cast/ice-cast-type-with-error-124848.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ fn main() {
1414
let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
1515
//~^ ERROR use of undeclared lifetime name `'a`
1616
//~| ERROR use of undeclared lifetime name `'a`
17-
//~| ERROR casting `&MyType<'_>` as `*const Cell<Option<&mut MyType<'_>>>` is invalid
1817
}

tests/ui/cast/ice-cast-type-with-error-124848.stderr

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,7 @@ help: provide the argument
5858
LL | let mut unpinned = MyType(Cell::new(None), /* value */);
5959
| +++++++++++++
6060

61-
error[E0606]: casting `&MyType<'_>` as `*const Cell<Option<&mut MyType<'_>>>` is invalid
62-
--> $DIR/ice-cast-type-with-error-124848.rs:14:20
63-
|
64-
LL | let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
65-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66-
67-
error: aborting due to 6 previous errors
61+
error: aborting due to 5 previous errors
6862

69-
Some errors have detailed explanations: E0061, E0261, E0425, E0606.
63+
Some errors have detailed explanations: E0061, E0261, E0425.
7064
For more information about an error, try `rustc --explain E0061`.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//! E0228 (lifetime bound for trait object cannot be deduced from context) should not be emitted
2+
//! when an undeclared lifetime bound has been specified.
3+
//!
4+
//! Regression test for https://github.com/rust-lang/rust/issues/152014
5+
6+
fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} //~ ERROR use of undeclared lifetime name `'undefined`
7+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0261]: use of undeclared lifetime name `'undefined`
2+
--> $DIR/undeclared-object-lifetime.rs:6:24
3+
|
4+
LL | fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {}
5+
| ^^^^^^^^^^ undeclared lifetime
6+
|
7+
help: consider introducing lifetime `'undefined` here
8+
|
9+
LL | fn f<'undefined>(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {}
10+
| ++++++++++++
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0261`.

0 commit comments

Comments
 (0)