diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 0707ff5ed02a0..6c1eaa809c905 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -357,11 +357,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ty::BoundRegionKind::BrAnon(_) => None, }, - ty::ReLateBound(..) - | ty::ReVar(..) - | ty::RePlaceholder(..) - | ty::ReEmpty(_) - | ty::ReErased => None, + ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None, } } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 0392367288c40..9d088642f7773 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -109,7 +109,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .iter() .find(|ur_vid| self.eval_equal(vid, **ur_vid)) .and_then(|ur_vid| self.definitions[*ur_vid].external_name) - .unwrap_or(infcx.tcx.lifetimes.re_root_empty), + .unwrap_or(infcx.tcx.lifetimes.re_erased), _ => region, }); @@ -433,7 +433,7 @@ struct ReverseMapper<'tcx> { key: ty::OpaqueTypeKey<'tcx>, map: FxHashMap, GenericArg<'tcx>>, - map_missing_regions_to_empty: bool, + do_not_error: bool, /// initially `Some`, set to `None` once error has been reported hidden_ty: Option>, @@ -450,29 +450,19 @@ impl<'tcx> ReverseMapper<'tcx> { hidden_ty: Ty<'tcx>, span: Span, ) -> Self { - Self { - tcx, - key, - map, - map_missing_regions_to_empty: false, - hidden_ty: Some(hidden_ty), - span, - } + Self { tcx, key, map, do_not_error: false, hidden_ty: Some(hidden_ty), span } } - fn fold_kind_mapping_missing_regions_to_empty( - &mut self, - kind: GenericArg<'tcx>, - ) -> GenericArg<'tcx> { - assert!(!self.map_missing_regions_to_empty); - self.map_missing_regions_to_empty = true; + fn fold_kind_no_missing_regions_error(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> { + assert!(!self.do_not_error); + self.do_not_error = true; let kind = kind.fold_with(self); - self.map_missing_regions_to_empty = false; + self.do_not_error = false; kind } fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> { - assert!(!self.map_missing_regions_to_empty); + assert!(!self.do_not_error); kind.fold_with(self) } } @@ -496,9 +486,9 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { ty::ReErased => return r, // The regions that we expect from borrow checking. - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {} + ty::ReEarlyBound(_) | ty::ReFree(_) => {} - ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => { + ty::RePlaceholder(_) | ty::ReVar(_) => { // All of the regions in the type should either have been // erased by writeback, or mapped back to named regions by // borrow checking. @@ -510,7 +500,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { match self.map.get(&r.into()).map(|k| k.unpack()) { Some(GenericArgKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), - None if self.map_missing_regions_to_empty => self.tcx.lifetimes.re_root_empty, + None if self.do_not_error => self.tcx.lifetimes.re_static, None if generics.parent.is_some() => { if let Some(hidden_ty) = self.hidden_ty.take() { unexpected_hidden_region_diagnostic( @@ -522,7 +512,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); } - self.tcx.lifetimes.re_root_empty + self.tcx.lifetimes.re_static } None => { self.tcx @@ -574,7 +564,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| { if index < generics.parent_count { // Accommodate missing regions in the parent kinds... - self.fold_kind_mapping_missing_regions_to_empty(kind) + self.fold_kind_no_missing_regions_error(kind) } else { // ...but not elsewhere. self.fold_kind_normally(kind) @@ -589,7 +579,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| { if index < generics.parent_count { // Accommodate missing regions in the parent kinds... - self.fold_kind_mapping_missing_regions_to_empty(kind) + self.fold_kind_no_missing_regions_error(kind) } else { // ...but not elsewhere. self.fold_kind_normally(kind) diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 7c10047e9dc83..f1b1c33a10543 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -347,13 +347,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { match outlives_bound { OutlivesBound::RegionSubRegion(r1, r2) => { - // `where Type:` is lowered to `where Type: 'empty` so that - // we check `Type` is well formed, but there's no use for - // this bound here. - if r1.is_empty() { - return; - } - // The bound says that `r1 <= r2`; we store `r2: r1`. let r1 = self.universal_regions.to_region_vid(r1); let r2 = self.universal_regions.to_region_vid(r2); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index b9b181681ec4b..8cf9ed53d39d0 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -54,13 +54,6 @@ pub struct UniversalRegions<'tcx> { /// The total number of universal region variables instantiated. num_universals: usize, - /// A special region variable created for the `'empty(U0)` region. - /// Note that this is **not** a "universal" region, as it doesn't - /// represent a universally bound placeholder or any such thing. - /// But we do create it here in this type because it's a useful region - /// to have around in a few limited cases. - pub root_empty: RegionVid, - /// The "defining" type for this function, with all universal /// regions instantiated. For a closure or generator, this is the /// closure type, but for a top-level function it's the `FnDef`. @@ -323,11 +316,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// See `UniversalRegionIndices::to_region_vid`. pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { - if let ty::ReEmpty(ty::UniverseIndex::ROOT) = *r { - self.root_empty - } else { - self.indices.to_region_vid(r) - } + self.indices.to_region_vid(r) } /// As part of the NLL unit tests, you can annotate a function with @@ -501,16 +490,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { _ => None, }; - let root_empty = self - .infcx - .next_nll_region_var(NllRegionVariableOrigin::Existential { from_forall: true }) - .to_region_vid(); - UniversalRegions { indices, fr_static, fr_fn_body, - root_empty, first_extern_index, first_local_index, num_universals, diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 6f1f9522c869d..7e051835b4bdf 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -27,13 +27,6 @@ impl<'a> DescriptionCtx<'a> { me.kind = "restatic"; } - ty::ReEmpty(ty::UniverseIndex::ROOT) => me.kind = "reempty", - - ty::ReEmpty(ui) => { - me.kind = "reemptyuni"; - me.arg = format!("{:?}", ui); - } - ty::RePlaceholder(_) => return None, // FIXME(#13998) RePlaceholder should probably print like diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 46f8c0e8d8b9a..9488d0a6cbb68 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -180,11 +180,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match *r { - ty::ReFree(_) - | ty::ReErased - | ty::ReStatic - | ty::ReEmpty(ty::UniverseIndex::ROOT) - | ty::ReEarlyBound(..) => r, + ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r, ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region( CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) }, @@ -199,10 +195,6 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { ) } - ty::ReEmpty(ui) => { - bug!("canonicalizing 'empty in universe {:?}", ui) // FIXME - } - _ => { // Other than `'static` or `'empty`, the query // response should be executing in a fully @@ -381,7 +373,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ty::ReStatic | ty::ReEarlyBound(..) | ty::ReFree(_) - | ty::ReEmpty(_) | 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 c1fb59009d369..524383e381fee 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -688,7 +688,6 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { ty::RePlaceholder(..) | ty::ReVar(..) - | ty::ReEmpty(_) | ty::ReStatic | ty::ReEarlyBound(..) | ty::ReFree(..) => { @@ -900,7 +899,6 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { ty::RePlaceholder(..) | ty::ReVar(..) - | ty::ReEmpty(_) | ty::ReStatic | ty::ReEarlyBound(..) | ty::ReFree(..) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 08460463998fd..9d5a128f8de30 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -97,11 +97,6 @@ pub(super) fn note_and_explain_region<'tcx>( msg_span_from_free_region(tcx, region, alt_span) } - ty::ReEmpty(ty::UniverseIndex::ROOT) => ("the empty lifetime".to_owned(), alt_span), - - // uh oh, hope no user ever sees THIS - ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), alt_span), - ty::RePlaceholder(_) => return, // FIXME(#13998) RePlaceholder should probably print like @@ -140,8 +135,6 @@ fn msg_span_from_free_region<'tcx>( (msg, Some(span)) } ty::ReStatic => ("the static lifetime".to_owned(), alt_span), - ty::ReEmpty(ty::UniverseIndex::ROOT) => ("an empty lifetime".to_owned(), alt_span), - ty::ReEmpty(ui) => (format!("an empty lifetime in universe {:?}", ui), alt_span), _ => bug!("{:?}", region), } } @@ -251,17 +244,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( // Explain the region we are capturing. match *hidden_region { - ty::ReEmpty(ty::UniverseIndex::ROOT) => { - // All lifetimes shorter than the function body are `empty` in - // lexical region resolution. The default explanation of "an empty - // lifetime" isn't really accurate here. - let message = format!( - "hidden type `{}` captures lifetime smaller than the function body", - hidden_ty - ); - err.span_note(span, &message); - } - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) => { + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { // Assuming regionck succeeded (*), we ought to always be // capturing *some* region from the fn header, and hence it // ought to be free. So under normal circumstances, we will go @@ -387,7 +370,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::UpperBoundUniverseConflict( _, _, - var_universe, + _, sup_origin, sup_r, ) => { @@ -398,7 +381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // placeholder. In practice, we expect more // tailored errors that don't really use this // value. - let sub_r = self.tcx.mk_region(ty::ReEmpty(var_universe)); + let sub_r = self.tcx.lifetimes.re_erased; self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit(); } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 84004d2b21f90..fee15afc7b3aa 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -126,7 +126,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::ReFree(_) | ty::ReVar(_) | ty::RePlaceholder(..) - | ty::ReEmpty(_) | 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 13b7e8eb96436..5f13b2b3deb1b 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -15,8 +15,9 @@ use rustc_data_structures::graph::implementation::{ use rustc_data_structures::intern::Interned; 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, ReEmpty, ReErased, ReFree, ReStatic}; +use rustc_middle::ty::{ReEarlyBound, ReErased, ReFree, ReStatic}; use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar}; use rustc_middle::ty::{Region, RegionVid}; use rustc_span::Span; @@ -51,6 +52,13 @@ pub struct LexicalRegionResolutions<'tcx> { #[derive(Copy, Clone, Debug)] pub(crate) enum VarValue<'tcx> { + /// Empty lifetime is for data that is never accessed. We tag the + /// empty lifetime with a universe -- the idea is that we don't + /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable. + /// Therefore, the `'empty` in a universe `U` is less than all + /// regions visible from `U`, but not less than regions not visible + /// from `U`. + Empty(ty::UniverseIndex), Value(Region<'tcx>), ErrorValue, } @@ -117,7 +125,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { &mut self, errors: &mut Vec>, ) -> LexicalRegionResolutions<'tcx> { - let mut var_data = self.construct_var_data(self.tcx()); + let mut var_data = self.construct_var_data(); if cfg!(debug_assertions) { self.dump_constraints(); @@ -137,13 +145,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// Initially, the value for all variables is set to `'empty`, the /// empty region. The `expansion` phase will grow this larger. - fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> { + fn construct_var_data(&self) -> LexicalRegionResolutions<'tcx> { LexicalRegionResolutions { values: IndexVec::from_fn_n( |vid| { let vid_universe = self.var_infos[vid].universe; - let re_empty = tcx.mk_region(ty::ReEmpty(vid_universe)); - VarValue::Value(re_empty) + VarValue::Empty(vid_universe) }, self.num_vars(), ), @@ -189,20 +196,131 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + /// Gets the LUb of a given region and the empty region + fn lub_empty(&self, a_region: Region<'tcx>) -> Result, PlaceholderRegion> { + match *a_region { + ReLateBound(..) | ReErased => { + bug!("cannot relate region: {:?}", a_region); + } + + ReVar(v_id) => { + span_bug!( + self.var_infos[v_id].origin.span(), + "lub invoked with non-concrete regions: {:?}", + a_region, + ); + } + + ReStatic => { + // nothing lives longer than `'static` + Ok(self.tcx().lifetimes.re_static) + } + + ReEarlyBound(_) | ReFree(_) => { + // All empty regions are less than early-bound, free, + // and scope regions. + Ok(a_region) + } + + RePlaceholder(placeholder) => Err(placeholder), + } + } + fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { + // In the first pass, we expand region vids according to constraints we + // have previously found. In the second pass, we loop through the region + // vids we expanded and expand *across* region vids (effectively + // "expanding" new `RegSubVar` constraints). + + // Tracks the `VarSubVar` constraints generated for each region vid. We + // later use this to expand across vids. let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len()); + // Tracks the changed region vids. let mut changes = Vec::new(); for constraint in self.data.constraints.keys() { - let (a_vid, a_region, b_vid, b_data) = match *constraint { + match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (None, a_region, b_vid, b_data) + + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); + } } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { VarValue::ErrorValue => continue, + VarValue::Empty(a_universe) => { + let b_data = var_values.value_mut(b_vid); + + let changed = (|| match *b_data { + VarValue::Empty(b_universe) => { + // Empty regions are ordered according to the universe + // they are associated with. + let ui = a_universe.min(b_universe); + + debug!( + "Expanding value of {:?} \ + from empty lifetime with universe {:?} \ + to empty lifetime with universe {:?}", + b_vid, b_universe, ui + ); + + *b_data = VarValue::Empty(ui); + true + } + VarValue::Value(cur_region) => { + let lub = match self.lub_empty(cur_region) { + Ok(r) => r, + // If the empty and placeholder regions are in the same universe, + // then the LUB is the Placeholder region (which is the cur_region). + // If they are not in the same universe, the LUB is the Static lifetime. + Err(placeholder) if a_universe == placeholder.universe => { + cur_region + } + Err(_) => self.tcx().lifetimes.re_static, + }; + + if lub == cur_region { + return false; + } + + debug!( + "Expanding value of {:?} from {:?} to {:?}", + b_vid, cur_region, lub + ); + + *b_data = VarValue::Value(lub); + true + } + + VarValue::ErrorValue => false, + })(); + + if changed { + changes.push(b_vid); + } + match b_data { + VarValue::Value(Region(Interned(ReStatic, _))) + | VarValue::ErrorValue => (), + _ => { + constraints[a_vid].push((a_vid, b_vid)); + constraints[b_vid].push((a_vid, b_vid)); + } + } + } VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); - (Some(a_vid), a_region, b_vid, b_data) + + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); + } + match b_data { + VarValue::Value(Region(Interned(ReStatic, _))) + | VarValue::ErrorValue => (), + _ => { + constraints[a_vid].push((a_vid, b_vid)); + constraints[b_vid].push((a_vid, b_vid)); + } + } } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { @@ -210,18 +328,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // is done, in `collect_errors`. continue; } - }; - if self.expand_node(a_region, b_vid, b_data) { - changes.push(b_vid); - } - if let Some(a_vid) = a_vid { - match b_data { - VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue => (), - _ => { - constraints[a_vid].push((a_vid, b_vid)); - constraints[b_vid].push((a_vid, b_vid)); - } - } } } @@ -242,6 +348,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + /// Expands the value of the region represented with `b_vid` with current + /// value `b_data` to the lub of `b_data` and `a_region`. The corresponds + /// with the constraint `'?b: 'a` (`'a <: '?b`), where `'a` is some known + /// region and `'?b` is some region variable. fn expand_node( &self, a_region: Region<'tcx>, @@ -263,14 +373,28 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } match *b_data { + VarValue::Empty(empty_ui) => { + let lub = match self.lub_empty(a_region) { + Ok(r) => r, + // If this empty region is from a universe that can + // name the placeholder, then the placeholder is + // larger; otherwise, the only ancestor is `'static`. + Err(placeholder) if empty_ui.can_name(placeholder.universe) => { + self.tcx().mk_region(RePlaceholder(placeholder)) + } + Err(_) => self.tcx().lifetimes.re_static, + }; + + debug!("Expanding value of {:?} from empty lifetime to {:?}", b_vid, lub); + + *b_data = VarValue::Value(lub); + true + } VarValue::Value(cur_region) => { // This is a specialized version of the `lub_concrete_regions` // check below for a common case, here purely as an // optimization. let b_universe = self.var_infos[b_vid].universe; - if let ReEmpty(a_universe) = *a_region && a_universe == b_universe { - return false; - } let mut lub = self.lub_concrete_regions(a_region, cur_region); if lub == cur_region { @@ -300,6 +424,78 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + /// True if `a <= b`. + fn sub_region_values(&self, a: VarValue<'tcx>, b: VarValue<'tcx>) -> bool { + match (a, b) { + // Error region is `'static` + (VarValue::ErrorValue, _) | (_, VarValue::ErrorValue) => return true, + (VarValue::Empty(a_ui), VarValue::Empty(b_ui)) => { + // Empty regions are ordered according to the universe + // they are associated with. + a_ui.min(b_ui) == b_ui + } + (VarValue::Value(a), VarValue::Empty(_)) => { + match *a { + ReLateBound(..) | ReErased => { + bug!("cannot relate region: {:?}", a); + } + + ReVar(v_id) => { + span_bug!( + self.var_infos[v_id].origin.span(), + "lub_concrete_regions invoked with non-concrete region: {:?}", + a + ); + } + + ReStatic | ReEarlyBound(_) | ReFree(_) => { + // nothing lives longer than `'static` + + // All empty regions are less than early-bound, free, + // and scope regions. + + false + } + + RePlaceholder(_) => { + // The LUB is either `a` or `'static` + false + } + } + } + (VarValue::Empty(a_ui), VarValue::Value(b)) => { + match *b { + ReLateBound(..) | ReErased => { + bug!("cannot relate region: {:?}", b); + } + + ReVar(v_id) => { + span_bug!( + self.var_infos[v_id].origin.span(), + "lub_concrete_regions invoked with non-concrete regions: {:?}", + b + ); + } + + ReStatic | ReEarlyBound(_) | ReFree(_) => { + // nothing lives longer than `'static` + // All empty regions are less than early-bound, free, + // and scope regions. + true + } + + RePlaceholder(placeholder) => { + // If this empty region is from a universe that can + // name the placeholder, then the placeholder is + // larger; otherwise, the only ancestor is `'static`. + if a_ui.can_name(placeholder.universe) { true } else { false } + } + } + } + (VarValue::Value(a), VarValue::Value(b)) => self.sub_concrete_regions(a, b), + } + } + /// True if `a <= b`, but not defined over inference variables. #[instrument(level = "trace", skip(self))] fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { @@ -355,37 +551,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.tcx().lifetimes.re_static } - (ReEmpty(_), ReEarlyBound(_) | ReFree(_)) => { - // All empty regions are less than early-bound, free, - // and scope regions. - b - } - - (ReEarlyBound(_) | ReFree(_), ReEmpty(_)) => { - // All empty regions are less than early-bound, free, - // and scope regions. - a - } - - (ReEmpty(a_ui), ReEmpty(b_ui)) => { - // Empty regions are ordered according to the universe - // they are associated with. - let ui = a_ui.min(b_ui); - self.tcx().mk_region(ReEmpty(ui)) - } - - (ReEmpty(empty_ui), RePlaceholder(placeholder)) - | (RePlaceholder(placeholder), ReEmpty(empty_ui)) => { - // If this empty region is from a universe that can - // name the placeholder, then the placeholder is - // larger; otherwise, the only ancestor is `'static`. - if empty_ui.can_name(placeholder.universe) { - self.tcx().mk_region(RePlaceholder(placeholder)) - } else { - self.tcx().lifetimes.re_static - } - } - (ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => { self.region_rels.lub_free_regions(a, b) } @@ -508,7 +673,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { for (node_vid, value) in var_data.values.iter_enumerated() { match *value { - VarValue::Value(_) => { /* Inference successful */ } + VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ } VarValue::ErrorValue => { // Inference impossible: this value contains // inconsistent constraints. @@ -829,12 +994,25 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } VerifyBound::OutlivedBy(r) => { - self.sub_concrete_regions(min, var_values.normalize(self.tcx(), *r)) + let a = match *min { + ty::ReVar(rid) => var_values.values[rid], + _ => VarValue::Value(min), + }; + let b = match **r { + ty::ReVar(rid) => var_values.values[rid], + _ => VarValue::Value(*r), + }; + self.sub_region_values(a, b) } - VerifyBound::IsEmpty => { - matches!(*min, ty::ReEmpty(_)) - } + VerifyBound::IsEmpty => match *min { + ty::ReVar(rid) => match var_values.values[rid] { + VarValue::ErrorValue => false, + VarValue::Empty(_) => true, + VarValue::Value(_) => false, + }, + _ => false, + }, VerifyBound::AnyBound(bs) => { bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min)) @@ -876,6 +1054,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ) -> ty::Region<'tcx> { let result = match *r { ty::ReVar(rid) => match self.values[rid] { + VarValue::Empty(_) => r, VarValue::Value(r) => r, VarValue::ErrorValue => tcx.lifetimes.re_static, }, diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 780e6ead10efa..e43d28ee56e3e 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -426,21 +426,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { data } - pub fn data(&self) -> &RegionConstraintData<'tcx> { + pub(super) fn data(&self) -> &RegionConstraintData<'tcx> { &self.data } - pub fn start_snapshot(&mut self) -> RegionSnapshot { + pub(super) fn start_snapshot(&mut self) -> RegionSnapshot { debug!("RegionConstraintCollector: start_snapshot"); RegionSnapshot { any_unifications: self.any_unifications } } - pub fn rollback_to(&mut self, snapshot: RegionSnapshot) { + pub(super) fn rollback_to(&mut self, snapshot: RegionSnapshot) { debug!("RegionConstraintCollector: rollback_to({:?})", snapshot); self.any_unifications = snapshot.any_unifications; } - pub fn new_region_var( + pub(super) fn new_region_var( &mut self, universe: ty::UniverseIndex, origin: RegionVariableOrigin, @@ -455,12 +455,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } /// Returns the universe for the given variable. - pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex { + pub(super) fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex { self.var_infos[vid].universe } /// Returns the origin for the given variable. - pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { + pub(super) fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { self.var_infos[vid].origin } @@ -492,7 +492,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.undo_log.push(AddVerify(index)); } - pub fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { + pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { // cannot add givens once regions are resolved if self.data.givens.insert((sub, sup)) { debug!("add_given({:?} <= {:?})", sub, sup); @@ -501,7 +501,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn make_eqregion( + pub(super) fn make_eqregion( &mut self, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, @@ -530,7 +530,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn member_constraint( + pub(super) fn member_constraint( &mut self, key: ty::OpaqueTypeKey<'tcx>, definition_span: Span, @@ -554,7 +554,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } #[instrument(skip(self, origin), level = "debug")] - pub fn make_subregion( + pub(super) fn make_subregion( &mut self, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, @@ -585,7 +585,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn verify_generic_bound( + pub(super) fn verify_generic_bound( &mut self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, @@ -595,7 +595,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.add_verify(Verify { kind, origin, region: sub, bound }); } - pub fn lub_regions( + pub(super) fn lub_regions( &mut self, tcx: TyCtxt<'tcx>, origin: SubregionOrigin<'tcx>, @@ -613,7 +613,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn glb_regions( + pub(super) fn glb_regions( &mut self, tcx: TyCtxt<'tcx>, origin: SubregionOrigin<'tcx>, @@ -634,7 +634,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } /// Resolves the passed RegionVid to the root RegionVid in the unification table - pub fn opportunistic_resolve_var(&mut self, rid: ty::RegionVid) -> ty::RegionVid { + pub(super) fn opportunistic_resolve_var(&mut self, rid: ty::RegionVid) -> ty::RegionVid { self.unification_table().find(rid).vid } @@ -699,7 +699,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => { ty::UniverseIndex::ROOT } - ty::ReEmpty(ui) => ui, 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 53e91e48c24d0..afb2d5b2ba5e5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -276,9 +276,6 @@ pub struct CommonTypes<'tcx> { } pub struct CommonLifetimes<'tcx> { - /// `ReEmpty` in the root universe. - pub re_root_empty: Region<'tcx>, - /// `ReStatic` pub re_static: Region<'tcx>, @@ -987,11 +984,7 @@ impl<'tcx> CommonLifetimes<'tcx> { )) }; - CommonLifetimes { - re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)), - re_static: mk(ty::ReStatic), - re_erased: mk(ty::ReErased), - } + CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5166372878fe9..301d1f5052eee 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1986,7 +1986,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { ty::ReVar(_) | ty::ReErased => false, - ty::ReStatic | ty::ReEmpty(_) => true, + ty::ReStatic => true, } } @@ -2070,14 +2070,6 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { p!("'static"); return Ok(self); } - ty::ReEmpty(ty::UniverseIndex::ROOT) => { - p!("'"); - return Ok(self); - } - ty::ReEmpty(ui) => { - p!(write("'", ui)); - return Ok(self); - } } p!("'_"); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c5c5d3473418c..702c2d27187ee 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1514,7 +1514,6 @@ impl<'tcx> Region<'tcx> { ty::ReStatic => true, ty::ReVar(..) => false, ty::RePlaceholder(placeholder) => placeholder.name.is_named(), - ty::ReEmpty(_) => false, ty::ReErased => false, } } @@ -1539,11 +1538,6 @@ impl<'tcx> Region<'tcx> { matches!(*self, ty::RePlaceholder(..)) } - #[inline] - pub fn is_empty(self) -> bool { - matches!(*self, ty::ReEmpty(..)) - } - #[inline] pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { match *self { @@ -1575,7 +1569,7 @@ impl<'tcx> Region<'tcx> { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; } - ty::ReEmpty(_) | ty::ReStatic => { + ty::ReStatic => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } ty::ReLateBound(..) => { 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 b1de979e8f8ec..bd8126f617773 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 @@ -305,8 +305,7 @@ fn encode_region<'tcx>( | RegionKind::ReFree(..) | RegionKind::ReStatic | RegionKind::ReVar(..) - | RegionKind::RePlaceholder(..) - | RegionKind::ReEmpty(..) => { + | RegionKind::RePlaceholder(..) => { bug!("encode_region: unexpected `{:?}`", region.kind()); } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 9a571837e9f5a..9d3a1a4a031ae 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -101,6 +101,7 @@ pub fn trait_obligations<'a, 'tcx>( wf.normalize(infcx) } +#[instrument(skip(infcx), ret)] pub fn predicate_obligations<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -440,6 +441,7 @@ impl<'tcx> WfPredicates<'tcx> { let param_env = self.param_env; let depth = self.recursion_depth; while let Some(arg) = walker.next() { + debug!(?arg, ?self.out); let ty = match arg.unpack() { GenericArgKind::Type(ty) => ty, @@ -689,6 +691,8 @@ impl<'tcx> WfPredicates<'tcx> { )); } } + + debug!(?self.out); } } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index a166371fed1e0..a6a098ce73f8d 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -485,10 +485,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t }) .intern(interner) } - ty::ReEmpty(ui) => { - chalk_ir::LifetimeData::Empty(chalk_ir::UniverseIndex { counter: ui.index() }) - .intern(interner) - } ty::ReErased => chalk_ir::LifetimeData::Erased.intern(interner), } } @@ -510,8 +506,8 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime return interner.tcx.lifetimes.re_static, - chalk_ir::LifetimeData::Empty(ui) => { - ty::ReEmpty(ty::UniverseIndex::from_usize(ui.counter)) + chalk_ir::LifetimeData::Empty(_) => { + bug!("Chalk should not have been passed an empty lifetime.") } chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased, chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 26e48d2d2147e..e164aaed6b4b8 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -3,14 +3,14 @@ use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use std::{fmt, hash}; +use crate::DebruijnIndex; use crate::FloatTy; +use crate::HashStableContext; use crate::IntTy; use crate::Interner; use crate::TyDecoder; use crate::TyEncoder; use crate::UintTy; -use crate::UniverseIndex; -use crate::{DebruijnIndex, HashStableContext}; use self::RegionKind::*; use self::TyKind::*; @@ -1023,14 +1023,6 @@ pub enum RegionKind { /// Should not exist outside of type inference. RePlaceholder(I::PlaceholderRegion), - /// Empty lifetime is for data that is never accessed. We tag the - /// empty lifetime with a universe -- the idea is that we don't - /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable. - /// Therefore, the `'empty` in a universe `U` is less than all - /// regions visible from `U`, but not less than regions not visible - /// from `U`. - ReEmpty(UniverseIndex), - /// Erased region, used by trait selection, in MIR and during codegen. ReErased, } @@ -1046,8 +1038,7 @@ const fn regionkind_discriminant(value: &RegionKind) -> usize { ReStatic => 3, ReVar(_) => 4, RePlaceholder(_) => 5, - ReEmpty(_) => 6, - ReErased => 7, + ReErased => 6, } } @@ -1072,7 +1063,6 @@ impl Clone for RegionKind { ReStatic => ReStatic, ReVar(a) => ReVar(a.clone()), RePlaceholder(a) => RePlaceholder(a.clone()), - ReEmpty(a) => ReEmpty(a.clone()), ReErased => ReErased, } } @@ -1099,7 +1089,6 @@ impl PartialEq for RegionKind { (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => { __self_0 == __arg_1_0 } - (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => __self_0 == __arg_1_0, (&ReErased, &ReErased) => true, _ => true, } @@ -1144,7 +1133,6 @@ impl Ord for RegionKind { (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => { Ord::cmp(__self_0, __arg_1_0) } - (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0), (&ReErased, &ReErased) => Ordering::Equal, _ => Ordering::Equal, } @@ -1182,10 +1170,6 @@ impl hash::Hash for RegionKind { hash::Hash::hash(®ionkind_discriminant(self), state); hash::Hash::hash(__self_0, state) } - (&ReEmpty(ref __self_0),) => { - hash::Hash::hash(®ionkind_discriminant(self), state); - hash::Hash::hash(__self_0, state) - } (&ReErased,) => { hash::Hash::hash(®ionkind_discriminant(self), state); } @@ -1211,8 +1195,6 @@ impl fmt::Debug for RegionKind { RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder), - ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui), - ReErased => write!(f, "ReErased"), } } @@ -1247,9 +1229,6 @@ where RePlaceholder(a) => e.emit_enum_variant(disc, |e| { a.encode(e); }), - ReEmpty(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), ReErased => e.emit_enum_variant(disc, |_| {}), } } @@ -1272,8 +1251,7 @@ where 3 => ReStatic, 4 => ReVar(Decodable::decode(d)), 5 => RePlaceholder(Decodable::decode(d)), - 6 => ReEmpty(Decodable::decode(d)), - 7 => ReErased, + 6 => ReErased, _ => panic!( "{}", format!( @@ -1305,9 +1283,6 @@ where ReErased | ReStatic => { // No variant fields to hash for these ... } - ReEmpty(universe) => { - universe.hash_stable(hcx, hasher); - } ReLateBound(db, br) => { db.hash_stable(hcx, hasher); br.hash_stable(hcx, hasher); diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 321064ec0fc91..ab143c059820d 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -144,6 +144,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs); let assumptions_in_impl_context = assumptions_in_impl_context.predicates; + debug!(?assumptions_in_impl_context, ?dtor_predicates.predicates); + let self_param_env = tcx.param_env(self_type_did); // An earlier version of this code attempted to do this checking diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5c6c8aca17346..b0ce0de1469b9 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1816,6 +1816,7 @@ fn report_bivariance( impl<'tcx> WfCheckingCtxt<'_, 'tcx> { /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that /// aren't true. + #[instrument(level = "debug", skip(self))] fn check_false_global_bounds(&mut self) { let tcx = self.ocx.infcx.tcx; let mut span = self.span; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f9c7c008fa484..3e7a6c3c54895 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1816,6 +1816,7 @@ pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir None } +#[instrument(level = "debug", skip(tcx))] fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { use rustc_hir::Node::*; use rustc_hir::*; @@ -2046,8 +2047,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( /// Returns a list of type predicates for the definition with ID `def_id`, including inferred /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus /// inferred constraints concerning which regions outlive other regions. +#[instrument(level = "debug", skip(tcx))] fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { - debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,); let inferred_outlives = tcx.inferred_outlives_of(def_id); diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs index b718ca9421336..3e8d023fb551c 100644 --- a/compiler/rustc_typeck/src/outlives/utils.rs +++ b/compiler/rustc_typeck/src/outlives/utils.rs @@ -161,12 +161,6 @@ fn is_free_region(region: Region<'_>) -> bool { // ignore it. We can't put it on the struct header anyway. ty::ReLateBound(..) => false, - // This can appear in `where Self: ` bounds (#64855): - // - // struct Bar(::Type) where Self: ; - // struct Baz<'a>(&'a Self) where Self: ; - ty::ReEmpty(_) => 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_typeck/src/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs index 4fe213ffeea35..840f0c978484d 100644 --- a/compiler/rustc_typeck/src/variance/constraints.rs +++ b/compiler/rustc_typeck/src/variance/constraints.rs @@ -411,11 +411,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // way early-bound regions do, so we skip them here. } - ty::ReFree(..) - | ty::ReVar(..) - | ty::RePlaceholder(..) - | ty::ReEmpty(_) - | ty::ReErased => { + 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. bug!( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bca3f4db4a854..9f0b7018af5f0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -250,7 +250,6 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option { debug!("cannot clean region {:?}", region); None @@ -347,10 +346,6 @@ fn clean_region_outlives_predicate<'tcx>( ) -> Option { let ty::OutlivesPredicate(a, b) = pred; - if a.is_empty() && b.is_empty() { - return None; - } - Some(WherePredicate::RegionPredicate { lifetime: clean_middle_region(a).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives( @@ -365,10 +360,6 @@ fn clean_type_outlives_predicate<'tcx>( ) -> Option { let ty::OutlivesPredicate(ty, lt) = pred; - if lt.is_empty() { - return None; - } - Some(WherePredicate::BoundPredicate { ty: clean_middle_ty(ty, cx, None), bounds: vec![GenericBound::Outlives( diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index cbfdf8c5d5639..0ab9d712d9f69 100644 --- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -13,11 +13,10 @@ | '_#2r | U0 | {bb0[0..=1], '_#2r} | '_#3r | U0 | {bb0[0..=1], '_#3r} | '_#4r | U0 | {bb0[0..=1], '_#4r} -| '_#5r | U0 | {} -| '_#6r | U0 | {bb0[0..=1], '_#1r} -| '_#7r | U0 | {bb0[0..=1], '_#2r} -| '_#8r | U0 | {bb0[0..=1], '_#1r} -| '_#9r | U0 | {bb0[0..=1], '_#3r} +| '_#5r | U0 | {bb0[0..=1], '_#1r} +| '_#6r | U0 | {bb0[0..=1], '_#2r} +| '_#7r | U0 | {bb0[0..=1], '_#1r} +| '_#8r | U0 | {bb0[0..=1], '_#3r} | | Inference Constraints | '_#0r live at {bb0[0..=1]} @@ -25,16 +24,16 @@ | '_#2r live at {bb0[0..=1]} | '_#3r live at {bb0[0..=1]} | '_#4r live at {bb0[0..=1]} -| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) -| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) -| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) -| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) -| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) -| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) -| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) -| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) | -fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool { +fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool { debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27 debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43 debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55 diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 55e7faf9ee47b..36705d18e0161 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -7,19 +7,18 @@ | Inferred Region Values | '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} | '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} -| '_#2r | U0 | {} -| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]} -| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]} -| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]} +| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]} +| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]} | | Inference Constraints | '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} | '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#3r live at {bb1[0]} -| '_#4r live at {bb1[1..=3]} -| '_#5r live at {bb1[4..=7], bb2[0..=2]} -| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) -| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| '_#2r live at {bb1[0]} +| '_#3r live at {bb1[1..=3]} +| '_#4r live at {bb1[4..=7], bb2[0..=2]} +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 @@ -33,10 +32,10 @@ fn main() -> () { let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 scope 1 { debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 scope 2 { debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 scope 3 { debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 } @@ -56,7 +55,7 @@ fn main() -> () { } bb1: { - _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 + _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 2647c94335f87..4f6256a67f46f 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -7,19 +7,18 @@ | Inferred Region Values | '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} | '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} -| '_#2r | U0 | {} -| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]} -| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]} -| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]} +| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]} +| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]} | | Inference Constraints | '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} | '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#3r live at {bb1[0]} -| '_#4r live at {bb1[1..=3]} -| '_#5r live at {bb1[4..=7], bb2[0..=2]} -| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) -| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| '_#2r live at {bb1[0]} +| '_#3r live at {bb1[1..=3]} +| '_#4r live at {bb1[4..=7], bb2[0..=2]} +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 @@ -33,10 +32,10 @@ fn main() -> () { let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 scope 1 { debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 scope 2 { debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 scope 3 { debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 } @@ -56,7 +55,7 @@ fn main() -> () { } bb1: { - _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 + _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir index 812eb3b82a6d0..8e10e70f192d2 100644 --- a/src/test/mir-opt/storage_ranges.main.nll.0.mir +++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir @@ -7,16 +7,15 @@ | Inferred Region Values | '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r} | '_#1r | U0 | {bb0[0..=22], '_#1r} -| '_#2r | U0 | {} -| '_#3r | U0 | {bb0[10..=11]} -| '_#4r | U0 | {bb0[11]} +| '_#2r | U0 | {bb0[10..=11]} +| '_#3r | U0 | {bb0[11]} | | Inference Constraints | '_#0r live at {bb0[0..=22]} | '_#1r live at {bb0[0..=22]} -| '_#3r live at {bb0[10]} -| '_#4r live at {bb0[11]} -| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) +| '_#2r live at {bb0[10]} +| '_#3r live at {bb0[11]} +| '_#2r: '_#3r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11 diff --git a/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr index fdaf353fe3d22..3ab7c66d11f2f 100644 --- a/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr +++ b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr @@ -2,7 +2,7 @@ error[E0382]: use of moved value: `c` --> $DIR/closure-print-generic-verbose-1.rs:17:5 | LL | let c = to_fn_once(move|| { - | - move occurs because `c` has type `[f::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'_#10r str>, T)]`, which does not implement the `Copy` trait + | - move occurs because `c` has type `[f::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'_#9r str>, T)]`, which does not implement the `Copy` trait ... LL | c(); | --- `c` moved due to this call diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index c3c7eb1bd9e5e..296131111e834 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -46,7 +46,7 @@ LL | | }); | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant + = note: requirement occurs because of the type `Cell<&'_#9r u32>`, which makes the generic argument `&'_#9r u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index 846e5aedb3e73..96a1bd1f07b65 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -46,7 +46,7 @@ LL | | }); | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `Cell<&'_#11r u32>`, which makes the generic argument `&'_#11r u32` invariant + = note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 6d17c7a7346f3..060037ed49691 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -173,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ( preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())), !preds.is_empty() && { - let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty); + let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_erased, ty); preds.iter().all(|t| { let ty_params = t.trait_ref.substs.iter().skip(1).collect::>(); implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)