From fa5cccfdf5db6b34e0991b52cdf5d81f4dfe7d7f Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Tue, 3 Feb 2026 23:34:42 +0000 Subject: [PATCH 1/2] Bind undeclared lifetimes as erroneous bound vars Undeclared lifetimes that appear in user code always give rise to an error (E0261) early in name resolution. This patch adds such undeclared lifetimes to the relevant context's bound vars, so that they resolve to regions with `RegionKind::Error(ErrorGuaranteed)`, in order to suppress some ensuing diagnostics (that might be resolved if the lifetime becomes properly declared). --- compiler/rustc_ast_lowering/src/lib.rs | 20 ++++---- compiler/rustc_hir/src/def.rs | 2 +- compiler/rustc_hir/src/hir.rs | 4 +- .../src/collect/resolve_bound_vars.rs | 9 ++-- compiler/rustc_resolve/src/late.rs | 49 +++++++++++++------ .../rustc_resolve/src/late/diagnostics.rs | 4 +- .../cast/ice-cast-type-with-error-124848.rs | 1 - .../ice-cast-type-with-error-124848.stderr | 10 +--- .../undeclared-object-lifetime.rs | 7 +++ .../undeclared-object-lifetime.stderr | 14 ++++++ tests/ui/stats/input-stats.stderr | 4 +- 11 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 tests/ui/object-lifetime/undeclared-object-lifetime.rs create mode 100644 tests/ui/object-lifetime/undeclared-object-lifetime.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e4f431fd2431c..3f30704fdfc40 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -878,7 +878,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind)) } - LifetimeRes::Static { .. } | LifetimeRes::Error => return None, + LifetimeRes::Static { .. } | LifetimeRes::Error { .. } => return None, res => panic!( "Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, ident.span @@ -1931,7 +1931,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { source: LifetimeSource, syntax: LifetimeSyntax, ) -> &'hir hir::Lifetime { - let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); + let res = + self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error { undeclared: None }); let res = match res { LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param), LifetimeRes::Fresh { param, .. } => { @@ -1947,7 +1948,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime)); hir::LifetimeKind::Static } - LifetimeRes::Error => hir::LifetimeKind::Error, + LifetimeRes::Error { undeclared } => hir::LifetimeKind::Error { undeclared }, LifetimeRes::ElidedAnchor { .. } => { panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span); } @@ -2014,12 +2015,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // AST resolution emitted an error on those parameters, so we lower them using // `ParamName::Error`. let ident = self.lower_ident(param.ident); - let param_name = - if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) { - ParamName::Error(ident) - } else { - ParamName::Plain(ident) - }; + let param_name = if let Some(LifetimeRes::Error { .. }) = + self.resolver.get_lifetime_res(param.id) + { + ParamName::Error(ident) + } else { + ParamName::Plain(ident) + }; let kind = hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index e93deaa84944e..d8d50dc6d68ae 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -990,7 +990,7 @@ pub enum LifetimeRes { /// `'static` lifetime. Static, /// Resolution failure. - Error, + Error { undeclared: Option }, /// HACK: This is used to recover the NodeId of an elided lifetime. ElidedAnchor { start: NodeId, end: NodeId }, } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index b117fa8327296..5854b30037a63 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -238,7 +238,7 @@ pub enum LifetimeKind { /// Indicates an error during lowering (usually `'_` in wrong place) /// that was already reported. - Error, + Error { undeclared: Option }, /// User wrote an anonymous lifetime, either `'_` or nothing (which gets /// converted to `'_`). The semantics of this lifetime should be inferred @@ -258,7 +258,7 @@ impl LifetimeKind { // -- but this is because, as far as the code in the compiler is // concerned -- `Fresh` variants act equivalently to "some fresh name". // They correspond to early-bound regions on an impl, in other words. - LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false, + LifetimeKind::Error { .. } | LifetimeKind::Param(..) | LifetimeKind::Static => false, } } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 26f79d374075b..d2ecb31cd3cf1 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -663,7 +663,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { LifetimeKind::Param(def_id) => { self.resolve_lifetime_ref(def_id, lt); } - LifetimeKind::Error => {} + LifetimeKind::Error { .. } => {} LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer | LifetimeKind::Static => { @@ -804,7 +804,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // If the user wrote an explicit name, use that. self.visit_lifetime(&*lifetime); } - LifetimeKind::Error => {} + LifetimeKind::Error { .. } => {} } } hir::TyKind::Ref(lifetime_ref, ref mt) => { @@ -892,7 +892,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.resolve_lifetime_ref(param_def_id, lifetime_ref) } // If we've already reported an error, just ignore `lifetime_ref`. - hir::LifetimeKind::Error => {} + hir::LifetimeKind::Error { undeclared: None } => {} + hir::LifetimeKind::Error { undeclared: Some(guar) } => { + self.insert_lifetime(lifetime_ref, ResolvedArg::Error(guar)) + } // Those will be resolved by typechecking. hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Infer => {} } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4faf7715de6eb..7738e9f47f86c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1785,7 +1785,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.emit_non_static_lt_in_const_param_ty_error(lifetime); self.record_lifetime_res( lifetime.id, - LifetimeRes::Error, + LifetimeRes::Error { undeclared: None }, LifetimeElisionCandidate::Ignore, ); return; @@ -1794,7 +1794,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.emit_forbidden_non_static_lifetime_error(cause, lifetime); self.record_lifetime_res( lifetime.id, - LifetimeRes::Error, + LifetimeRes::Error { undeclared: None }, LifetimeElisionCandidate::Ignore, ); return; @@ -1812,8 +1812,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let outer_res = lifetime_rib_iter .find_map(|rib| rib.bindings.get_key_value(&normalized_ident).map(|(&outer, _)| outer)); - self.emit_undeclared_lifetime_error(lifetime, outer_res); - self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named); + let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res); + self.record_lifetime_res( + lifetime.id, + LifetimeRes::Error { undeclared: Some(guar) }, + LifetimeElisionCandidate::Named, + ); } #[instrument(level = "debug", skip(self))] @@ -1953,7 +1957,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { span: lifetime.ident.span, }); }; - self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate); + self.record_lifetime_res( + lifetime.id, + LifetimeRes::Error { undeclared: None }, + elision_candidate, + ); return; } LifetimeRibKind::Elided(res) => { @@ -1962,7 +1970,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } LifetimeRibKind::ElisionFailure => { self.diag_metadata.current_elision_failures.push(missing_lifetime); - self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate); + self.record_lifetime_res( + lifetime.id, + LifetimeRes::Error { undeclared: None }, + elision_candidate, + ); return; } LifetimeRibKind::Item => break, @@ -1973,7 +1985,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } } - self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate); + self.record_lifetime_res( + lifetime.id, + LifetimeRes::Error { undeclared: None }, + elision_candidate, + ); self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); } @@ -2231,7 +2247,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for id in node_ids { self.record_lifetime_res( id, - LifetimeRes::Error, + LifetimeRes::Error { undeclared: None }, LifetimeElisionCandidate::Named, ); } @@ -2267,7 +2283,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for id in node_ids { self.record_lifetime_res( id, - LifetimeRes::Error, + LifetimeRes::Error { undeclared: None }, LifetimeElisionCandidate::Ignore, ); } @@ -2281,7 +2297,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for id in node_ids { self.record_lifetime_res( id, - LifetimeRes::Error, + LifetimeRes::Error { undeclared: None }, LifetimeElisionCandidate::Ignore, ); } @@ -2329,7 +2345,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { candidates.push((res, candidate)); } } - LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {} + LifetimeRes::Infer | LifetimeRes::Error { .. } | LifetimeRes::ElidedAnchor { .. } => {} } } @@ -3030,7 +3046,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { { diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error); + self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); continue; } @@ -3042,7 +3058,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let rib = match param.kind { GenericParamKind::Lifetime => { // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error); + self.record_lifetime_param( + param.id, + LifetimeRes::Error { undeclared: None }, + ); continue; } GenericParamKind::Type { .. } => &mut function_type_rib, @@ -3076,7 +3095,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span }) .emit_unless_delay(is_raw_underscore_lifetime); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error); + self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); continue; } @@ -3086,7 +3105,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { lifetime: param.ident, }); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error); + self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); continue; } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8794c4ff8b025..0f4d16384f816 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3274,7 +3274,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &self, lifetime_ref: &ast::Lifetime, outer_lifetime_ref: Option, - ) { + ) -> ErrorGuaranteed { debug_assert_ne!(lifetime_ref.ident.name, kw::UnderscoreLifetime); let mut err = if let Some(outer) = outer_lifetime_ref { struct_span_code_err!( @@ -3319,7 +3319,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); } - err.emit(); + err.emit() } fn suggest_introducing_lifetime( diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs index 9b3732b02db43..0c623de8050b0 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.rs +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -14,5 +14,4 @@ fn main() { let bad_addr = &unpinned as *const Cell>> as usize; //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` - //~| ERROR casting `&MyType<'_>` as `*const Cell>>` is invalid } diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index dff2277273248..665b0e0a0dd49 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -58,13 +58,7 @@ help: provide the argument LL | let mut unpinned = MyType(Cell::new(None), /* value */); | +++++++++++++ -error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid - --> $DIR/ice-cast-type-with-error-124848.rs:14:20 - | -LL | let bad_addr = &unpinned as *const Cell>> as usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0061, E0261, E0425, E0606. +Some errors have detailed explanations: E0061, E0261, E0425. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/object-lifetime/undeclared-object-lifetime.rs b/tests/ui/object-lifetime/undeclared-object-lifetime.rs new file mode 100644 index 0000000000000..7c0e1100fe7bb --- /dev/null +++ b/tests/ui/object-lifetime/undeclared-object-lifetime.rs @@ -0,0 +1,7 @@ +//! E0228 (lifetime bound for trait object cannot be deduced from context) should not be emitted +//! when an undeclared lifetime bound has been specified. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152014 + +fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} //~ ERROR use of undeclared lifetime name `'undefined` +fn main() {} diff --git a/tests/ui/object-lifetime/undeclared-object-lifetime.stderr b/tests/ui/object-lifetime/undeclared-object-lifetime.stderr new file mode 100644 index 0000000000000..b6646a05420b3 --- /dev/null +++ b/tests/ui/object-lifetime/undeclared-object-lifetime.stderr @@ -0,0 +1,14 @@ +error[E0261]: use of undeclared lifetime name `'undefined` + --> $DIR/undeclared-object-lifetime.rs:6:24 + | +LL | fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} + | ^^^^^^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'undefined` here + | +LL | fn f<'undefined>(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index a91a15bc63dff..ca223e4cb8e57 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -114,10 +114,10 @@ hir-stats - Type 16 (NN.N%) 1 hir-stats - Lifetime 48 (NN.N%) 3 hir-stats ExprField 40 (NN.N%) 1 40 hir-stats Mod 32 (NN.N%) 1 32 -hir-stats Lifetime 28 (NN.N%) 1 28 +hir-stats Lifetime 32 (NN.N%) 1 32 hir-stats TraitItemId 8 (NN.N%) 2 4 hir-stats ImplItemId 8 (NN.N%) 2 4 hir-stats ForeignItemId 4 (NN.N%) 1 4 hir-stats ---------------------------------------------------------------- -hir-stats Total 8_576 172 +hir-stats Total 8_580 172 hir-stats ================================================================ From 8e83a5770aaad584341f74e3d2f3edc9c7d9fd5f Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Wed, 4 Feb 2026 09:43:23 +0000 Subject: [PATCH 2/2] Propagate all early lifetime resolution errors to RBV --- compiler/rustc_ast_lowering/src/lib.rs | 48 +++---- compiler/rustc_hir/src/def.rs | 2 +- compiler/rustc_hir/src/hir.rs | 8 +- .../src/collect/resolve_bound_vars.rs | 11 +- .../src/hir_ty_lowering/dyn_trait.rs | 12 +- compiler/rustc_resolve/src/late.rs | 117 ++++++++++-------- .../rustc_resolve/src/late/diagnostics.rs | 64 ++++++---- tests/ui/closures/binder/implicit-stuff.rs | 1 - .../ui/closures/binder/implicit-stuff.stderr | 11 +- .../ice-line-bounds-issue-148732.rs | 1 - .../ice-line-bounds-issue-148732.stderr | 17 +-- tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs | 1 - .../ui/rfcs/rfc-1623-static/rfc1623-3.stderr | 11 +- tests/ui/stats/input-stats.stderr | 4 +- 14 files changed, 150 insertions(+), 158 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3f30704fdfc40..11baca246b8f0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -878,7 +878,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind)) } - LifetimeRes::Static { .. } | LifetimeRes::Error { .. } => return None, + LifetimeRes::Static { .. } | LifetimeRes::Error(..) => return None, res => panic!( "Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, ident.span @@ -1932,27 +1932,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { syntax: LifetimeSyntax, ) -> &'hir hir::Lifetime { let res = - self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error { undeclared: None }); - let res = match res { - LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param), - LifetimeRes::Fresh { param, .. } => { - assert_eq!(ident.name, kw::UnderscoreLifetime); - let param = self.local_def_id(param); - hir::LifetimeKind::Param(param) - } - LifetimeRes::Infer => { - assert_eq!(ident.name, kw::UnderscoreLifetime); - hir::LifetimeKind::Infer - } - LifetimeRes::Static { .. } => { - assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime)); - hir::LifetimeKind::Static - } - LifetimeRes::Error { undeclared } => hir::LifetimeKind::Error { undeclared }, - LifetimeRes::ElidedAnchor { .. } => { - panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span); - } - }; + self.resolver.get_lifetime_res(id).map_or( + hir::LifetimeKind::NotFound, + |res| match res { + LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param), + LifetimeRes::Fresh { param, .. } => { + assert_eq!(ident.name, kw::UnderscoreLifetime); + let param = self.local_def_id(param); + hir::LifetimeKind::Param(param) + } + LifetimeRes::Infer => { + assert_eq!(ident.name, kw::UnderscoreLifetime); + hir::LifetimeKind::Infer + } + LifetimeRes::Static { .. } => { + assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime)); + hir::LifetimeKind::Static + } + LifetimeRes::Error(guar) => hir::LifetimeKind::Error(guar), + LifetimeRes::ElidedAnchor { .. } => { + panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span); + } + }, + ); debug!(?res); self.arena.alloc(hir::Lifetime::new( @@ -2015,7 +2017,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // AST resolution emitted an error on those parameters, so we lower them using // `ParamName::Error`. let ident = self.lower_ident(param.ident); - let param_name = if let Some(LifetimeRes::Error { .. }) = + let param_name = if let Some(LifetimeRes::Error(..)) = self.resolver.get_lifetime_res(param.id) { ParamName::Error(ident) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index d8d50dc6d68ae..dd2cd4939432b 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -990,7 +990,7 @@ pub enum LifetimeRes { /// `'static` lifetime. Static, /// Resolution failure. - Error { undeclared: Option }, + Error(rustc_span::ErrorGuaranteed), /// HACK: This is used to recover the NodeId of an elided lifetime. ElidedAnchor { start: NodeId, end: NodeId }, } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5854b30037a63..474ae725ff493 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -238,7 +238,8 @@ pub enum LifetimeKind { /// Indicates an error during lowering (usually `'_` in wrong place) /// that was already reported. - Error { undeclared: Option }, + Error(ErrorGuaranteed), + NotFound, /// User wrote an anonymous lifetime, either `'_` or nothing (which gets /// converted to `'_`). The semantics of this lifetime should be inferred @@ -258,7 +259,10 @@ impl LifetimeKind { // -- but this is because, as far as the code in the compiler is // concerned -- `Fresh` variants act equivalently to "some fresh name". // They correspond to early-bound regions on an impl, in other words. - LifetimeKind::Error { .. } | LifetimeKind::Param(..) | LifetimeKind::Static => false, + LifetimeKind::Error(..) + | LifetimeKind::NotFound + | LifetimeKind::Param(..) + | LifetimeKind::Static => false, } } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d2ecb31cd3cf1..995d6433964f7 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -663,7 +663,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { LifetimeKind::Param(def_id) => { self.resolve_lifetime_ref(def_id, lt); } - LifetimeKind::Error { .. } => {} + LifetimeKind::Error(..) | LifetimeKind::NotFound => {} LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer | LifetimeKind::Static => { @@ -804,7 +804,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // If the user wrote an explicit name, use that. self.visit_lifetime(&*lifetime); } - LifetimeKind::Error { .. } => {} + LifetimeKind::Error(..) | LifetimeKind::NotFound => {} } } hir::TyKind::Ref(lifetime_ref, ref mt) => { @@ -891,9 +891,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { hir::LifetimeKind::Param(param_def_id) => { self.resolve_lifetime_ref(param_def_id, lifetime_ref) } - // If we've already reported an error, just ignore `lifetime_ref`. - hir::LifetimeKind::Error { undeclared: None } => {} - hir::LifetimeKind::Error { undeclared: Some(guar) } => { + // Just ignore `lifetime_ref` if it couldn't be resolved + hir::LifetimeKind::NotFound => {} + // Keep track of lifetimes about which errors have already been reported + hir::LifetimeKind::Error(guar) => { self.insert_lifetime(lifetime_ref, ResolvedArg::Error(guar)) } // Those will be resolved by typechecking. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index 57defac577d8a..b3e6b9623bd27 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -451,17 +451,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } else { let reason = if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind { - if let hir::Node::Ty(hir::Ty { - kind: hir::TyKind::Ref(parent_lifetime, _), - .. - }) = tcx.parent_hir_node(hir_id) - && tcx.named_bound_var(parent_lifetime.hir_id).is_none() - { - // Parent lifetime must have failed to resolve. Don't emit a redundant error. - RegionInferReason::ExplicitObjectLifetime - } else { - RegionInferReason::ObjectLifetimeDefault - } + RegionInferReason::ObjectLifetimeDefault } else { RegionInferReason::ExplicitObjectLifetime }; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7738e9f47f86c..3303936f490d2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -746,7 +746,8 @@ pub(crate) struct DiagMetadata<'ast> { /// Accumulate the errors due to missed lifetime elision, /// and report them all at once for each function. - current_elision_failures: Vec, + current_elision_failures: + Vec<(MissingLifetime, LifetimeElisionCandidate, NodeId, Option)>, } struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { @@ -1782,19 +1783,19 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match rib.kind { LifetimeRibKind::Item => break, LifetimeRibKind::ConstParamTy => { - self.emit_non_static_lt_in_const_param_ty_error(lifetime); + let guar = self.emit_non_static_lt_in_const_param_ty_error(lifetime); self.record_lifetime_res( lifetime.id, - LifetimeRes::Error { undeclared: None }, + LifetimeRes::Error(guar), LifetimeElisionCandidate::Ignore, ); return; } LifetimeRibKind::ConcreteAnonConst(cause) => { - self.emit_forbidden_non_static_lifetime_error(cause, lifetime); + let guar = self.emit_forbidden_non_static_lifetime_error(cause, lifetime); self.record_lifetime_res( lifetime.id, - LifetimeRes::Error { undeclared: None }, + LifetimeRes::Error(guar), LifetimeElisionCandidate::Ignore, ); return; @@ -1815,7 +1816,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res); self.record_lifetime_res( lifetime.id, - LifetimeRes::Error { undeclared: Some(guar) }, + LifetimeRes::Error(guar), LifetimeElisionCandidate::Named, ); } @@ -1882,7 +1883,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } LifetimeRibKind::AnonymousReportError => { - if elided { + let guar = if elided { let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| { if let LifetimeRibKind::Generics { span, @@ -1914,7 +1915,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.r.dcx().emit_err(errors::LendingIteratorReportError { lifetime: lifetime.ident.span, ty: ty.span, - }); + }) } else { let decl = if !trait_id.is_local() && let Some(assoc) = self.diag_metadata.current_impl_item @@ -1944,22 +1945,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span); - err.emit(); + err.emit() } } else { self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError { span: lifetime.ident.span, suggestion, - }); + }) } } else { self.r.dcx().emit_err(errors::ExplicitAnonymousLifetimeReportError { span: lifetime.ident.span, - }); + }) }; self.record_lifetime_res( lifetime.id, - LifetimeRes::Error { undeclared: None }, + LifetimeRes::Error(guar), elision_candidate, ); return; @@ -1969,12 +1970,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; } LifetimeRibKind::ElisionFailure => { - self.diag_metadata.current_elision_failures.push(missing_lifetime); - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error { undeclared: None }, + self.diag_metadata.current_elision_failures.push(( + missing_lifetime, elision_candidate, - ); + lifetime.id, + None, + )); return; } LifetimeRibKind::Item => break, @@ -1985,12 +1986,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } } - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Error { undeclared: None }, - elision_candidate, - ); - self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); + let guar = self.report_missing_lifetime_specifiers([&missing_lifetime], None); + self.record_lifetime_res(lifetime.id, LifetimeRes::Error(guar), elision_candidate); } fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) { @@ -2238,16 +2235,17 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { !segment.has_generic_args, elided_lifetime_span, ); - self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere { - span: path_span, - subdiag, - }); + let guar = + self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere { + span: path_span, + subdiag, + }); should_lint = false; for id in node_ids { self.record_lifetime_res( id, - LifetimeRes::Error { undeclared: None }, + LifetimeRes::Error(guar), LifetimeElisionCandidate::Named, ); } @@ -2279,14 +2277,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { break; } LifetimeRibKind::ElisionFailure => { - self.diag_metadata.current_elision_failures.push(missing_lifetime); - for id in node_ids { - self.record_lifetime_res( - id, - LifetimeRes::Error { undeclared: None }, - LifetimeElisionCandidate::Ignore, - ); - } + self.diag_metadata.current_elision_failures.push(( + missing_lifetime, + LifetimeElisionCandidate::Ignore, + node_ids.start, + Some(node_ids.end), + )); break; } // `LifetimeRes::Error`, which would usually be used in the case of @@ -2294,14 +2290,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // we simply resolve to an implicit lifetime, which will be checked later, at // which point a suitable error will be emitted. LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => { + let guar = + self.report_missing_lifetime_specifiers([&missing_lifetime], None); for id in node_ids { self.record_lifetime_res( id, - LifetimeRes::Error { undeclared: None }, + LifetimeRes::Error(guar), LifetimeElisionCandidate::Ignore, ); } - self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); break; } LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {} @@ -2345,7 +2342,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { candidates.push((res, candidate)); } } - LifetimeRes::Infer | LifetimeRes::Error { .. } | LifetimeRes::ElidedAnchor { .. } => {} + LifetimeRes::Infer | LifetimeRes::Error(..) | LifetimeRes::ElidedAnchor { .. } => {} } } @@ -2389,7 +2386,23 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { replace(&mut this.diag_metadata.current_elision_failures, outer_failures); if !elision_failures.is_empty() { let Err(failure_info) = elision_lifetime else { bug!() }; - this.report_missing_lifetime_specifiers(elision_failures, Some(failure_info)); + let guar = this.report_missing_lifetime_specifiers( + elision_failures.iter().map(|(missing_lifetime, ..)| missing_lifetime), + Some(failure_info), + ); + let mut record_res = |lifetime, candidate| { + this.record_lifetime_res(lifetime, LifetimeRes::Error(guar), candidate) + }; + for (_, candidate, start, end) in elision_failures { + match end { + Some(end) => { + for lifetime in start..end { + record_res(lifetime, candidate) + } + } + None => record_res(start, candidate), + } + } } }); } @@ -3044,9 +3057,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if let GenericParamKind::Lifetime = param.kind && let Some(&original) = seen_lifetimes.get(&ident) { - diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident); + let guar = diagnostics::signal_lifetime_shadowing( + self.r.tcx.sess, + original, + param.ident, + ); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); + self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); continue; } @@ -3054,14 +3071,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { Entry::Occupied(entry) => { let span = *entry.get(); let err = ResolutionError::NameAlreadyUsedInParameterList(ident, span); - self.report_error(param.ident.span, err); + let guar = self.r.report_error(param.ident.span, err); let rib = match param.kind { GenericParamKind::Lifetime => { // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param( - param.id, - LifetimeRes::Error { undeclared: None }, - ); + self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); continue; } GenericParamKind::Type { .. } => &mut function_type_rib, @@ -3090,22 +3104,23 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .iter() .any(|span| span == param.span()); - self.r + let guar = self + .r .dcx() .create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span }) .emit_unless_delay(is_raw_underscore_lifetime); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); + self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); continue; } if param.ident.name == kw::StaticLifetime { - self.r.dcx().emit_err(errors::StaticLifetimeIsReserved { + let guar = self.r.dcx().emit_err(errors::StaticLifetimeIsReserved { span: param.ident.span, lifetime: param.ident, }); // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error { undeclared: None }); + self.record_lifetime_param(param.id, LifetimeRes::Error(guar)); continue; } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0f4d16384f816..c89591649da5f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -131,7 +131,7 @@ pub(super) struct ElisionFnParameter { /// Description of lifetimes that appear as candidates for elision. /// This is used to suggest introducing an explicit lifetime. -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub(super) enum LifetimeElisionCandidate { /// This is not a real lifetime. Ignore, @@ -3473,14 +3473,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } - pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) { + pub(crate) fn emit_non_static_lt_in_const_param_ty_error( + &self, + lifetime_ref: &ast::Lifetime, + ) -> ErrorGuaranteed { self.r .dcx() .create_err(errors::ParamInTyOfConstParam { span: lifetime_ref.ident.span, name: lifetime_ref.ident.name, }) - .emit(); + .emit() } /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. @@ -3490,18 +3493,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &self, cause: NoConstantGenericsReason, lifetime_ref: &ast::Lifetime, - ) { + ) -> ErrorGuaranteed { match cause { - NoConstantGenericsReason::IsEnumDiscriminant => { - self.r - .dcx() - .create_err(errors::ParamInEnumDiscriminant { - span: lifetime_ref.ident.span, - name: lifetime_ref.ident.name, - param_kind: errors::ParamKindInEnumDiscriminant::Lifetime, - }) - .emit(); - } + NoConstantGenericsReason::IsEnumDiscriminant => self + .r + .dcx() + .create_err(errors::ParamInEnumDiscriminant { + span: lifetime_ref.ident.span, + name: lifetime_ref.ident.name, + param_kind: errors::ParamKindInEnumDiscriminant::Lifetime, + }) + .emit(), NoConstantGenericsReason::NonTrivialConstArg => { assert!(!self.r.tcx.features().generic_const_exprs()); self.r @@ -3517,18 +3519,18 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .is_nightly_build() .then_some(errors::ParamInNonTrivialAnonConstHelp), }) - .emit(); + .emit() } } } - pub(crate) fn report_missing_lifetime_specifiers( + pub(crate) fn report_missing_lifetime_specifiers<'a>( &mut self, - lifetime_refs: Vec, + lifetime_refs: impl Clone + IntoIterator, function_param_lifetimes: Option<(Vec, Vec)>, ) -> ErrorGuaranteed { - let num_lifetimes: usize = lifetime_refs.iter().map(|lt| lt.count).sum(); - let spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect(); + let num_lifetimes: usize = lifetime_refs.clone().into_iter().map(|lt| lt.count).sum(); + let spans: Vec<_> = lifetime_refs.clone().into_iter().map(|lt| lt.span).collect(); let mut err = struct_span_code_err!( self.r.dcx(), @@ -3545,13 +3547,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.emit() } - fn add_missing_lifetime_specifiers_label( + fn add_missing_lifetime_specifiers_label<'a>( &mut self, err: &mut Diag<'_>, - lifetime_refs: Vec, + lifetime_refs: impl Clone + IntoIterator, function_param_lifetimes: Option<(Vec, Vec)>, ) { - for < in &lifetime_refs { + for < in lifetime_refs.clone() { err.span_label( lt.span, format!( @@ -3680,7 +3682,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (lt.span.shrink_to_hi(), sugg) } }; - for < in &lifetime_refs { + for < in lifetime_refs.clone() { spans_suggs.push(build_sugg(lt)); } debug!(?spans_suggs); @@ -3708,7 +3710,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } 1 => { let post = if maybe_static { - let owned = if let [lt] = &lifetime_refs[..] + let mut lifetime_refs = lifetime_refs.clone().into_iter(); + let owned = if let Some(lt) = lifetime_refs.next() + && lifetime_refs.next().is_none() && lt.kind != MissingLifetimeKind::Ampersand { ", or if you will only have owned values" @@ -3733,7 +3737,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // we identified that the return expression references only one argument, we // would suggest borrowing only that argument, and we'd skip the prior // "use `'static`" suggestion entirely. - if let [lt] = &lifetime_refs[..] + let mut lifetime_refs = lifetime_refs.clone().into_iter(); + if let Some(lt) = lifetime_refs.next() + && lifetime_refs.next().is_none() && (lt.kind == MissingLifetimeKind::Ampersand || lt.kind == MissingLifetimeKind::Underscore) { @@ -4029,7 +4035,11 @@ fn mk_where_bound_predicate( } /// Report lifetime/lifetime shadowing as an error. -pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) { +pub(super) fn signal_lifetime_shadowing( + sess: &Session, + orig: Ident, + shadower: Ident, +) -> ErrorGuaranteed { struct_span_code_err!( sess.dcx(), shadower.span, @@ -4039,7 +4049,7 @@ pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: I ) .with_span_label(orig.span, "first declared here") .with_span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name)) - .emit(); + .emit() } struct LifetimeFinder<'ast> { diff --git a/tests/ui/closures/binder/implicit-stuff.rs b/tests/ui/closures/binder/implicit-stuff.rs index c976c200b0c8e..09e4c747afee8 100644 --- a/tests/ui/closures/binder/implicit-stuff.rs +++ b/tests/ui/closures/binder/implicit-stuff.rs @@ -24,5 +24,4 @@ fn main() { //~| ERROR `'_` cannot be used here let _ = for<'a> |x: &()| -> &'a () { x }; //~ ERROR `&` without an explicit lifetime name cannot be used here let _ = for<'a> |x: &'a ()| -> &() { x }; //~ ERROR `&` without an explicit lifetime name cannot be used here - //~^ ERROR: lifetime may not live long enough } diff --git a/tests/ui/closures/binder/implicit-stuff.stderr b/tests/ui/closures/binder/implicit-stuff.stderr index 330a05a79bae3..cec2a60ba28c8 100644 --- a/tests/ui/closures/binder/implicit-stuff.stderr +++ b/tests/ui/closures/binder/implicit-stuff.stderr @@ -102,15 +102,6 @@ LL | let _ = for<'a> |x: &'a _, y, z: _| -> &'a _ { | | | `for<...>` is here -error: lifetime may not live long enough - --> $DIR/implicit-stuff.rs:26:42 - | -LL | let _ = for<'a> |x: &'a ()| -> &() { x }; - | -- - ^ returning this value requires that `'a` must outlive `'1` - | | | - | | let's call the lifetime of this reference `'1` - | lifetime `'a` defined here - -error: aborting due to 16 previous errors +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0637`. diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.rs b/tests/ui/delegation/ice-line-bounds-issue-148732.rs index e44c784760216..699e7d86f2581 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.rs +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.rs @@ -3,7 +3,6 @@ reuse a as b { //~| ERROR functions delegation is not yet fully implemented dbg!(b); //~^ ERROR missing lifetime specifier - //~| ERROR `fn() {b}` doesn't implement `Debug` } fn main() {} diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index 83cc238b5e0c4..c4f261181b109 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -17,7 +17,7 @@ LL | / reuse a as b { LL | | LL | | LL | | dbg!(b); -... | +LL | | LL | | } | |_^ | @@ -25,18 +25,7 @@ LL | | } = help: add `#![feature(fn_delegation)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0277]: `fn() {b}` doesn't implement `Debug` - --> $DIR/ice-line-bounds-issue-148732.rs:4:5 - | -LL | reuse a as b { - | - consider calling this function -... -LL | dbg!(b); - | ^^^^^^^ the trait `Debug` is not implemented for fn item `fn() {b}` - | - = help: use parentheses to call this function: `b()` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0106, E0277, E0425, E0658. +Some errors have detailed explanations: E0106, E0425, E0658. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs index 26fa6fdb57f95..35a2ef10c2e3c 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs @@ -9,6 +9,5 @@ static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = //~^ ERROR missing lifetime specifier [E0106] &(non_elidable as fn(&u8, &u8) -> &u8); //~^ ERROR missing lifetime specifier [E0106] - //~| ERROR non-primitive cast fn main() {} diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr index 77fc3f0412ebf..05ea6e44486fd 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr @@ -23,13 +23,6 @@ help: consider making the type lifetime-generic with a new `'a` lifetime LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); | +++++++ ++ ++ ++ -error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8` - --> $DIR/rfc1623-3.rs:10:6 - | -LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0106, E0605. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index ca223e4cb8e57..a91a15bc63dff 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -114,10 +114,10 @@ hir-stats - Type 16 (NN.N%) 1 hir-stats - Lifetime 48 (NN.N%) 3 hir-stats ExprField 40 (NN.N%) 1 40 hir-stats Mod 32 (NN.N%) 1 32 -hir-stats Lifetime 32 (NN.N%) 1 32 +hir-stats Lifetime 28 (NN.N%) 1 28 hir-stats TraitItemId 8 (NN.N%) 2 4 hir-stats ImplItemId 8 (NN.N%) 2 4 hir-stats ForeignItemId 4 (NN.N%) 1 4 hir-stats ---------------------------------------------------------------- -hir-stats Total 8_580 172 +hir-stats Total 8_576 172 hir-stats ================================================================