Auto merge of #98559 - jackh726:remove-reempty, r=oli-obk
Remove ReEmpty r? rust-lang/types
This commit is contained in:
commit
2287107588
32 changed files with 336 additions and 298 deletions
|
@ -357,11 +357,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
ty::BoundRegionKind::BrAnon(_) => None,
|
ty::BoundRegionKind::BrAnon(_) => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::ReLateBound(..)
|
ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None,
|
||||||
| ty::ReVar(..)
|
|
||||||
| ty::RePlaceholder(..)
|
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReErased => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
|
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
|
||||||
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
|
.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,
|
_ => region,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ struct ReverseMapper<'tcx> {
|
||||||
|
|
||||||
key: ty::OpaqueTypeKey<'tcx>,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
||||||
map_missing_regions_to_empty: bool,
|
do_not_error: bool,
|
||||||
|
|
||||||
/// initially `Some`, set to `None` once error has been reported
|
/// initially `Some`, set to `None` once error has been reported
|
||||||
hidden_ty: Option<Ty<'tcx>>,
|
hidden_ty: Option<Ty<'tcx>>,
|
||||||
|
@ -450,29 +450,19 @@ impl<'tcx> ReverseMapper<'tcx> {
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self { tcx, key, map, do_not_error: false, hidden_ty: Some(hidden_ty), span }
|
||||||
tcx,
|
|
||||||
key,
|
|
||||||
map,
|
|
||||||
map_missing_regions_to_empty: false,
|
|
||||||
hidden_ty: Some(hidden_ty),
|
|
||||||
span,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_kind_mapping_missing_regions_to_empty(
|
fn fold_kind_no_missing_regions_error(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
||||||
&mut self,
|
assert!(!self.do_not_error);
|
||||||
kind: GenericArg<'tcx>,
|
self.do_not_error = true;
|
||||||
) -> GenericArg<'tcx> {
|
|
||||||
assert!(!self.map_missing_regions_to_empty);
|
|
||||||
self.map_missing_regions_to_empty = true;
|
|
||||||
let kind = kind.fold_with(self);
|
let kind = kind.fold_with(self);
|
||||||
self.map_missing_regions_to_empty = false;
|
self.do_not_error = false;
|
||||||
kind
|
kind
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
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)
|
kind.fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,9 +486,9 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
ty::ReErased => return r,
|
ty::ReErased => return r,
|
||||||
|
|
||||||
// The regions that we expect from borrow checking.
|
// 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
|
// All of the regions in the type should either have been
|
||||||
// erased by writeback, or mapped back to named regions by
|
// erased by writeback, or mapped back to named regions by
|
||||||
// borrow checking.
|
// borrow checking.
|
||||||
|
@ -510,7 +500,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
||||||
Some(GenericArgKind::Lifetime(r1)) => r1,
|
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||||
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
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() => {
|
None if generics.parent.is_some() => {
|
||||||
if let Some(hidden_ty) = self.hidden_ty.take() {
|
if let Some(hidden_ty) = self.hidden_ty.take() {
|
||||||
unexpected_hidden_region_diagnostic(
|
unexpected_hidden_region_diagnostic(
|
||||||
|
@ -522,7 +512,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
self.tcx.lifetimes.re_root_empty
|
self.tcx.lifetimes.re_static
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.tcx
|
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)| {
|
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
|
||||||
if index < generics.parent_count {
|
if index < generics.parent_count {
|
||||||
// Accommodate missing regions in the parent kinds...
|
// 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 {
|
} else {
|
||||||
// ...but not elsewhere.
|
// ...but not elsewhere.
|
||||||
self.fold_kind_normally(kind)
|
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)| {
|
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
|
||||||
if index < generics.parent_count {
|
if index < generics.parent_count {
|
||||||
// Accommodate missing regions in the parent kinds...
|
// 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 {
|
} else {
|
||||||
// ...but not elsewhere.
|
// ...but not elsewhere.
|
||||||
self.fold_kind_normally(kind)
|
self.fold_kind_normally(kind)
|
||||||
|
|
|
@ -347,13 +347,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||||
|
|
||||||
match outlives_bound {
|
match outlives_bound {
|
||||||
OutlivesBound::RegionSubRegion(r1, r2) => {
|
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`.
|
// The bound says that `r1 <= r2`; we store `r2: r1`.
|
||||||
let r1 = self.universal_regions.to_region_vid(r1);
|
let r1 = self.universal_regions.to_region_vid(r1);
|
||||||
let r2 = self.universal_regions.to_region_vid(r2);
|
let r2 = self.universal_regions.to_region_vid(r2);
|
||||||
|
|
|
@ -54,13 +54,6 @@ pub struct UniversalRegions<'tcx> {
|
||||||
/// The total number of universal region variables instantiated.
|
/// The total number of universal region variables instantiated.
|
||||||
num_universals: usize,
|
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
|
/// The "defining" type for this function, with all universal
|
||||||
/// regions instantiated. For a closure or generator, this is the
|
/// regions instantiated. For a closure or generator, this is the
|
||||||
/// closure type, but for a top-level function it's the `FnDef`.
|
/// 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`.
|
/// See `UniversalRegionIndices::to_region_vid`.
|
||||||
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||||
if let ty::ReEmpty(ty::UniverseIndex::ROOT) = *r {
|
self.indices.to_region_vid(r)
|
||||||
self.root_empty
|
|
||||||
} else {
|
|
||||||
self.indices.to_region_vid(r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// As part of the NLL unit tests, you can annotate a function with
|
/// As part of the NLL unit tests, you can annotate a function with
|
||||||
|
@ -501,16 +490,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let root_empty = self
|
|
||||||
.infcx
|
|
||||||
.next_nll_region_var(NllRegionVariableOrigin::Existential { from_forall: true })
|
|
||||||
.to_region_vid();
|
|
||||||
|
|
||||||
UniversalRegions {
|
UniversalRegions {
|
||||||
indices,
|
indices,
|
||||||
fr_static,
|
fr_static,
|
||||||
fr_fn_body,
|
fr_fn_body,
|
||||||
root_empty,
|
|
||||||
first_extern_index,
|
first_extern_index,
|
||||||
first_local_index,
|
first_local_index,
|
||||||
num_universals,
|
num_universals,
|
||||||
|
|
|
@ -27,13 +27,6 @@ impl<'a> DescriptionCtx<'a> {
|
||||||
me.kind = "restatic";
|
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,
|
ty::RePlaceholder(_) => return None,
|
||||||
|
|
||||||
// FIXME(#13998) RePlaceholder should probably print like
|
// FIXME(#13998) RePlaceholder should probably print like
|
||||||
|
|
|
@ -180,11 +180,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
|
||||||
r: ty::Region<'tcx>,
|
r: ty::Region<'tcx>,
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReFree(_)
|
ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r,
|
||||||
| ty::ReErased
|
|
||||||
| ty::ReStatic
|
|
||||||
| ty::ReEmpty(ty::UniverseIndex::ROOT)
|
|
||||||
| ty::ReEarlyBound(..) => r,
|
|
||||||
|
|
||||||
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
|
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
|
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
|
// Other than `'static` or `'empty`, the query
|
||||||
// response should be executing in a fully
|
// response should be executing in a fully
|
||||||
|
@ -381,7 +373,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
ty::ReStatic
|
ty::ReStatic
|
||||||
| ty::ReEarlyBound(..)
|
| ty::ReEarlyBound(..)
|
||||||
| ty::ReFree(_)
|
| ty::ReFree(_)
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
|
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
|
||||||
}
|
}
|
||||||
|
|
|
@ -688,7 +688,6 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||||
|
|
||||||
ty::RePlaceholder(..)
|
ty::RePlaceholder(..)
|
||||||
| ty::ReVar(..)
|
| ty::ReVar(..)
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReStatic
|
| ty::ReStatic
|
||||||
| ty::ReEarlyBound(..)
|
| ty::ReEarlyBound(..)
|
||||||
| ty::ReFree(..) => {
|
| ty::ReFree(..) => {
|
||||||
|
@ -900,7 +899,6 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
||||||
|
|
||||||
ty::RePlaceholder(..)
|
ty::RePlaceholder(..)
|
||||||
| ty::ReVar(..)
|
| ty::ReVar(..)
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReStatic
|
| ty::ReStatic
|
||||||
| ty::ReEarlyBound(..)
|
| ty::ReEarlyBound(..)
|
||||||
| ty::ReFree(..) => {
|
| ty::ReFree(..) => {
|
||||||
|
|
|
@ -97,11 +97,6 @@ pub(super) fn note_and_explain_region<'tcx>(
|
||||||
msg_span_from_free_region(tcx, region, alt_span)
|
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,
|
ty::RePlaceholder(_) => return,
|
||||||
|
|
||||||
// FIXME(#13998) RePlaceholder should probably print like
|
// FIXME(#13998) RePlaceholder should probably print like
|
||||||
|
@ -140,8 +135,6 @@ fn msg_span_from_free_region<'tcx>(
|
||||||
(msg, Some(span))
|
(msg, Some(span))
|
||||||
}
|
}
|
||||||
ty::ReStatic => ("the static lifetime".to_owned(), alt_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),
|
_ => bug!("{:?}", region),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,17 +244,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
|
|
||||||
// Explain the region we are capturing.
|
// Explain the region we are capturing.
|
||||||
match *hidden_region {
|
match *hidden_region {
|
||||||
ty::ReEmpty(ty::UniverseIndex::ROOT) => {
|
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
|
||||||
// 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(_) => {
|
|
||||||
// Assuming regionck succeeded (*), we ought to always be
|
// Assuming regionck succeeded (*), we ought to always be
|
||||||
// capturing *some* region from the fn header, and hence it
|
// capturing *some* region from the fn header, and hence it
|
||||||
// ought to be free. So under normal circumstances, we will go
|
// ought to be free. So under normal circumstances, we will go
|
||||||
|
@ -387,7 +370,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
RegionResolutionError::UpperBoundUniverseConflict(
|
RegionResolutionError::UpperBoundUniverseConflict(
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
var_universe,
|
_,
|
||||||
sup_origin,
|
sup_origin,
|
||||||
sup_r,
|
sup_r,
|
||||||
) => {
|
) => {
|
||||||
|
@ -398,7 +381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
// placeholder. In practice, we expect more
|
// placeholder. In practice, we expect more
|
||||||
// tailored errors that don't really use this
|
// tailored errors that don't really use this
|
||||||
// value.
|
// 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();
|
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
| ty::ReFree(_)
|
| ty::ReFree(_)
|
||||||
| ty::ReVar(_)
|
| ty::ReVar(_)
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReErased => {
|
| ty::ReErased => {
|
||||||
// replace all free regions with 'erased
|
// replace all free regions with 'erased
|
||||||
self.tcx().lifetimes.re_erased
|
self.tcx().lifetimes.re_erased
|
||||||
|
|
|
@ -15,8 +15,9 @@ use rustc_data_structures::graph::implementation::{
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
|
use rustc_middle::ty::PlaceholderRegion;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
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::{ReLateBound, RePlaceholder, ReVar};
|
||||||
use rustc_middle::ty::{Region, RegionVid};
|
use rustc_middle::ty::{Region, RegionVid};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -51,6 +52,13 @@ pub struct LexicalRegionResolutions<'tcx> {
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub(crate) enum VarValue<'tcx> {
|
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>),
|
Value(Region<'tcx>),
|
||||||
ErrorValue,
|
ErrorValue,
|
||||||
}
|
}
|
||||||
|
@ -117,7 +125,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
errors: &mut Vec<RegionResolutionError<'tcx>>,
|
errors: &mut Vec<RegionResolutionError<'tcx>>,
|
||||||
) -> LexicalRegionResolutions<'tcx> {
|
) -> LexicalRegionResolutions<'tcx> {
|
||||||
let mut var_data = self.construct_var_data(self.tcx());
|
let mut var_data = self.construct_var_data();
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
self.dump_constraints();
|
self.dump_constraints();
|
||||||
|
@ -137,13 +145,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
|
|
||||||
/// Initially, the value for all variables is set to `'empty`, the
|
/// Initially, the value for all variables is set to `'empty`, the
|
||||||
/// empty region. The `expansion` phase will grow this larger.
|
/// 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 {
|
LexicalRegionResolutions {
|
||||||
values: IndexVec::from_fn_n(
|
values: IndexVec::from_fn_n(
|
||||||
|vid| {
|
|vid| {
|
||||||
let vid_universe = self.var_infos[vid].universe;
|
let vid_universe = self.var_infos[vid].universe;
|
||||||
let re_empty = tcx.mk_region(ty::ReEmpty(vid_universe));
|
VarValue::Empty(vid_universe)
|
||||||
VarValue::Value(re_empty)
|
|
||||||
},
|
},
|
||||||
self.num_vars(),
|
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<Region<'tcx>, 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>) {
|
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());
|
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
|
||||||
|
// Tracks the changed region vids.
|
||||||
let mut changes = Vec::new();
|
let mut changes = Vec::new();
|
||||||
for constraint in self.data.constraints.keys() {
|
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) => {
|
Constraint::RegSubVar(a_region, b_vid) => {
|
||||||
let b_data = var_values.value_mut(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) {
|
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
|
||||||
VarValue::ErrorValue => continue,
|
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) => {
|
VarValue::Value(a_region) => {
|
||||||
let b_data = var_values.value_mut(b_vid);
|
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(..) => {
|
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
|
||||||
|
@ -210,18 +328,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
// is done, in `collect_errors`.
|
// is done, in `collect_errors`.
|
||||||
continue;
|
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(
|
fn expand_node(
|
||||||
&self,
|
&self,
|
||||||
a_region: Region<'tcx>,
|
a_region: Region<'tcx>,
|
||||||
|
@ -263,14 +373,28 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match *b_data {
|
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) => {
|
VarValue::Value(cur_region) => {
|
||||||
// This is a specialized version of the `lub_concrete_regions`
|
// This is a specialized version of the `lub_concrete_regions`
|
||||||
// check below for a common case, here purely as an
|
// check below for a common case, here purely as an
|
||||||
// optimization.
|
// optimization.
|
||||||
let b_universe = self.var_infos[b_vid].universe;
|
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);
|
let mut lub = self.lub_concrete_regions(a_region, cur_region);
|
||||||
if lub == 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.
|
/// True if `a <= b`, but not defined over inference variables.
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
|
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
|
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(_)) => {
|
(ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => {
|
||||||
self.region_rels.lub_free_regions(a, b)
|
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() {
|
for (node_vid, value) in var_data.values.iter_enumerated() {
|
||||||
match *value {
|
match *value {
|
||||||
VarValue::Value(_) => { /* Inference successful */ }
|
VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ }
|
||||||
VarValue::ErrorValue => {
|
VarValue::ErrorValue => {
|
||||||
// Inference impossible: this value contains
|
// Inference impossible: this value contains
|
||||||
// inconsistent constraints.
|
// inconsistent constraints.
|
||||||
|
@ -829,12 +994,25 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyBound::OutlivedBy(r) => {
|
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 => {
|
VerifyBound::IsEmpty => match *min {
|
||||||
matches!(*min, ty::ReEmpty(_))
|
ty::ReVar(rid) => match var_values.values[rid] {
|
||||||
}
|
VarValue::ErrorValue => false,
|
||||||
|
VarValue::Empty(_) => true,
|
||||||
|
VarValue::Value(_) => false,
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
|
||||||
VerifyBound::AnyBound(bs) => {
|
VerifyBound::AnyBound(bs) => {
|
||||||
bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min))
|
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> {
|
) -> ty::Region<'tcx> {
|
||||||
let result = match *r {
|
let result = match *r {
|
||||||
ty::ReVar(rid) => match self.values[rid] {
|
ty::ReVar(rid) => match self.values[rid] {
|
||||||
|
VarValue::Empty(_) => r,
|
||||||
VarValue::Value(r) => r,
|
VarValue::Value(r) => r,
|
||||||
VarValue::ErrorValue => tcx.lifetimes.re_static,
|
VarValue::ErrorValue => tcx.lifetimes.re_static,
|
||||||
},
|
},
|
||||||
|
|
|
@ -426,21 +426,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> &RegionConstraintData<'tcx> {
|
pub(super) fn data(&self) -> &RegionConstraintData<'tcx> {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_snapshot(&mut self) -> RegionSnapshot {
|
pub(super) fn start_snapshot(&mut self) -> RegionSnapshot {
|
||||||
debug!("RegionConstraintCollector: start_snapshot");
|
debug!("RegionConstraintCollector: start_snapshot");
|
||||||
RegionSnapshot { any_unifications: self.any_unifications }
|
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);
|
debug!("RegionConstraintCollector: rollback_to({:?})", snapshot);
|
||||||
self.any_unifications = snapshot.any_unifications;
|
self.any_unifications = snapshot.any_unifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_region_var(
|
pub(super) fn new_region_var(
|
||||||
&mut self,
|
&mut self,
|
||||||
universe: ty::UniverseIndex,
|
universe: ty::UniverseIndex,
|
||||||
origin: RegionVariableOrigin,
|
origin: RegionVariableOrigin,
|
||||||
|
@ -455,12 +455,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the universe for the given variable.
|
/// 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
|
self.var_infos[vid].universe
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the origin for the given variable.
|
/// 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
|
self.var_infos[vid].origin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
self.undo_log.push(AddVerify(index));
|
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
|
// cannot add givens once regions are resolved
|
||||||
if self.data.givens.insert((sub, sup)) {
|
if self.data.givens.insert((sub, sup)) {
|
||||||
debug!("add_given({:?} <= {:?})", 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,
|
&mut self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: Region<'tcx>,
|
sub: Region<'tcx>,
|
||||||
|
@ -530,7 +530,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn member_constraint(
|
pub(super) fn member_constraint(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: ty::OpaqueTypeKey<'tcx>,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
definition_span: Span,
|
definition_span: Span,
|
||||||
|
@ -554,7 +554,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, origin), level = "debug")]
|
#[instrument(skip(self, origin), level = "debug")]
|
||||||
pub fn make_subregion(
|
pub(super) fn make_subregion(
|
||||||
&mut self,
|
&mut self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: Region<'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,
|
&mut self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
kind: GenericKind<'tcx>,
|
kind: GenericKind<'tcx>,
|
||||||
|
@ -595,7 +595,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
self.add_verify(Verify { kind, origin, region: sub, bound });
|
self.add_verify(Verify { kind, origin, region: sub, bound });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lub_regions(
|
pub(super) fn lub_regions(
|
||||||
&mut self,
|
&mut self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
|
@ -613,7 +613,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn glb_regions(
|
pub(super) fn glb_regions(
|
||||||
&mut self,
|
&mut self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
|
@ -634,7 +634,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the passed RegionVid to the root RegionVid in the unification table
|
/// 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
|
self.unification_table().find(rid).vid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +699,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
|
ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
|
||||||
ty::UniverseIndex::ROOT
|
ty::UniverseIndex::ROOT
|
||||||
}
|
}
|
||||||
ty::ReEmpty(ui) => ui,
|
|
||||||
ty::RePlaceholder(placeholder) => placeholder.universe,
|
ty::RePlaceholder(placeholder) => placeholder.universe,
|
||||||
ty::ReVar(vid) => self.var_universe(vid),
|
ty::ReVar(vid) => self.var_universe(vid),
|
||||||
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
|
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
|
||||||
|
|
|
@ -276,9 +276,6 @@ pub struct CommonTypes<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommonLifetimes<'tcx> {
|
pub struct CommonLifetimes<'tcx> {
|
||||||
/// `ReEmpty` in the root universe.
|
|
||||||
pub re_root_empty: Region<'tcx>,
|
|
||||||
|
|
||||||
/// `ReStatic`
|
/// `ReStatic`
|
||||||
pub re_static: Region<'tcx>,
|
pub re_static: Region<'tcx>,
|
||||||
|
|
||||||
|
@ -987,11 +984,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
CommonLifetimes {
|
CommonLifetimes { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased) }
|
||||||
re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)),
|
|
||||||
re_static: mk(ty::ReStatic),
|
|
||||||
re_erased: mk(ty::ReErased),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1986,7 +1986,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
|
||||||
|
|
||||||
ty::ReVar(_) | ty::ReErased => false,
|
ty::ReVar(_) | ty::ReErased => false,
|
||||||
|
|
||||||
ty::ReStatic | ty::ReEmpty(_) => true,
|
ty::ReStatic => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2070,14 +2070,6 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||||
p!("'static");
|
p!("'static");
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
ty::ReEmpty(ty::UniverseIndex::ROOT) => {
|
|
||||||
p!("'<empty>");
|
|
||||||
return Ok(self);
|
|
||||||
}
|
|
||||||
ty::ReEmpty(ui) => {
|
|
||||||
p!(write("'<empty:{:?}>", ui));
|
|
||||||
return Ok(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p!("'_");
|
p!("'_");
|
||||||
|
|
|
@ -1514,7 +1514,6 @@ impl<'tcx> Region<'tcx> {
|
||||||
ty::ReStatic => true,
|
ty::ReStatic => true,
|
||||||
ty::ReVar(..) => false,
|
ty::ReVar(..) => false,
|
||||||
ty::RePlaceholder(placeholder) => placeholder.name.is_named(),
|
ty::RePlaceholder(placeholder) => placeholder.name.is_named(),
|
||||||
ty::ReEmpty(_) => false,
|
|
||||||
ty::ReErased => false,
|
ty::ReErased => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1539,11 +1538,6 @@ impl<'tcx> Region<'tcx> {
|
||||||
matches!(*self, ty::RePlaceholder(..))
|
matches!(*self, ty::RePlaceholder(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_empty(self) -> bool {
|
|
||||||
matches!(*self, ty::ReEmpty(..))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -1575,7 +1569,7 @@ impl<'tcx> Region<'tcx> {
|
||||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||||
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
|
||||||
}
|
}
|
||||||
ty::ReEmpty(_) | ty::ReStatic => {
|
ty::ReStatic => {
|
||||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||||
}
|
}
|
||||||
ty::ReLateBound(..) => {
|
ty::ReLateBound(..) => {
|
||||||
|
|
|
@ -305,8 +305,7 @@ fn encode_region<'tcx>(
|
||||||
| RegionKind::ReFree(..)
|
| RegionKind::ReFree(..)
|
||||||
| RegionKind::ReStatic
|
| RegionKind::ReStatic
|
||||||
| RegionKind::ReVar(..)
|
| RegionKind::ReVar(..)
|
||||||
| RegionKind::RePlaceholder(..)
|
| RegionKind::RePlaceholder(..) => {
|
||||||
| RegionKind::ReEmpty(..) => {
|
|
||||||
bug!("encode_region: unexpected `{:?}`", region.kind());
|
bug!("encode_region: unexpected `{:?}`", region.kind());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ pub fn trait_obligations<'a, 'tcx>(
|
||||||
wf.normalize(infcx)
|
wf.normalize(infcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(infcx), ret)]
|
||||||
pub fn predicate_obligations<'a, 'tcx>(
|
pub fn predicate_obligations<'a, 'tcx>(
|
||||||
infcx: &InferCtxt<'a, 'tcx>,
|
infcx: &InferCtxt<'a, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
@ -440,6 +441,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
let depth = self.recursion_depth;
|
let depth = self.recursion_depth;
|
||||||
while let Some(arg) = walker.next() {
|
while let Some(arg) = walker.next() {
|
||||||
|
debug!(?arg, ?self.out);
|
||||||
let ty = match arg.unpack() {
|
let ty = match arg.unpack() {
|
||||||
GenericArgKind::Type(ty) => ty,
|
GenericArgKind::Type(ty) => ty,
|
||||||
|
|
||||||
|
@ -689,6 +691,8 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(?self.out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -485,10 +485,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
|
||||||
})
|
})
|
||||||
.intern(interner)
|
.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),
|
ty::ReErased => chalk_ir::LifetimeData::Erased.intern(interner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,8 +506,8 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
|
||||||
name: ty::BoundRegionKind::BrAnon(p.idx as u32),
|
name: ty::BoundRegionKind::BrAnon(p.idx as u32),
|
||||||
}),
|
}),
|
||||||
chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
|
chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
|
||||||
chalk_ir::LifetimeData::Empty(ui) => {
|
chalk_ir::LifetimeData::Empty(_) => {
|
||||||
ty::ReEmpty(ty::UniverseIndex::from_usize(ui.counter))
|
bug!("Chalk should not have been passed an empty lifetime.")
|
||||||
}
|
}
|
||||||
chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
|
chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
|
||||||
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
|
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
|
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
|
||||||
use std::{fmt, hash};
|
use std::{fmt, hash};
|
||||||
|
|
||||||
|
use crate::DebruijnIndex;
|
||||||
use crate::FloatTy;
|
use crate::FloatTy;
|
||||||
|
use crate::HashStableContext;
|
||||||
use crate::IntTy;
|
use crate::IntTy;
|
||||||
use crate::Interner;
|
use crate::Interner;
|
||||||
use crate::TyDecoder;
|
use crate::TyDecoder;
|
||||||
use crate::TyEncoder;
|
use crate::TyEncoder;
|
||||||
use crate::UintTy;
|
use crate::UintTy;
|
||||||
use crate::UniverseIndex;
|
|
||||||
use crate::{DebruijnIndex, HashStableContext};
|
|
||||||
|
|
||||||
use self::RegionKind::*;
|
use self::RegionKind::*;
|
||||||
use self::TyKind::*;
|
use self::TyKind::*;
|
||||||
|
@ -1023,14 +1023,6 @@ pub enum RegionKind<I: Interner> {
|
||||||
/// Should not exist outside of type inference.
|
/// Should not exist outside of type inference.
|
||||||
RePlaceholder(I::PlaceholderRegion),
|
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.
|
/// Erased region, used by trait selection, in MIR and during codegen.
|
||||||
ReErased,
|
ReErased,
|
||||||
}
|
}
|
||||||
|
@ -1046,8 +1038,7 @@ const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
|
||||||
ReStatic => 3,
|
ReStatic => 3,
|
||||||
ReVar(_) => 4,
|
ReVar(_) => 4,
|
||||||
RePlaceholder(_) => 5,
|
RePlaceholder(_) => 5,
|
||||||
ReEmpty(_) => 6,
|
ReErased => 6,
|
||||||
ReErased => 7,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,7 +1063,6 @@ impl<I: Interner> Clone for RegionKind<I> {
|
||||||
ReStatic => ReStatic,
|
ReStatic => ReStatic,
|
||||||
ReVar(a) => ReVar(a.clone()),
|
ReVar(a) => ReVar(a.clone()),
|
||||||
RePlaceholder(a) => RePlaceholder(a.clone()),
|
RePlaceholder(a) => RePlaceholder(a.clone()),
|
||||||
ReEmpty(a) => ReEmpty(a.clone()),
|
|
||||||
ReErased => ReErased,
|
ReErased => ReErased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1089,6 @@ impl<I: Interner> PartialEq for RegionKind<I> {
|
||||||
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
|
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
|
||||||
__self_0 == __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,
|
(&ReErased, &ReErased) => true,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1133,6 @@ impl<I: Interner> Ord for RegionKind<I> {
|
||||||
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
|
(&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
|
||||||
Ord::cmp(__self_0, __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,
|
(&ReErased, &ReErased) => Ordering::Equal,
|
||||||
_ => Ordering::Equal,
|
_ => Ordering::Equal,
|
||||||
}
|
}
|
||||||
|
@ -1182,10 +1170,6 @@ impl<I: Interner> hash::Hash for RegionKind<I> {
|
||||||
hash::Hash::hash(®ionkind_discriminant(self), state);
|
hash::Hash::hash(®ionkind_discriminant(self), state);
|
||||||
hash::Hash::hash(__self_0, 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,) => {
|
(&ReErased,) => {
|
||||||
hash::Hash::hash(®ionkind_discriminant(self), state);
|
hash::Hash::hash(®ionkind_discriminant(self), state);
|
||||||
}
|
}
|
||||||
|
@ -1211,8 +1195,6 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
|
||||||
|
|
||||||
RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
|
RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
|
||||||
|
|
||||||
ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
|
|
||||||
|
|
||||||
ReErased => write!(f, "ReErased"),
|
ReErased => write!(f, "ReErased"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1247,9 +1229,6 @@ where
|
||||||
RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
|
RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
|
||||||
a.encode(e);
|
a.encode(e);
|
||||||
}),
|
}),
|
||||||
ReEmpty(a) => e.emit_enum_variant(disc, |e| {
|
|
||||||
a.encode(e);
|
|
||||||
}),
|
|
||||||
ReErased => e.emit_enum_variant(disc, |_| {}),
|
ReErased => e.emit_enum_variant(disc, |_| {}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1272,8 +1251,7 @@ where
|
||||||
3 => ReStatic,
|
3 => ReStatic,
|
||||||
4 => ReVar(Decodable::decode(d)),
|
4 => ReVar(Decodable::decode(d)),
|
||||||
5 => RePlaceholder(Decodable::decode(d)),
|
5 => RePlaceholder(Decodable::decode(d)),
|
||||||
6 => ReEmpty(Decodable::decode(d)),
|
6 => ReErased,
|
||||||
7 => ReErased,
|
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"{}",
|
"{}",
|
||||||
format!(
|
format!(
|
||||||
|
@ -1305,9 +1283,6 @@ where
|
||||||
ReErased | ReStatic => {
|
ReErased | ReStatic => {
|
||||||
// No variant fields to hash for these ...
|
// No variant fields to hash for these ...
|
||||||
}
|
}
|
||||||
ReEmpty(universe) => {
|
|
||||||
universe.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ReLateBound(db, br) => {
|
ReLateBound(db, br) => {
|
||||||
db.hash_stable(hcx, hasher);
|
db.hash_stable(hcx, hasher);
|
||||||
br.hash_stable(hcx, hasher);
|
br.hash_stable(hcx, hasher);
|
||||||
|
|
|
@ -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 = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
|
||||||
let assumptions_in_impl_context = assumptions_in_impl_context.predicates;
|
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);
|
let self_param_env = tcx.param_env(self_type_did);
|
||||||
|
|
||||||
// An earlier version of this code attempted to do this checking
|
// An earlier version of this code attempted to do this checking
|
||||||
|
|
|
@ -1816,6 +1816,7 @@ fn report_bivariance(
|
||||||
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
|
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
|
||||||
/// aren't true.
|
/// aren't true.
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn check_false_global_bounds(&mut self) {
|
fn check_false_global_bounds(&mut self) {
|
||||||
let tcx = self.ocx.infcx.tcx;
|
let tcx = self.ocx.infcx.tcx;
|
||||||
let mut span = self.span;
|
let mut span = self.span;
|
||||||
|
|
|
@ -1816,6 +1816,7 @@ pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||||
use rustc_hir::Node::*;
|
use rustc_hir::Node::*;
|
||||||
use rustc_hir::*;
|
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
|
/// 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
|
/// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
|
||||||
/// inferred constraints concerning which regions outlive other regions.
|
/// inferred constraints concerning which regions outlive other regions.
|
||||||
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
|
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);
|
let mut result = tcx.explicit_predicates_of(def_id);
|
||||||
debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,);
|
debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,);
|
||||||
let inferred_outlives = tcx.inferred_outlives_of(def_id);
|
let inferred_outlives = tcx.inferred_outlives_of(def_id);
|
||||||
|
|
|
@ -161,12 +161,6 @@ fn is_free_region(region: Region<'_>) -> bool {
|
||||||
// ignore it. We can't put it on the struct header anyway.
|
// ignore it. We can't put it on the struct header anyway.
|
||||||
ty::ReLateBound(..) => false,
|
ty::ReLateBound(..) => false,
|
||||||
|
|
||||||
// This can appear in `where Self: ` bounds (#64855):
|
|
||||||
//
|
|
||||||
// struct Bar<T>(<Self as Foo>::Type) where Self: ;
|
|
||||||
// struct Baz<'a>(&'a Self) where Self: ;
|
|
||||||
ty::ReEmpty(_) => false,
|
|
||||||
|
|
||||||
// These regions don't appear in types from type declarations:
|
// These regions don't appear in types from type declarations:
|
||||||
ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
|
ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
|
||||||
bug!("unexpected region in outlives inference: {:?}", region);
|
bug!("unexpected region in outlives inference: {:?}", region);
|
||||||
|
|
|
@ -411,11 +411,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
// way early-bound regions do, so we skip them here.
|
// way early-bound regions do, so we skip them here.
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReFree(..)
|
ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
|
||||||
| ty::ReVar(..)
|
|
||||||
| ty::RePlaceholder(..)
|
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReErased => {
|
|
||||||
// We don't expect to see anything but 'static or bound
|
// We don't expect to see anything but 'static or bound
|
||||||
// regions when visiting member types or method types.
|
// regions when visiting member types or method types.
|
||||||
bug!(
|
bug!(
|
||||||
|
|
|
@ -250,7 +250,6 @@ pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Life
|
||||||
| ty::ReFree(..)
|
| ty::ReFree(..)
|
||||||
| ty::ReVar(..)
|
| ty::ReVar(..)
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
| ty::ReEmpty(_)
|
|
||||||
| ty::ReErased => {
|
| ty::ReErased => {
|
||||||
debug!("cannot clean region {:?}", region);
|
debug!("cannot clean region {:?}", region);
|
||||||
None
|
None
|
||||||
|
@ -347,10 +346,6 @@ fn clean_region_outlives_predicate<'tcx>(
|
||||||
) -> Option<WherePredicate> {
|
) -> Option<WherePredicate> {
|
||||||
let ty::OutlivesPredicate(a, b) = pred;
|
let ty::OutlivesPredicate(a, b) = pred;
|
||||||
|
|
||||||
if a.is_empty() && b.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(WherePredicate::RegionPredicate {
|
Some(WherePredicate::RegionPredicate {
|
||||||
lifetime: clean_middle_region(a).expect("failed to clean lifetime"),
|
lifetime: clean_middle_region(a).expect("failed to clean lifetime"),
|
||||||
bounds: vec![GenericBound::Outlives(
|
bounds: vec![GenericBound::Outlives(
|
||||||
|
@ -365,10 +360,6 @@ fn clean_type_outlives_predicate<'tcx>(
|
||||||
) -> Option<WherePredicate> {
|
) -> Option<WherePredicate> {
|
||||||
let ty::OutlivesPredicate(ty, lt) = pred;
|
let ty::OutlivesPredicate(ty, lt) = pred;
|
||||||
|
|
||||||
if lt.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(WherePredicate::BoundPredicate {
|
Some(WherePredicate::BoundPredicate {
|
||||||
ty: clean_middle_ty(ty, cx, None),
|
ty: clean_middle_ty(ty, cx, None),
|
||||||
bounds: vec![GenericBound::Outlives(
|
bounds: vec![GenericBound::Outlives(
|
||||||
|
|
|
@ -13,11 +13,10 @@
|
||||||
| '_#2r | U0 | {bb0[0..=1], '_#2r}
|
| '_#2r | U0 | {bb0[0..=1], '_#2r}
|
||||||
| '_#3r | U0 | {bb0[0..=1], '_#3r}
|
| '_#3r | U0 | {bb0[0..=1], '_#3r}
|
||||||
| '_#4r | U0 | {bb0[0..=1], '_#4r}
|
| '_#4r | U0 | {bb0[0..=1], '_#4r}
|
||||||
| '_#5r | U0 | {}
|
| '_#5r | U0 | {bb0[0..=1], '_#1r}
|
||||||
| '_#6r | U0 | {bb0[0..=1], '_#1r}
|
| '_#6r | U0 | {bb0[0..=1], '_#2r}
|
||||||
| '_#7r | U0 | {bb0[0..=1], '_#2r}
|
| '_#7r | U0 | {bb0[0..=1], '_#1r}
|
||||||
| '_#8r | U0 | {bb0[0..=1], '_#1r}
|
| '_#8r | U0 | {bb0[0..=1], '_#3r}
|
||||||
| '_#9r | U0 | {bb0[0..=1], '_#3r}
|
|
||||||
|
|
|
|
||||||
| Inference Constraints
|
| Inference Constraints
|
||||||
| '_#0r live at {bb0[0..=1]}
|
| '_#0r live at {bb0[0..=1]}
|
||||||
|
@ -25,16 +24,16 @@
|
||||||
| '_#2r live at {bb0[0..=1]}
|
| '_#2r live at {bb0[0..=1]}
|
||||||
| '_#3r live at {bb0[0..=1]}
|
| '_#3r live at {bb0[0..=1]}
|
||||||
| '_#4r 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: '_#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: '_#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)
|
| '_#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: '_#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)
|
| '_#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: '_#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)
|
| '_#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)
|
||||||
| '_#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)
|
| '_#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)
|
||||||
| '_#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)
|
| '_#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)
|
||||||
| '_#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)
|
| '_#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)
|
||||||
| '_#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)
|
| '_#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 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 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
|
debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
| Inferred Region Values
|
| 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}
|
| '_#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}
|
| '_#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 | {}
|
| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]}
|
||||||
| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
|
| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
|
||||||
| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
|
| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
|
||||||
| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
|
|
||||||
|
|
|
|
||||||
| Inference Constraints
|
| 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]}
|
| '_#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]}
|
| '_#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]}
|
| '_#2r live at {bb1[0]}
|
||||||
| '_#4r live at {bb1[1..=3]}
|
| '_#3r live at {bb1[1..=3]}
|
||||||
| '_#5r live at {bb1[4..=7], bb2[0..=2]}
|
| '_#4r 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)
|
| '_#2r: '_#3r 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)
|
| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
|
||||||
|
|
|
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
|
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
|
let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
|
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 {
|
scope 2 {
|
||||||
debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
|
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 {
|
scope 3 {
|
||||||
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
|
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
|
||||||
}
|
}
|
||||||
|
@ -56,7 +55,7 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
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
|
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
|
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
|
_6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
| Inferred Region Values
|
| 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}
|
| '_#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}
|
| '_#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 | {}
|
| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]}
|
||||||
| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]}
|
| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]}
|
||||||
| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]}
|
| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]}
|
||||||
| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]}
|
|
||||||
|
|
|
|
||||||
| Inference Constraints
|
| 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]}
|
| '_#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]}
|
| '_#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]}
|
| '_#2r live at {bb1[0]}
|
||||||
| '_#4r live at {bb1[1..=3]}
|
| '_#3r live at {bb1[1..=3]}
|
||||||
| '_#5r live at {bb1[4..=7], bb2[0..=2]}
|
| '_#4r 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)
|
| '_#2r: '_#3r 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)
|
| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
|
||||||
|
|
|
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
|
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
|
let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
|
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 {
|
scope 2 {
|
||||||
debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
|
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 {
|
scope 3 {
|
||||||
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
|
debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
|
||||||
}
|
}
|
||||||
|
@ -56,7 +55,7 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
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
|
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
|
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
|
_6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
|
||||||
|
|
|
@ -7,16 +7,15 @@
|
||||||
| Inferred Region Values
|
| Inferred Region Values
|
||||||
| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
|
| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r}
|
||||||
| '_#1r | U0 | {bb0[0..=22], '_#1r}
|
| '_#1r | U0 | {bb0[0..=22], '_#1r}
|
||||||
| '_#2r | U0 | {}
|
| '_#2r | U0 | {bb0[10..=11]}
|
||||||
| '_#3r | U0 | {bb0[10..=11]}
|
| '_#3r | U0 | {bb0[11]}
|
||||||
| '_#4r | U0 | {bb0[11]}
|
|
||||||
|
|
|
|
||||||
| Inference Constraints
|
| Inference Constraints
|
||||||
| '_#0r live at {bb0[0..=22]}
|
| '_#0r live at {bb0[0..=22]}
|
||||||
| '_#1r live at {bb0[0..=22]}
|
| '_#1r live at {bb0[0..=22]}
|
||||||
| '_#3r live at {bb0[10]}
|
| '_#2r live at {bb0[10]}
|
||||||
| '_#4r live at {bb0[11]}
|
| '_#3r live at {bb0[11]}
|
||||||
| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
|
| '_#2r: '_#3r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
|
||||||
|
|
|
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11
|
let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0382]: use of moved value: `c`
|
||||||
--> $DIR/closure-print-generic-verbose-1.rs:17:5
|
--> $DIR/closure-print-generic-verbose-1.rs:17:5
|
||||||
|
|
|
|
||||||
LL | let c = to_fn_once(move|| {
|
LL | let c = to_fn_once(move|| {
|
||||||
| - move occurs because `c` has type `[f<T>::{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<T>::{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();
|
LL | c();
|
||||||
| --- `c` moved due to this call
|
| --- `c` moved due to this call
|
||||||
|
|
|
@ -46,7 +46,7 @@ LL | | });
|
||||||
| |______`cell_a` escapes the function body here
|
| |______`cell_a` escapes the function body here
|
||||||
| argument requires that `'a` must outlive `'static`
|
| 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<T>` is invariant over the parameter `T`
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ LL | | });
|
||||||
| |______`cell_a` escapes the function body here
|
| |______`cell_a` escapes the function body here
|
||||||
| argument requires that `'a` must outlive `'static`
|
| 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<T>` is invariant over the parameter `T`
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
|
|
|
@ -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.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())),
|
||||||
!preds.is_empty() && {
|
!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| {
|
preds.iter().all(|t| {
|
||||||
let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>();
|
let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>();
|
||||||
implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)
|
implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue