From 30cf7a3f51d6a25006077d3e9ec3222de3104b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 3 Feb 2023 23:21:56 +0000 Subject: [PATCH 1/6] Introduce `ReError` CC #69314 --- .../src/diagnostics/region_name.rs | 10 +- .../src/region_infer/opaque_types.rs | 2 +- .../rustc_borrowck/src/universal_regions.rs | 2 + .../rustc_hir_analysis/src/astconv/mod.rs | 12 +- .../src/check/compare_impl_item.rs | 2 +- .../rustc_hir_analysis/src/collect/type_of.rs | 2 +- .../rustc_hir_analysis/src/outlives/utils.rs | 2 + .../src/variance/constraints.rs | 2 + .../src/errors/note_and_explain.rs | 2 + .../src/infer/canonical/canonicalizer.rs | 1 + compiler/rustc_infer/src/infer/combine.rs | 6 +- .../src/infer/error_reporting/mod.rs | 17 ++- .../src/infer/error_reporting/note.rs | 6 +- compiler/rustc_infer/src/infer/freshen.rs | 1 + .../src/infer/lexical_region_resolve/mod.rs | 12 +- .../src/infer/region_constraints/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 9 +- compiler/rustc_middle/src/ty/generics.rs | 2 +- compiler/rustc_middle/src/ty/opaque_types.rs | 6 +- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- compiler/rustc_middle/src/ty/sty.rs | 7 ++ compiler/rustc_resolve/src/late.rs | 1 - .../src/typeid/typeid_itanium_cxx_abi.rs | 1 + compiler/rustc_traits/src/chalk/lowering.rs | 3 + compiler/rustc_type_ir/src/sty.rs | 12 +- src/librustdoc/clean/mod.rs | 1 + .../ui/associated-type-bounds/elision.stderr | 4 +- .../async-await/async-fn-path-elision.stderr | 1 - .../const-param-elided-lifetime.min.stderr | 10 +- .../const-param-elided-lifetime.rs | 10 +- .../issues/issue-56445-1.min.stderr | 2 +- .../ui/const-generics/issues/issue-56445-1.rs | 2 +- ...incorrect-explicit-lifetime-name-needed.rs | 1 - ...rrect-explicit-lifetime-name-needed.stderr | 18 +-- .../path-elided.stderr | 1 - .../trait-elided.stderr | 1 - .../in-trait/signature-mismatch.stderr | 4 +- tests/ui/inference/issue-107090.rs | 10 +- tests/ui/inference/issue-107090.stderr | 115 ++---------------- tests/ui/issues/issue-10412.stderr | 1 - tests/ui/lifetimes/issue-26638.stderr | 4 +- tests/ui/lifetimes/issue-69314.fixed | 22 ++++ tests/ui/lifetimes/issue-69314.rs | 22 ++++ tests/ui/lifetimes/issue-69314.stderr | 26 ++++ .../ui/lifetimes/unusual-rib-combinations.rs | 2 +- .../lifetimes/unusual-rib-combinations.stderr | 2 +- .../issue-74918-missing-lifetime.stderr | 4 +- .../generic_type_does_not_live_long_enough.rs | 2 +- ...eric_type_does_not_live_long_enough.stderr | 2 +- .../wf/wf-in-foreign-fn-decls-issue-80468.rs | 2 +- .../wf-in-foreign-fn-decls-issue-80468.stderr | 25 +--- 51 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 tests/ui/lifetimes/issue-69314.fixed create mode 100644 tests/ui/lifetimes/issue-69314.rs create mode 100644 tests/ui/lifetimes/issue-69314.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 2440f20502a..d56ca1981ae 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -343,11 +343,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let note = match closure_kind_ty.to_opt_closure_kind() { Some(ty::ClosureKind::Fn) => { "closure implements `Fn`, so references to captured variables \ - can't escape the closure" + can't escape the closure" } Some(ty::ClosureKind::FnMut) => { "closure implements `FnMut`, so references to captured variables \ - can't escape the closure" + can't escape the closure" } Some(ty::ClosureKind::FnOnce) => { bug!("BrEnv in a `FnOnce` closure"); @@ -364,7 +364,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ty::BoundRegionKind::BrAnon(..) => None, }, - ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None, + ty::ReLateBound(..) + | ty::ReVar(..) + | ty::RePlaceholder(..) + | ty::ReErased + | ty::ReError => None, } } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index e0e814cfc0a..e598b70d12a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -95,7 +95,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { concrete_type.span, "opaque type with non-universal region substs", ); - infcx.tcx.lifetimes.re_static + infcx.tcx.lifetimes.re_error } } }; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 5380913f5c8..6680c57b0c9 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -821,6 +821,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> { pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.to_region_vid() + } else if let ty::ReError = *r { + RegionVid::new(0) } else { *self .indices diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3d5f189e233..a1f5782fbd5 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -264,10 +264,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // reported an error in this case -- but if // not, let's error out. tcx.sess.delay_span_bug(lifetime.ident.span, "unelided lifetime in signature"); - - // Supply some dummy value. We don't have an - // `re_error`, annoyingly, so use `'static`. - tcx.lifetimes.re_static + tcx.lifetimes.re_error }) } } @@ -482,10 +479,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // This indicates an illegal lifetime in a non-assoc-trait position tcx.sess.delay_span_bug(self.span, "unelided lifetime in signature"); - - // Supply some dummy value. We don't have an - // `re_error`, annoyingly, so use `'static`. - tcx.lifetimes.re_static + tcx.lifetimes.re_error }) .into(), GenericParamDefKind::Type { has_default, .. } => { @@ -1629,7 +1623,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.emit(); } - tcx.lifetimes.re_static + tcx.lifetimes.re_error }) } }) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 236e36f28ca..facfc4313f4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -792,7 +792,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( return_span, "expected ReFree to map to ReEarlyBound" ); - return tcx.lifetimes.re_static; + return tcx.lifetimes.re_error; }; tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: e.def_id, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c5522c94874..e80ff89623a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -928,7 +928,7 @@ fn infer_placeholder_type<'a>( // Typeck doesn't expect erased regions to be returned from `type_of`. tcx.fold_regions(ty, |r, _| match *r { - ty::ReErased => tcx.lifetimes.re_static, + ty::ReErased | ty::ReError => tcx.lifetimes.re_static, _ => r, }) } diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 9459c5f54ab..bca385f6bdc 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -170,6 +170,8 @@ fn is_free_region(region: Region<'_>) -> bool { // ignore it. We can't put it on the struct header anyway. ty::ReLateBound(..) => false, + ty::ReError => false, + // These regions don't appear in types from type declarations: ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => { bug!("unexpected region in outlives inference: {:?}", region); diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 165782f209a..06a4a5d366f 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -409,6 +409,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // way early-bound regions do, so we skip them here. } + ty::ReError => {} + ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => { // We don't expect to see anything but 'static or bound // regions when visiting member types or method types. diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 7aaa5ce2f42..b51a85977e7 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -31,6 +31,8 @@ impl<'a> DescriptionCtx<'a> { ty::RePlaceholder(_) => return None, + ty::ReError => return None, + // FIXME(#13998) RePlaceholder should probably print like // ReFree rather than dumping Debug output on the user. // diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 87c6dfad5fa..78a86b4e267 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -371,6 +371,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ty::ReStatic | ty::ReEarlyBound(..) + | ty::ReError | ty::ReFree(_) | ty::RePlaceholder(..) | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a567b6acdbe..a7684ea1ff6 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -705,6 +705,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { return Ok(r); } + ty::ReError => { + return Ok(r); + } + ty::RePlaceholder(..) | ty::ReVar(..) | ty::ReStatic @@ -861,7 +865,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. - ty::ReLateBound(..) | ty::ReErased => { + ty::ReLateBound(..) | ty::ReErased | ty::ReError => { return Ok(r); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 86f3174b7b2..ceaa58257bb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -134,6 +134,8 @@ pub(super) fn note_and_explain_region<'tcx>( ty::RePlaceholder(_) => return, + ty::ReError => return, + // FIXME(#13998) RePlaceholder should probably print like // ReFree rather than dumping Debug output on the user. // @@ -313,6 +315,9 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( ) } } + ty::ReError => { + err.delay_as_bug(); + } _ => { // Ugh. This is a painful case: the hidden region is not one // that we can easily summarize or explain. This can happen @@ -2546,7 +2551,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); err.note_expected_found(&"", sup_expected, &"", sup_found); - err.emit(); + if sub_region.is_error() | sup_region.is_error() { + err.delay_as_bug(); + } else { + err.emit(); + } return; } @@ -2562,7 +2571,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); self.note_region_origin(&mut err, &sub_origin); - err.emit(); + if sub_region.is_error() | sup_region.is_error() { + err.delay_as_bug(); + } else { + err.emit(); + } } /// Determine whether an error associated with the given span and definition diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index b18cbd404d4..bdd09a995dc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -78,7 +78,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { sub: Region<'tcx>, sup: Region<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - match origin { + let mut err = match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let mut err = self.report_and_explain_type_error(trace, terr); @@ -299,7 +299,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); err } + }; + if sub.is_error() || sup.is_error() { + err.delay_as_bug(); } + err } pub fn suggest_copy_trait_method_bounds( diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 2355234637c..33cd29d26fe 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -126,6 +126,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::ReFree(_) | ty::ReVar(_) | ty::RePlaceholder(..) + | ty::ReError | ty::ReErased => { // replace all free regions with 'erased self.tcx().lifetimes.re_erased diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index ce8aec8044b..c79ef980282 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -17,7 +17,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{ReEarlyBound, ReErased, ReFree, ReStatic}; +use rustc_middle::ty::{ReEarlyBound, ReErased, ReError, ReFree, ReStatic}; use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar}; use rustc_middle::ty::{Region, RegionVid}; use rustc_span::Span; @@ -211,7 +211,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - ReStatic => { + ReStatic | ReError => { // nothing lives longer than `'static` Ok(self.tcx().lifetimes.re_static) } @@ -436,7 +436,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } (VarValue::Value(a), VarValue::Empty(_)) => { match *a { - ReLateBound(..) | ReErased => { + ReLateBound(..) | ReErased | ReError => { bug!("cannot relate region: {:?}", a); } @@ -465,7 +465,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } (VarValue::Empty(a_ui), VarValue::Value(b)) => { match *b { - ReLateBound(..) | ReErased => { + ReLateBound(..) | ReErased | ReError => { bug!("cannot relate region: {:?}", b); } @@ -546,6 +546,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } + (ReError, _) | (_, ReError) => self.tcx().lifetimes.re_error, + (ReStatic, _) | (_, ReStatic) => { // nothing lives longer than `'static` self.tcx().lifetimes.re_static @@ -1040,7 +1042,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, - VarValue::ErrorValue => tcx.lifetimes.re_static, + VarValue::ErrorValue => tcx.lifetimes.re_error, }, _ => r, }; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 0428481b7ff..f7b5129b49f 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -696,7 +696,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { match *region { - ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => { + ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) | ty::ReError => { ty::UniverseIndex::ROOT } ty::RePlaceholder(placeholder) => placeholder.universe, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9205a8a0ffe..948675ebc37 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -275,6 +275,9 @@ pub struct CommonLifetimes<'tcx> { /// Erased region, used outside of type inference. pub re_erased: Region<'tcx>, + + /// Error region, used only for error reporting. + pub re_error: Region<'tcx>, } pub struct CommonConsts<'tcx> { @@ -324,7 +327,11 @@ impl<'tcx> CommonLifetimes<'tcx> { )) }; - CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) } + CommonLifetimes { + re_static: mk(ty::ReStatic), + re_erased: mk(ty::ReErased), + re_error: mk(ty::ReError), + } } } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 801ca600445..7cbf7994be0 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -100,7 +100,7 @@ impl GenericParamDef { preceding_substs: &[ty::GenericArg<'tcx>], ) -> ty::GenericArg<'tcx> { match &self.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(), + ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_error.into(), ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into() diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 7ff58f02623..576cccc09d5 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -109,6 +109,8 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { // them. ty::ReErased => return r, + ty::ReError => return r, + // The regions that we expect from borrow checking. ty::ReEarlyBound(_) | ty::ReFree(_) => {} @@ -132,13 +134,13 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { self.span, format!( "lifetime `{}` is part of concrete type but not used in \ - parameter list of the `impl Trait` type alias", + parameter list of the `impl Trait` type alias", r ), ) .emit(); - self.tcx().lifetimes.re_static + self.tcx().lifetimes.re_error } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bbb4fd999bc..228827bcbf4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2114,7 +2114,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { ty::ReVar(_) if identify_regions => true, - ty::ReVar(_) | ty::ReErased => false, + ty::ReVar(_) | ty::ReErased | ty::ReError => false, ty::ReStatic => true, } @@ -2194,6 +2194,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } ty::ReVar(_) => {} ty::ReErased => {} + ty::ReError => {} ty::ReStatic => { p!("'static"); return Ok(self); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 98d6b683563..beadb9a2f0f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1623,9 +1623,15 @@ impl<'tcx> Region<'tcx> { ty::ReVar(..) => false, ty::RePlaceholder(placeholder) => placeholder.name.is_named(), ty::ReErased => false, + ty::ReError => false, } } + #[inline] + pub fn is_error(self) -> bool { + matches!(*self, ty::ReError) + } + #[inline] pub fn is_static(self) -> bool { matches!(*self, ty::ReStatic) @@ -1686,6 +1692,7 @@ impl<'tcx> Region<'tcx> { ty::ReErased => { flags = flags | TypeFlags::HAS_RE_ERASED; } + ty::ReError => {} } debug!("type_flags({:?}) = {:?}", self, flags); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3ca10ac50ba..b28aee40b16 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1725,7 +1725,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { !segment.has_generic_args, elided_lifetime_span, ); - err.note("assuming a `'static` lifetime..."); err.emit(); should_lint = false; diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index c9b4ab0a38d..4d58ff921e3 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -299,6 +299,7 @@ fn encode_region<'tcx>( RegionKind::ReEarlyBound(..) | RegionKind::ReFree(..) | RegionKind::ReStatic + | RegionKind::ReError | RegionKind::ReVar(..) | RegionKind::RePlaceholder(..) => { bug!("encode_region: unexpected `{:?}`", region.kind()); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 9c5db3314c5..05b201b9f99 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -493,6 +493,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ty::ReEarlyBound(_) => { panic!("Should have already been substituted."); } + ty::ReError => { + panic!("Error lifetime should not have already been lowered."); + } ty::ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( chalk_ir::DebruijnIndex::new(db.as_u32()), br.var.as_usize(), diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 3ede95e8431..0b573f96bf7 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -960,6 +960,9 @@ pub enum RegionKind { /// Erased region, used by trait selection, in MIR and during codegen. ReErased, + + /// A region that resulted from some other error. Used exclusively for diagnostics. + ReError, } // This is manually implemented for `RegionKind` because `std::mem::discriminant` @@ -974,6 +977,7 @@ const fn regionkind_discriminant(value: &RegionKind) -> usize { ReVar(_) => 4, RePlaceholder(_) => 5, ReErased => 6, + ReError => 7, } } @@ -999,6 +1003,7 @@ impl Clone for RegionKind { ReVar(r) => ReVar(r.clone()), RePlaceholder(r) => RePlaceholder(r.clone()), ReErased => ReErased, + ReError => ReError, } } } @@ -1077,6 +1082,7 @@ impl hash::Hash for RegionKind { ReVar(r) => r.hash(state), RePlaceholder(r) => r.hash(state), ReErased => (), + ReError => (), } } } @@ -1100,6 +1106,8 @@ impl fmt::Debug for RegionKind { RePlaceholder(placeholder) => write!(f, "RePlaceholder({placeholder:?})"), ReErased => f.write_str("ReErased"), + + ReError => f.write_str("ReError"), } } } @@ -1134,6 +1142,7 @@ where a.encode(e); }), ReErased => e.emit_enum_variant(disc, |_| {}), + ReError => e.emit_enum_variant(disc, |_| {}), } } } @@ -1156,6 +1165,7 @@ where 4 => ReVar(Decodable::decode(d)), 5 => RePlaceholder(Decodable::decode(d)), 6 => ReErased, + 7 => ReError, _ => panic!( "{}", format!( @@ -1184,7 +1194,7 @@ where ) { std::mem::discriminant(self).hash_stable(hcx, hasher); match self { - ReErased | ReStatic => { + ReErased | ReStatic | ReError => { // No variant fields to hash for these ... } ReLateBound(d, r) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 80493b100bb..8a493478e9c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -242,6 +242,7 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option { debug!("cannot clean region {:?}", region); diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr index b64a4dab206..cc10bbcc0b5 100644 --- a/tests/ui/associated-type-bounds/elision.stderr +++ b/tests/ui/associated-type-bounds/elision.stderr @@ -16,10 +16,10 @@ error[E0308]: mismatched types LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } | ----------------------------- -------------- ^^^^^^^^ expected `Option<&()>`, found `Option>` | | | - | | expected `Option<&'static ()>` because of return type + | | expected `Option<&()>` because of return type | this type parameter | - = note: expected enum `Option<&'static ()>` + = note: expected enum `Option<&()>` found enum `Option>` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/async-fn-path-elision.stderr b/tests/ui/async-await/async-fn-path-elision.stderr index 5e0c8c29989..224198653dc 100644 --- a/tests/ui/async-await/async-fn-path-elision.stderr +++ b/tests/ui/async-await/async-fn-path-elision.stderr @@ -4,7 +4,6 @@ error[E0726]: implicit elided lifetime not allowed here LL | async fn error(lt: HasLifetime) { | ^^^^^^^^^^^ expected lifetime parameter | - = note: assuming a `'static` lifetime... help: indicate the anonymous lifetime | LL | async fn error(lt: HasLifetime<'_>) { diff --git a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr index 4bba42c7782..656bc29466f 100644 --- a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr +++ b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr @@ -28,7 +28,7 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here LL | fn bar() {} | ^ explicit lifetime name needed here -error: `&'static u8` is forbidden as the type of a const generic parameter +error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:9:19 | LL | struct A; @@ -37,7 +37,7 @@ LL | struct A; = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: `&'static u8` is forbidden as the type of a const generic parameter +error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:14:15 | LL | impl A { @@ -46,7 +46,7 @@ LL | impl A { = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: `&'static u8` is forbidden as the type of a const generic parameter +error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:22:15 | LL | impl B for A {} @@ -55,7 +55,7 @@ LL | impl B for A {} = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: `&'static u8` is forbidden as the type of a const generic parameter +error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:26:17 | LL | fn bar() {} @@ -64,7 +64,7 @@ LL | fn bar() {} = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: `&'static u8` is forbidden as the type of a const generic parameter +error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:17:21 | LL | fn foo(&self) {} diff --git a/tests/ui/const-generics/const-param-elided-lifetime.rs b/tests/ui/const-generics/const-param-elided-lifetime.rs index 487b82dbf4a..45611d6bf5f 100644 --- a/tests/ui/const-generics/const-param-elided-lifetime.rs +++ b/tests/ui/const-generics/const-param-elided-lifetime.rs @@ -8,23 +8,23 @@ struct A; //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR `&'static u8` is forbidden +//[min]~^^ ERROR `&u8` is forbidden trait B {} impl A { //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR `&'static u8` is forbidden +//[min]~^^ ERROR `&u8` is forbidden fn foo(&self) {} //~^ ERROR `&` without an explicit lifetime name cannot be used here - //[min]~^^ ERROR `&'static u8` is forbidden + //[min]~^^ ERROR `&u8` is forbidden } impl B for A {} //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR `&'static u8` is forbidden +//[min]~^^ ERROR `&u8` is forbidden fn bar() {} //~^ ERROR `&` without an explicit lifetime name cannot be used here -//[min]~^^ ERROR `&'static u8` is forbidden +//[min]~^^ ERROR `&u8` is forbidden fn main() {} diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr index 43a5df117fd..9f880134162 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr @@ -6,7 +6,7 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | = note: for more information, see issue #74052 -error: `&'static str` is forbidden as the type of a const generic parameter +error: `&str` is forbidden as the type of a const generic parameter --> $DIR/issue-56445-1.rs:9:25 | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); diff --git a/tests/ui/const-generics/issues/issue-56445-1.rs b/tests/ui/const-generics/issues/issue-56445-1.rs index 13eb2ea9f69..0741c3796ad 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.rs +++ b/tests/ui/const-generics/issues/issue-56445-1.rs @@ -8,6 +8,6 @@ use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); //~^ ERROR: use of non-static lifetime `'a` in const generic -//[min]~| ERROR: `&'static str` is forbidden as the type of a const generic parameter +//[min]~| ERROR: `&str` is forbidden as the type of a const generic parameter impl Bug<'_, ""> {} diff --git a/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs b/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs index 9ea9fc71b55..54b483f53d4 100644 --- a/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs +++ b/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs @@ -8,7 +8,6 @@ fn should_error() where T : Into<&u32> {} trait X<'a, K: 'a> { fn foo<'b, L: X<&'b Nested>>(); //~^ ERROR missing lifetime specifier [E0106] - //~| ERROR the type `&'b Nested` does not fulfill the required lifetime } fn bar<'b, L: X<&'b Nested>>(){} diff --git a/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr b/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr index 9d859fddf56..faf4c9eb872 100644 --- a/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr +++ b/tests/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr @@ -29,7 +29,7 @@ LL | fn foo<'b, L: X<'lifetime, &'b Nested>>(); | ++++++++++ error[E0106]: missing lifetime specifier - --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:14:16 + --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:16 | LL | fn bar<'b, L: X<&'b Nested>>(){} | ^ expected named lifetime parameter @@ -39,19 +39,7 @@ help: consider using the `'b` lifetime LL | fn bar<'b, L: X<'b, &'b Nested>>(){} | +++ -error[E0477]: the type `&'b Nested` does not fulfill the required lifetime - --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:19 - | -LL | fn foo<'b, L: X<&'b Nested>>(); - | ^^^^^^^^^^^^^^^^ - | -note: type must satisfy the static lifetime as required by this binding - --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:8:16 - | -LL | trait X<'a, K: 'a> { - | ^^ +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0106, E0477, E0637. +Some errors have detailed explanations: E0106, E0637. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-header-lifetime-elision/path-elided.stderr b/tests/ui/impl-header-lifetime-elision/path-elided.stderr index 0b7d3f1e851..18e4c618dba 100644 --- a/tests/ui/impl-header-lifetime-elision/path-elided.stderr +++ b/tests/ui/impl-header-lifetime-elision/path-elided.stderr @@ -4,7 +4,6 @@ error[E0726]: implicit elided lifetime not allowed here LL | impl MyTrait for Foo { | ^^^ expected lifetime parameter | - = note: assuming a `'static` lifetime... help: indicate the anonymous lifetime | LL | impl MyTrait for Foo<'_> { diff --git a/tests/ui/impl-header-lifetime-elision/trait-elided.stderr b/tests/ui/impl-header-lifetime-elision/trait-elided.stderr index 412bba6be71..74631a03786 100644 --- a/tests/ui/impl-header-lifetime-elision/trait-elided.stderr +++ b/tests/ui/impl-header-lifetime-elision/trait-elided.stderr @@ -4,7 +4,6 @@ error[E0726]: implicit elided lifetime not allowed here LL | impl MyTrait for u32 {} | ^^^^^^^ expected lifetime parameter | - = note: assuming a `'static` lifetime... help: indicate the anonymous lifetime | LL | impl MyTrait<'_> for u32 {} diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.stderr index e105660173b..c4fcaabe446 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.stderr @@ -2,12 +2,12 @@ error: `impl` item signature doesn't match `trait` item signature --> $DIR/signature-mismatch.rs:15:5 | LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; - | ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future> + 'static` + | ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '3` ... LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` | - = note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + 'static` + = note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '3` found signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output diff --git a/tests/ui/inference/issue-107090.rs b/tests/ui/inference/issue-107090.rs index 9426445656f..a22e12c6d88 100644 --- a/tests/ui/inference/issue-107090.rs +++ b/tests/ui/inference/issue-107090.rs @@ -2,9 +2,7 @@ use std::marker::PhantomData; struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) where Foo<'short, 'out, T>: Convert<'a, 'b>; - //~^ ERROR mismatched types - //~^^ ERROR mismatched types - //~^^^ ERROR use of undeclared lifetime name + //~^ ERROR use of undeclared lifetime name //~| ERROR use of undeclared lifetime name `'out` trait Convert<'a, 'b>: Sized { @@ -13,19 +11,15 @@ trait Convert<'a, 'b>: Sized { impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { //~^ ERROR use of undeclared lifetime name //~^^ ERROR use of undeclared lifetime name `'out` - //~| ERROR cannot infer an appropriate lifetime for lifetime parameter fn cast(&'long self) -> &'short Foo<'short, 'out, T> { //~^ ERROR use of undeclared lifetime name - //~| ERROR cannot infer an appropriate lifetime for lifetime parameter self } } fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { //~^ ERROR use of undeclared lifetime name - //~^^ ERROR incompatible lifetime on type - //~| ERROR `x` has lifetime `'in_` but it needs to satisfy a `'static` lifetime requirement - sadness.cast() + sadness.cast() //~ ERROR mismatched types } fn main() {} diff --git a/tests/ui/inference/issue-107090.stderr b/tests/ui/inference/issue-107090.stderr index 33cb39014ac..6233b629ad6 100644 --- a/tests/ui/inference/issue-107090.stderr +++ b/tests/ui/inference/issue-107090.stderr @@ -30,7 +30,7 @@ LL | struct Foo<'out, 'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) | +++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/issue-107090.rs:13:47 + --> $DIR/issue-107090.rs:11:47 | LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { | - ^^ undeclared lifetime @@ -38,13 +38,13 @@ LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> | help: consider introducing lifetime `'b` here: `'b,` error[E0261]: use of undeclared lifetime name `'out` - --> $DIR/issue-107090.rs:13:67 + --> $DIR/issue-107090.rs:11:67 | LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { | - help: consider introducing lifetime `'out` here: `'out,` ^^^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'out` - --> $DIR/issue-107090.rs:17:49 + --> $DIR/issue-107090.rs:14:49 | LL | fn cast(&'long self) -> &'short Foo<'short, 'out, T> { | ^^^^ undeclared lifetime @@ -59,7 +59,7 @@ LL | impl<'out, 'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'ou | +++++ error[E0261]: use of undeclared lifetime name `'short` - --> $DIR/issue-107090.rs:24:68 + --> $DIR/issue-107090.rs:20:68 | LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { | - ^^^^^^ undeclared lifetime @@ -67,107 +67,18 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, | help: consider introducing lifetime `'short` here: `'short,` error[E0308]: mismatched types - --> $DIR/issue-107090.rs:4:27 - | -LL | Foo<'short, 'out, T>: Convert<'a, 'b>; - | ^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected trait `Convert<'static, 'static>` - found trait `Convert<'a, 'b>` -note: the lifetime `'a` as defined here... - --> $DIR/issue-107090.rs:2:12 - | -LL | struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) - | ^^ - = note: ...does not necessarily outlive the static lifetime - -error[E0308]: mismatched types - --> $DIR/issue-107090.rs:4:27 - | -LL | Foo<'short, 'out, T>: Convert<'a, 'b>; - | ^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected trait `Convert<'static, 'static>` - found trait `Convert<'a, 'b>` -note: the lifetime `'b` as defined here... - --> $DIR/issue-107090.rs:2:16 - | -LL | struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) - | ^^ - = note: ...does not necessarily outlive the static lifetime - -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'long` due to conflicting requirements - --> $DIR/issue-107090.rs:13:55 - | -LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { - | ^^^^^^^^^^^^^^^^^^^^ - | -note: first, the lifetime cannot outlive the lifetime `'short` as defined here... - --> $DIR/issue-107090.rs:13:21 - | -LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { - | ^^^^^^ - = note: ...but the lifetime must also be valid for the static lifetime... -note: ...so that the types are compatible - --> $DIR/issue-107090.rs:13:55 - | -LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { - | ^^^^^^^^^^^^^^^^^^^^ - = note: expected `Convert<'short, 'static>` - found `Convert<'_, 'static>` - -error: incompatible lifetime on type - --> $DIR/issue-107090.rs:24:29 + --> $DIR/issue-107090.rs:22:5 | LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { - | ^^^^^^^^^^^^^^^^^^ + | - this type parameter ------- expected `&'out T` because of return type +LL | +LL | sadness.cast() + | ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>` | -note: because this has an unmet lifetime requirement - --> $DIR/issue-107090.rs:4:27 - | -LL | Foo<'short, 'out, T>: Convert<'a, 'b>; - | ^^^^^^^^^^^^^^^ introduces a `'static` lifetime requirement -note: the lifetime `'out` as defined here... - --> $DIR/issue-107090.rs:24:17 - | -LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { - | ^^^^ -note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl` - --> $DIR/issue-107090.rs:13:1 - | -LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected reference `&'out T` + found reference `&Foo<'_, '_, T>` -error[E0759]: `x` has lifetime `'in_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/issue-107090.rs:24:29 - | -LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { - | ^^^^^^^^^^^^^^^^^^ - | | - | this data with lifetime `'in_`... - | ...is used and required to live as long as `'static` here +error: aborting due to 7 previous errors -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'long` due to conflicting requirements - --> $DIR/issue-107090.rs:17:13 - | -LL | fn cast(&'long self) -> &'short Foo<'short, 'out, T> { - | ^^^^^^^^^^^ - | -note: first, the lifetime cannot outlive the lifetime `'short` as defined here... - --> $DIR/issue-107090.rs:13:21 - | -LL | impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { - | ^^^^^^ - = note: ...but the lifetime must also be valid for the static lifetime... -note: ...so that the types are compatible - --> $DIR/issue-107090.rs:17:13 - | -LL | fn cast(&'long self) -> &'short Foo<'short, 'out, T> { - | ^^^^^^^^^^^ - = note: expected `Convert<'short, 'static>` - found `Convert<'_, 'static>` - -error: aborting due to 12 previous errors - -Some errors have detailed explanations: E0261, E0308, E0495, E0759. +Some errors have detailed explanations: E0261, E0308. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/issues/issue-10412.stderr b/tests/ui/issues/issue-10412.stderr index 46b9fd541ad..26666782d2a 100644 --- a/tests/ui/issues/issue-10412.stderr +++ b/tests/ui/issues/issue-10412.stderr @@ -46,7 +46,6 @@ error[E0726]: implicit elided lifetime not allowed here LL | impl<'self> Serializable for &'self str { | ^^^^^^^^^^^^^^^^^ expected lifetime parameter | - = note: assuming a `'static` lifetime... help: indicate the anonymous lifetime | LL | impl<'self> Serializable<'_, str> for &'self str { diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index 4dfacb93801..30afcecf827 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -40,9 +40,9 @@ error[E0308]: mismatched types LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } | ---- ^^^^^^^^^^^ expected `&str`, found `Option<&str>` | | - | expected `&'static str` because of return type + | expected `&str` because of return type | - = note: expected reference `&'static str` + = note: expected reference `&str` found enum `Option<&str>` error[E0061]: this function takes 1 argument but 0 arguments were supplied diff --git a/tests/ui/lifetimes/issue-69314.fixed b/tests/ui/lifetimes/issue-69314.fixed new file mode 100644 index 00000000000..41116d4ea61 --- /dev/null +++ b/tests/ui/lifetimes/issue-69314.fixed @@ -0,0 +1,22 @@ +// run-rustfix +// edition:2021 +#![allow(dead_code, unused_mut, unused_variables)] +struct A {} +struct Msg<'a> { + s: &'a [i32], +} +impl A { + async fn g(buf: &[i32]) -> Msg<'_> { + Msg { s: &buf[0..1] } + } + async fn f() { + let mut buf = [0; 512]; + let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m = Self::g(m2).await; + Self::f2(m).await; + } + async fn f2(m: Msg<'_>) {} + //~^ ERROR implicit elided lifetime not allowed here +} + +fn main() {} diff --git a/tests/ui/lifetimes/issue-69314.rs b/tests/ui/lifetimes/issue-69314.rs new file mode 100644 index 00000000000..17445341eb6 --- /dev/null +++ b/tests/ui/lifetimes/issue-69314.rs @@ -0,0 +1,22 @@ +// run-rustfix +// edition:2021 +#![allow(dead_code, unused_mut, unused_variables)] +struct A {} +struct Msg<'a> { + s: &'a [i32], +} +impl A { + async fn g(buf: &[i32]) -> Msg<'_> { + Msg { s: &buf[0..1] } + } + async fn f() { + let mut buf = [0; 512]; + let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m = Self::g(m2).await; + Self::f2(m).await; + } + async fn f2(m: Msg) {} + //~^ ERROR implicit elided lifetime not allowed here +} + +fn main() {} diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr new file mode 100644 index 00000000000..7ae6789285b --- /dev/null +++ b/tests/ui/lifetimes/issue-69314.stderr @@ -0,0 +1,26 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/issue-69314.rs:18:20 + | +LL | async fn f2(m: Msg) {} + | ^^^ expected lifetime parameter + | +help: indicate the anonymous lifetime + | +LL | async fn f2(m: Msg<'_>) {} + | ++++ + +error[E0597]: `buf` does not live long enough + --> $DIR/issue-69314.rs:14:19 + | +LL | let m2 = &buf[..]; + | ^^^ borrowed value does not live long enough +LL | let m = Self::g(m2).await; + | ----------- argument requires that `buf` is borrowed for `'static` +LL | Self::f2(m).await; +LL | } + | - `buf` dropped here while still borrowed + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0597, E0726. +For more information about an error, try `rustc --explain E0597`. diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index b4c86aab863..1c122f42e59 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -23,6 +23,6 @@ fn c() {} // Elided lifetime in path in ConstGeneric fn d() {} //~^ ERROR missing lifetime specifier -//~| ERROR `S<'static>` is forbidden as the type of a const generic parameter +//~| ERROR `S<'_>` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 6d7b4250698..68f4fce0178 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -46,7 +46,7 @@ LL | fn a() -> [u8; foo::()] { = note: expected type `usize` found fn item `fn() {foo}` -error: `S<'static>` is forbidden as the type of a const generic parameter +error: `S<'_>` is forbidden as the type of a const generic parameter --> $DIR/unusual-rib-combinations.rs:24:15 | LL | fn d() {} diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr index 9ddea162944..b5231823099 100644 --- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr +++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr @@ -16,9 +16,9 @@ LL | fn next(&mut self) -> Option> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut ChunkingIterator) -> Option>` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | - = note: expected `fn(&'1 mut ChunkingIterator) -> Option>` + = note: expected `fn(&'1 mut ChunkingIterator) -> Option>` | - = note: expected signature `fn(&'1 mut ChunkingIterator) -> Option>` + = note: expected signature `fn(&'1 mut ChunkingIterator) -> Option>` found signature `fn(&'1 mut ChunkingIterator) -> Option>` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index d3e169a70d3..cdd8f6f1976 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -4,7 +4,7 @@ fn main() { let y = 42; let x = wrong_generic(&y); let z: i32 = x; - //~^ ERROR expected generic type parameter, found `&'static i32 + //~^ ERROR expected generic type parameter, found `&i32` } type WrongGeneric = impl 'static; diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index 19115fd2866..fa79e51e9f7 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -4,7 +4,7 @@ error: at least one trait must be specified LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ -error[E0792]: expected generic type parameter, found `&'static i32` +error[E0792]: expected generic type parameter, found `&i32` --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 | LL | let z: i32 = x; diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs index 4fcf8f403bb..0be5127dcc4 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs @@ -13,5 +13,5 @@ pub struct Ref<'a>(&'a u8); impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here extern "C" { - pub fn repro(_: Wrapper); //~ ERROR: incompatible lifetime on type + pub fn repro(_: Wrapper); } diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr index 94f6dc26624..b10856571a6 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr @@ -4,34 +4,11 @@ error[E0726]: implicit elided lifetime not allowed here LL | impl Trait for Ref {} | ^^^ expected lifetime parameter | - = note: assuming a `'static` lifetime... help: indicate the anonymous lifetime | LL | impl Trait for Ref<'_> {} | ++++ -error: incompatible lifetime on type - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21 - | -LL | pub fn repro(_: Wrapper); - | ^^^^^^^^^^^^ - | -note: because this has an unmet lifetime requirement - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23 - | -LL | pub struct Wrapper(T); - | ^^^^^ introduces a `'static` lifetime requirement -note: the anonymous lifetime as defined here... - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:29 - | -LL | pub fn repro(_: Wrapper); - | ^^^ -note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl` - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1 - | -LL | impl Trait for Ref {} - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0726`. From ffaf2a5c270f6677d7746f6ae30f498692afc750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 5 Feb 2023 12:32:27 +0000 Subject: [PATCH 2/6] review comments --- compiler/rustc_hir_analysis/src/collect/type_of.rs | 2 +- compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index e80ff89623a..c5522c94874 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -928,7 +928,7 @@ fn infer_placeholder_type<'a>( // Typeck doesn't expect erased regions to be returned from `type_of`. tcx.fold_regions(ty, |r, _| match *r { - ty::ReErased | ty::ReError => tcx.lifetimes.re_static, + ty::ReErased => tcx.lifetimes.re_static, _ => r, }) } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index c79ef980282..bc1d9dc3fde 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -211,11 +211,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - ReStatic | ReError => { + ReStatic => { // nothing lives longer than `'static` Ok(self.tcx().lifetimes.re_static) } + ReError => Ok(self.tcx().lifetimes.re_error), + ReEarlyBound(_) | ReFree(_) => { // All empty regions are less than early-bound, free, // and scope regions. From 861f4512353e83dbc67de34992058f44fc1b4648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Feb 2023 14:55:16 +0000 Subject: [PATCH 3/6] Change to `ReError(ErrorGuaranteed)` --- .../src/diagnostics/region_name.rs | 2 +- .../src/region_infer/opaque_types.rs | 5 ++-- .../rustc_borrowck/src/universal_regions.rs | 2 +- .../rustc_hir_analysis/src/astconv/mod.rs | 8 ++--- .../src/check/compare_impl_item.rs | 8 +---- .../rustc_hir_analysis/src/outlives/utils.rs | 2 +- .../src/variance/constraints.rs | 2 +- .../src/errors/note_and_explain.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 4 +-- .../src/infer/error_reporting/mod.rs | 4 +-- compiler/rustc_infer/src/infer/freshen.rs | 2 +- .../src/infer/lexical_region_resolve/mod.rs | 10 +++---- .../src/infer/region_constraints/mod.rs | 8 +++-- compiler/rustc_middle/src/ty/context.rs | 30 ++++++++++++++----- compiler/rustc_middle/src/ty/generics.rs | 2 +- compiler/rustc_middle/src/ty/opaque_types.rs | 4 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +-- compiler/rustc_middle/src/ty/sty.rs | 6 ++-- .../src/typeid/typeid_itanium_cxx_abi.rs | 2 +- compiler/rustc_traits/src/chalk/lowering.rs | 2 +- compiler/rustc_type_ir/src/sty.rs | 18 ++++++----- src/librustdoc/clean/mod.rs | 2 +- 23 files changed, 70 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index d56ca1981ae..237e063d8d1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -368,7 +368,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased - | ty::ReError => None, + | ty::ReError(_) => None, } } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index e598b70d12a..c7b22d5f2e6 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -91,11 +91,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } None => { subst_regions.push(vid); - infcx.tcx.sess.delay_span_bug( + infcx.tcx.re_error_with_message( concrete_type.span, "opaque type with non-universal region substs", - ); - infcx.tcx.lifetimes.re_error + ) } } }; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 6680c57b0c9..e813ff837ff 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -821,7 +821,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.to_region_vid() - } else if let ty::ReError = *r { + } else if let ty::ReError(_) = *r { RegionVid::new(0) } else { *self diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a1f5782fbd5..76dd3b9a0d1 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -263,8 +263,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // elision. `resolve_lifetime` should have // reported an error in this case -- but if // not, let's error out. - tcx.sess.delay_span_bug(lifetime.ident.span, "unelided lifetime in signature"); - tcx.lifetimes.re_error + tcx.re_error_with_message(lifetime.ident.span, "unelided lifetime in signature") }) } } @@ -478,8 +477,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?param, "unelided lifetime in signature"); // This indicates an illegal lifetime in a non-assoc-trait position - tcx.sess.delay_span_bug(self.span, "unelided lifetime in signature"); - tcx.lifetimes.re_error + tcx.re_error_with_message(self.span, "unelided lifetime in signature") }) .into(), GenericParamDefKind::Type { has_default, .. } => { @@ -1623,7 +1621,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.emit(); } - tcx.lifetimes.re_error + tcx.re_error() }) } }) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index facfc4313f4..640920638a7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -786,13 +786,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( } let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind()) else { - tcx - .sess - .delay_span_bug( - return_span, - "expected ReFree to map to ReEarlyBound" - ); - return tcx.lifetimes.re_error; + return tcx.re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound") }; tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: e.def_id, diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index bca385f6bdc..c5c5f63a108 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -170,7 +170,7 @@ fn is_free_region(region: Region<'_>) -> bool { // ignore it. We can't put it on the struct header anyway. ty::ReLateBound(..) => false, - ty::ReError => false, + ty::ReError(_) => false, // These regions don't appear in types from type declarations: ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 06a4a5d366f..b0cf0387f87 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // way early-bound regions do, so we skip them here. } - ty::ReError => {} + ty::ReError(_) => {} ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => { // We don't expect to see anything but 'static or bound diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index b51a85977e7..5d861a78af8 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -31,7 +31,7 @@ impl<'a> DescriptionCtx<'a> { ty::RePlaceholder(_) => return None, - ty::ReError => return None, + ty::ReError(_) => return None, // FIXME(#13998) RePlaceholder should probably print like // ReFree rather than dumping Debug output on the user. diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 78a86b4e267..13c39dab3ad 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -371,7 +371,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ty::ReStatic | ty::ReEarlyBound(..) - | ty::ReError + | ty::ReError(_) | ty::ReFree(_) | ty::RePlaceholder(..) | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a7684ea1ff6..1360044fe75 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -705,7 +705,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { return Ok(r); } - ty::ReError => { + ty::ReError(_) => { return Ok(r); } @@ -865,7 +865,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. - ty::ReLateBound(..) | ty::ReErased | ty::ReError => { + ty::ReLateBound(..) | ty::ReErased | ty::ReError(_) => { return Ok(r); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ceaa58257bb..88a0d6def5e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -134,7 +134,7 @@ pub(super) fn note_and_explain_region<'tcx>( ty::RePlaceholder(_) => return, - ty::ReError => return, + ty::ReError(_) => return, // FIXME(#13998) RePlaceholder should probably print like // ReFree rather than dumping Debug output on the user. @@ -315,7 +315,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( ) } } - ty::ReError => { + ty::ReError(_) => { err.delay_as_bug(); } _ => { diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 33cd29d26fe..1c76950cc6c 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::ReFree(_) | ty::ReVar(_) | ty::RePlaceholder(..) - | ty::ReError + | ty::ReError(_) | ty::ReErased => { // replace all free regions with 'erased self.tcx().lifetimes.re_erased diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index bc1d9dc3fde..d4a12195ca0 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -216,7 +216,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { Ok(self.tcx().lifetimes.re_static) } - ReError => Ok(self.tcx().lifetimes.re_error), + ReError(_) => Ok(self.tcx().re_error()), ReEarlyBound(_) | ReFree(_) => { // All empty regions are less than early-bound, free, @@ -438,7 +438,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } (VarValue::Value(a), VarValue::Empty(_)) => { match *a { - ReLateBound(..) | ReErased | ReError => { + ReLateBound(..) | ReErased | ReError(_) => { bug!("cannot relate region: {:?}", a); } @@ -467,7 +467,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } (VarValue::Empty(a_ui), VarValue::Value(b)) => { match *b { - ReLateBound(..) | ReErased | ReError => { + ReLateBound(..) | ReErased | ReError(_) => { bug!("cannot relate region: {:?}", b); } @@ -548,7 +548,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - (ReError, _) | (_, ReError) => self.tcx().lifetimes.re_error, + (ReError(_), _) | (_, ReError(_)) => self.tcx().re_error(), (ReStatic, _) | (_, ReStatic) => { // nothing lives longer than `'static` @@ -1044,7 +1044,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, - VarValue::ErrorValue => tcx.lifetimes.re_error, + VarValue::ErrorValue => tcx.re_error(), }, _ => r, }; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index f7b5129b49f..cb24375c7a3 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -696,9 +696,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { match *region { - ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) | ty::ReError => { - ty::UniverseIndex::ROOT - } + ty::ReStatic + | ty::ReErased + | ty::ReFree(..) + | ty::ReEarlyBound(..) + | ty::ReError(_) => ty::UniverseIndex::ROOT, ty::RePlaceholder(placeholder) => placeholder.universe, ty::ReVar(vid) => self.var_universe(vid), ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 948675ebc37..0e6126ae7c5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -275,9 +275,6 @@ pub struct CommonLifetimes<'tcx> { /// Erased region, used outside of type inference. pub re_erased: Region<'tcx>, - - /// Error region, used only for error reporting. - pub re_error: Region<'tcx>, } pub struct CommonConsts<'tcx> { @@ -327,11 +324,7 @@ impl<'tcx> CommonLifetimes<'tcx> { )) }; - CommonLifetimes { - re_static: mk(ty::ReStatic), - re_erased: mk(ty::ReErased), - re_error: mk(ty::ReError), - } + CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) } } } @@ -656,6 +649,27 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Error(reported)) } + /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` to ensure it + /// gets used. + #[track_caller] + pub fn re_error(self) -> Region<'tcx> { + self.re_error_with_message( + DUMMY_SP, + "RegionKind::ReError constructed but no error reported", + ) + } + + /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` with the given + /// `msg` to ensure it gets used. + #[track_caller] + pub fn re_error_with_message>(self, span: S, msg: &str) -> Region<'tcx> { + let reported = self.sess.delay_span_bug(span, msg); + let r = ty::ReError(reported); + Region(Interned::new_unchecked( + self.interners.region.intern(r, |r| InternedInSet(self.interners.arena.alloc(r))).0, + )) + } + /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` #[track_caller] pub fn const_error_with_guaranteed( diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 7cbf7994be0..0112debc1c8 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -100,7 +100,7 @@ impl GenericParamDef { preceding_substs: &[ty::GenericArg<'tcx>], ) -> ty::GenericArg<'tcx> { match &self.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_error.into(), + ty::GenericParamDefKind::Lifetime => tcx.re_error().into(), ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into() diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 576cccc09d5..624b62e1800 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -109,7 +109,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { // them. ty::ReErased => return r, - ty::ReError => return r, + ty::ReError(_) => return r, // The regions that we expect from borrow checking. ty::ReEarlyBound(_) | ty::ReFree(_) => {} @@ -140,7 +140,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().lifetimes.re_error + self.tcx().re_error() } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 228827bcbf4..a8b23e64e82 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2114,7 +2114,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { ty::ReVar(_) if identify_regions => true, - ty::ReVar(_) | ty::ReErased | ty::ReError => false, + ty::ReVar(_) | ty::ReErased | ty::ReError(_) => false, ty::ReStatic => true, } @@ -2194,7 +2194,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } ty::ReVar(_) => {} ty::ReErased => {} - ty::ReError => {} + ty::ReError(_) => {} ty::ReStatic => { p!("'static"); return Ok(self); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index beadb9a2f0f..b3b2a4fd0e5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1623,13 +1623,13 @@ impl<'tcx> Region<'tcx> { ty::ReVar(..) => false, ty::RePlaceholder(placeholder) => placeholder.name.is_named(), ty::ReErased => false, - ty::ReError => false, + ty::ReError(_) => false, } } #[inline] pub fn is_error(self) -> bool { - matches!(*self, ty::ReError) + matches!(*self, ty::ReError(_)) } #[inline] @@ -1692,7 +1692,7 @@ impl<'tcx> Region<'tcx> { ty::ReErased => { flags = flags | TypeFlags::HAS_RE_ERASED; } - ty::ReError => {} + ty::ReError(_) => {} } debug!("type_flags({:?}) = {:?}", self, flags); diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 4d58ff921e3..710f3826403 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -299,7 +299,7 @@ fn encode_region<'tcx>( RegionKind::ReEarlyBound(..) | RegionKind::ReFree(..) | RegionKind::ReStatic - | RegionKind::ReError + | RegionKind::ReError(_) | RegionKind::ReVar(..) | RegionKind::RePlaceholder(..) => { bug!("encode_region: unexpected `{:?}`", region.kind()); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 05b201b9f99..65ed3105d10 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -493,7 +493,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ty::ReEarlyBound(_) => { panic!("Should have already been substituted."); } - ty::ReError => { + ty::ReError(_) => { panic!("Error lifetime should not have already been lowered."); } ty::ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 0b573f96bf7..ea31678b493 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -962,7 +962,7 @@ pub enum RegionKind { ReErased, /// A region that resulted from some other error. Used exclusively for diagnostics. - ReError, + ReError(I::ErrorGuaranteed), } // This is manually implemented for `RegionKind` because `std::mem::discriminant` @@ -977,7 +977,7 @@ const fn regionkind_discriminant(value: &RegionKind) -> usize { ReVar(_) => 4, RePlaceholder(_) => 5, ReErased => 6, - ReError => 7, + ReError(_) => 7, } } @@ -989,6 +989,7 @@ where I::FreeRegion: Copy, I::RegionVid: Copy, I::PlaceholderRegion: Copy, + I::ErrorGuaranteed: Copy, { } @@ -1003,7 +1004,7 @@ impl Clone for RegionKind { ReVar(r) => ReVar(r.clone()), RePlaceholder(r) => RePlaceholder(r.clone()), ReErased => ReErased, - ReError => ReError, + ReError(r) => ReError(r.clone()), } } } @@ -1082,7 +1083,7 @@ impl hash::Hash for RegionKind { ReVar(r) => r.hash(state), RePlaceholder(r) => r.hash(state), ReErased => (), - ReError => (), + ReError(_) => (), } } } @@ -1107,7 +1108,7 @@ impl fmt::Debug for RegionKind { ReErased => f.write_str("ReErased"), - ReError => f.write_str("ReError"), + ReError(_) => f.write_str("ReError"), } } } @@ -1142,7 +1143,7 @@ where a.encode(e); }), ReErased => e.emit_enum_variant(disc, |_| {}), - ReError => e.emit_enum_variant(disc, |_| {}), + ReError(_) => e.emit_enum_variant(disc, |_| {}), } } } @@ -1155,6 +1156,7 @@ where I::FreeRegion: Decodable, I::RegionVid: Decodable, I::PlaceholderRegion: Decodable, + I::ErrorGuaranteed: Decodable, { fn decode(d: &mut D) -> Self { match Decoder::read_usize(d) { @@ -1165,7 +1167,7 @@ where 4 => ReVar(Decodable::decode(d)), 5 => RePlaceholder(Decodable::decode(d)), 6 => ReErased, - 7 => ReError, + 7 => ReError(Decodable::decode(d)), _ => panic!( "{}", format!( @@ -1194,7 +1196,7 @@ where ) { std::mem::discriminant(self).hash_stable(hcx, hasher); match self { - ReErased | ReStatic | ReError => { + ReErased | ReStatic | ReError(_) => { // No variant fields to hash for these ... } ReLateBound(d, r) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8a493478e9c..5bda3620dd0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -242,7 +242,7 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option { debug!("cannot clean region {:?}", region); From ed8651c7b8f9a179b584124cde3994bb93433bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Feb 2023 15:11:04 +0000 Subject: [PATCH 4/6] Use 'static RegionVid for ReError --- compiler/rustc_borrowck/src/universal_regions.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index e813ff837ff..56930c89b2c 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -167,6 +167,9 @@ struct UniversalRegionIndices<'tcx> { /// contains an entry for `ReStatic` -- it might be nice to just /// use a substs, and then handle `ReStatic` another way. indices: FxHashMap, RegionVid>, + + /// The vid assigned to `'static`. Used only for diagnostics. + pub fr_static: RegionVid, } #[derive(Debug, PartialEq)] @@ -609,7 +612,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let subst_mapping = iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.to_region_vid())); - UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect() } + UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static } } fn compute_inputs_and_output( @@ -821,8 +824,11 @@ impl<'tcx> UniversalRegionIndices<'tcx> { pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.to_region_vid() - } else if let ty::ReError(_) = *r { - RegionVid::new(0) + } else if r.is_error() { + // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the + // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if + // errors are being emitted and 2) it leaves the happy path unaffected. + self.fr_static } else { *self .indices From 32227255386cb8387e3961845f101d23bac42b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 7 Feb 2023 15:47:28 +0000 Subject: [PATCH 5/6] Fix `RegionKind: PartialEq` to account for `ReError` --- compiler/rustc_type_ir/src/sty.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index ea31678b493..61557fdc0ed 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -1022,10 +1022,11 @@ impl PartialEq for RegionKind { (ReVar(a_r), ReVar(b_r)) => a_r == b_r, (RePlaceholder(a_r), RePlaceholder(b_r)) => a_r == b_r, (ReErased, ReErased) => true, + (ReError(_), ReError(_)) => true, _ => { debug_assert!( false, - "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}" + "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}" ); true } From 3689295a6bf43a6defbb392e1aca08757fa14a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Feb 2023 10:38:45 +0000 Subject: [PATCH 6/6] Use `ErrorGuaranteed` more in `ReError` --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 10 +++++----- .../src/infer/lexical_region_resolve/mod.rs | 8 +++++--- compiler/rustc_middle/src/ty/context.rs | 13 ++++++++----- compiler/rustc_middle/src/ty/generics.rs | 2 +- compiler/rustc_middle/src/ty/opaque_types.rs | 5 +++-- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 76dd3b9a0d1..f121979be71 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1614,14 +1614,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "the lifetime bound for this object type cannot be deduced \ from context; please supply an explicit bound" ); - if borrowed { + let e = if borrowed { // We will have already emitted an error E0106 complaining about a // missing named lifetime in `&dyn Trait`, so we elide this one. - err.delay_as_bug(); + err.delay_as_bug() } else { - err.emit(); - } - tcx.re_error() + err.emit() + }; + tcx.re_error(e) }) } }) diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index d4a12195ca0..4a2210bdb68 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -216,7 +216,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { Ok(self.tcx().lifetimes.re_static) } - ReError(_) => Ok(self.tcx().re_error()), + ReError(_) => Ok(a_region), ReEarlyBound(_) | ReFree(_) => { // All empty regions are less than early-bound, free, @@ -548,7 +548,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ); } - (ReError(_), _) | (_, ReError(_)) => self.tcx().re_error(), + (ReError(_), _) => a, + + (_, ReError(_)) => b, (ReStatic, _) | (_, ReStatic) => { // nothing lives longer than `'static` @@ -1044,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, - VarValue::ErrorValue => tcx.re_error(), + VarValue::ErrorValue => tcx.re_error_misc(), }, _ => r, }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0e6126ae7c5..d1d7d0f8430 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -649,10 +649,16 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Error(reported)) } + /// Constructs a `RegionKind::ReError` lifetime. + #[track_caller] + pub fn re_error(self, reported: ErrorGuaranteed) -> Region<'tcx> { + self.mk_region(ty::ReError(reported)) + } + /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` to ensure it /// gets used. #[track_caller] - pub fn re_error(self) -> Region<'tcx> { + pub fn re_error_misc(self) -> Region<'tcx> { self.re_error_with_message( DUMMY_SP, "RegionKind::ReError constructed but no error reported", @@ -664,10 +670,7 @@ impl<'tcx> TyCtxt<'tcx> { #[track_caller] pub fn re_error_with_message>(self, span: S, msg: &str) -> Region<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - let r = ty::ReError(reported); - Region(Interned::new_unchecked( - self.interners.region.intern(r, |r| InternedInSet(self.interners.arena.alloc(r))).0, - )) + self.re_error(reported) } /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 0112debc1c8..ea95a38f272 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -100,7 +100,7 @@ impl GenericParamDef { preceding_substs: &[ty::GenericArg<'tcx>], ) -> ty::GenericArg<'tcx> { match &self.kind { - ty::GenericParamDefKind::Lifetime => tcx.re_error().into(), + ty::GenericParamDefKind::Lifetime => tcx.re_error_misc().into(), ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into() diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 624b62e1800..a5ebdbc8792 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -127,7 +127,8 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(u) => panic!("region mapped to unexpected kind: {:?}", u), None if self.do_not_error => self.tcx.lifetimes.re_static, None => { - self.tcx + let e = self + .tcx .sess .struct_span_err(self.span, "non-defining opaque type use in defining scope") .span_label( @@ -140,7 +141,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().re_error() + self.tcx().re_error(e) } } }