Skip to content

rustc: add ReErased to be used by trait selection, MIR and trans. #34012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,10 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx

fn fold_region(&mut self, r: ty::Region) -> ty::Region {
match r {
// Never make variables for regions bound within the type itself.
ty::ReLateBound(..) => { return r; }
// Never make variables for regions bound within the type itself,
// nor for erased regions.
ty::ReLateBound(..) |
ty::ReErased => { return r; }

// Early-bound regions should really have been substituted away before
// we get to this point.
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
//
// We shouldn't really be having unification failures with ReVar
// and ReLateBound though.
ty::ReSkolemized(..) | ty::ReVar(_) | ty::ReLateBound(..) => {
ty::ReSkolemized(..) |
ty::ReVar(_) |
ty::ReLateBound(..) |
ty::ReErased => {
(format!("lifetime {:?}", region), None)
}
};
Expand Down
9 changes: 5 additions & 4 deletions src/librustc/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
//! error messages or in any other form. Freshening is only really useful as an internal detail.
//!
//! __An important detail concerning regions.__ The freshener also replaces *all* regions with
//! 'static. The reason behind this is that, in general, we do not take region relationships into
//! 'erased. The reason behind this is that, in general, we do not take region relationships into
//! account when making type-overloaded decisions. This is important because of the design of the
//! region inferencer, which is not based on unification but rather on accumulating and then
//! solving a set of constraints. In contrast, the type inferencer assigns a value to each type
Expand Down Expand Up @@ -96,9 +96,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
ty::ReScope(_) |
ty::ReVar(_) |
ty::ReSkolemized(..) |
ty::ReEmpty => {
// replace all free regions with 'static
ty::ReStatic
ty::ReEmpty |
ty::ReErased => {
// replace all free regions with 'erased
ty::ReErased
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/infer/region_inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_data_structures::unify::{self, UnificationTable};
use middle::free_region::FreeRegionMap;
use ty::{self, Ty, TyCtxt};
use ty::{BoundRegion, Region, RegionVid};
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound};
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased};
use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};

use std::cell::{Cell, RefCell};
Expand Down Expand Up @@ -918,8 +918,10 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
(ReLateBound(..), _) |
(_, ReLateBound(..)) |
(ReEarlyBound(..), _) |
(_, ReEarlyBound(..)) => {
bug!("cannot relate bound region: LUB({:?}, {:?})", a, b);
(_, ReEarlyBound(..)) |
(ReErased, _) |
(_, ReErased) => {
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikomatsakis Is this what you were talking about?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eddyb it's a start; I think we might be able to go a bit further. But probably we should just land this change and I can experiment off-line.

}

(ReStatic, _) | (_, ReStatic) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl FlagComputation {
}
ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
ty::ReStatic => {}
ty::ReStatic | ty::ReErased => {}
_ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
}

Expand Down
12 changes: 6 additions & 6 deletions src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,12 +421,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
collector.regions
}

/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
/// Replace any late-bound regions bound in `value` with `'erased`. Useful in trans but also
/// method lookup and a few other places where precise region relationships are not required.
pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
where T : TypeFoldable<'tcx>
{
self.replace_late_bound_regions(value, |_| ty::ReStatic).0
self.replace_late_bound_regions(value, |_| ty::ReErased).0
}

/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
Expand Down Expand Up @@ -547,15 +547,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'static.
// all free regions with 'erased.
//
// Note that we *CAN* replace early-bound regions -- the
// type system never "sees" those, they get substituted
// away. In trans, they will always be erased to 'static
// away. In trans, they will always be erased to 'erased
// whenever a substitution occurs.
match r {
ty::ReLateBound(..) => r,
_ => ty::ReStatic
_ => ty::ReErased
}
}
}
Expand Down Expand Up @@ -651,7 +651,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
// does this represent a region that cannot be named
// in a global way? used in fulfillment caching.
match r {
ty::ReStatic | ty::ReEmpty => {}
ty::ReStatic | ty::ReEmpty | ty::ReErased => {}
_ => return true,
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,9 @@ pub enum Region {
/// The only way to get an instance of ReEmpty is to have a region
/// variable with no constraints.
ReEmpty,

/// Erased region, used by trait selection, in MIR and during trans.
ReErased,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {

pub fn erase_regions(self) -> Substs<'tcx> {
let Substs { types, regions } = self;
let regions = regions.map(|_| ty::ReStatic);
let regions = regions.map(|_| ty::ReErased);
Substs { types: types, regions: regions }
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

let region = |state: &mut SipHasher, r: ty::Region| {
match r {
ty::ReStatic => {}
ty::ReStatic | ty::ReErased => {}
ty::ReLateBound(db, ty::BrAnon(i)) => {
db.hash(state);
i.hash(state);
Expand Down
54 changes: 31 additions & 23 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,36 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
write!(f, "{}", cont)
}
};
let print_region = |f: &mut fmt::Formatter, region: &ty::Region| -> _ {
if verbose {
write!(f, "{:?}", region)
} else {
let s = region.to_string();
if s.is_empty() {
// This happens when the value of the region
// parameter is not easily serialized. This may be
// because the user omitted it in the first place,
// or because it refers to some block in the code,
// etc. I'm not sure how best to serialize this.
write!(f, "'_")

let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| {
// Don't print any regions if they're all erased.
if regions.iter().all(|r| *r == ty::ReErased) {
return Ok(());
}

for region in regions {
start_or_continue(f, start, ", ")?;
if verbose {
write!(f, "{:?}", region)?;
} else {
write!(f, "{}", s)
let s = region.to_string();
if s.is_empty() {
// This happens when the value of the region
// parameter is not easily serialized. This may be
// because the user omitted it in the first place,
// or because it refers to some block in the code,
// etc. I'm not sure how best to serialize this.
write!(f, "'_")?;
} else {
write!(f, "{}", s)?;
}
}
}

Ok(())
};

for region in substs.regions.get_slice(subst::TypeSpace) {
start_or_continue(f, "<", ", ")?;
print_region(f, region)?;
}
print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;

let num_supplied_defaults = if verbose {
0
Expand Down Expand Up @@ -211,10 +219,7 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
write!(f, "::{}", item_name)?;
}

for region in substs.regions.get_slice(subst::FnSpace) {
start_or_continue(f, "::<", ", ")?;
print_region(f, region)?;
}
print_regions(f, "::<", substs.regions.get_slice(subst::FnSpace))?;

// FIXME: consider being smart with defaults here too
for ty in substs.types.get_slice(subst::FnSpace) {
Expand Down Expand Up @@ -536,7 +541,9 @@ impl fmt::Debug for ty::Region {
write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
}

ty::ReEmpty => write!(f, "ReEmpty")
ty::ReEmpty => write!(f, "ReEmpty"),

ty::ReErased => write!(f, "ReErased")
}
}
}
Expand Down Expand Up @@ -600,7 +607,8 @@ impl fmt::Display for ty::Region {
write!(f, "{}", br)
}
ty::ReScope(_) |
ty::ReVar(_) => Ok(()),
ty::ReVar(_) |
ty::ReErased => Ok(()),
ty::ReStatic => write!(f, "'static"),
ty::ReEmpty => write!(f, "'<empty>"),
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/gather_loans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
ty::ReLateBound(..) |
ty::ReEarlyBound(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) => {
ty::ReSkolemized(..) |
ty::ReErased => {
span_bug!(
cmt.span,
"invalid borrow lifetime: {:?}",
Expand Down
9 changes: 3 additions & 6 deletions src/librustc_metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,9 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
assert_eq!(self.next(), '|');
ty::ReScope(scope)
}
't' => {
ty::ReStatic
}
'e' => {
ty::ReStatic
}
't' => ty::ReStatic,
'e' => ty::ReEmpty,
'E' => ty::ReErased,
_ => bug!("parse_region: bad input")
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
ty::ReEmpty => {
write!(w, "e");
}
ty::ReErased => {
write!(w, "E");
}
ty::ReVar(_) | ty::ReSkolemized(..) => {
// these should not crop up after typeck
bug!("cannot encode region variables");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ fn bind_subslice_pat(bcx: Block,
let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]);
let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right);
let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
let slice_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic),
let slice_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReErased),
bcx.tcx().mk_slice(unit_ty));
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
Store(bcx, slice_begin, expr::get_dataptr(bcx, scratch.val));
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
};

let bare_fn_ty_maybe_ref = if is_by_ref {
tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), bare_fn_ty)
tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), bare_fn_ty)
} else {
bare_fn_ty
};
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ fn get_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-> Ty<'tcx> {
match tcx.closure_kind(closure_id) {
ty::ClosureKind::Fn => {
tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), fn_ty)
tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), fn_ty)
}
ty::ClosureKind::FnMut => {
tcx.mk_mut_ref(tcx.mk_region(ty::ReStatic), fn_ty)
tcx.mk_mut_ref(tcx.mk_region(ty::ReErased), fn_ty)
}
ty::ClosureKind::FnOnce => fn_ty,
}
Expand Down Expand Up @@ -344,7 +344,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
// Find a version of the closure type. Substitute static for the
// region since it doesn't really matter.
let closure_ty = tcx.mk_closure_from_closure_substs(closure_def_id, substs);
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty);
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), closure_ty);

// Make a version with the type of by-ref closure.
let ty::ClosureTy { unsafety, abi, mut sig } =
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Don't copy data to do a deref+ref
// (i.e., skip the last auto-deref).
llconst = addr_of(cx, llconst, type_of::align_of(cx, ty), "autoref");
ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReStatic), ty);
ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReErased), ty);
}
} else if adj.autoderefs > 0 {
let (dv, dt) = const_deref(cx, llconst, ty);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
assert!(scheme.generics.types.is_empty());
self.tcx().mk_substs(
Substs::new(VecPerParamSpace::empty(),
scheme.generics.regions.map(|_| ty::ReStatic)))
scheme.generics.regions.map(|_| ty::ReErased)))
}

pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1978,7 +1978,7 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Compute final type. Note that we are loose with the region and
// mutability, since those things don't matter in trans.
let referent_ty = lv_datum.ty;
let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), referent_ty);
let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReErased), referent_ty);

// Construct the resulting datum. The right datum to return here would be an Lvalue datum,
// because there is cleanup scheduled and the datum doesn't own the data, but for thin pointers
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// the method may have some early-bound lifetimes, add
// regions for those
let num_dummy_regions = trait_method_type.generics.regions.len(FnSpace);
let dummy_regions = vec![ty::ReStatic; num_dummy_regions];
let dummy_regions = vec![ty::ReErased; num_dummy_regions];
let method_substs = substs.clone()
.with_method(vec![], dummy_regions);
let method_substs = tcx.mk_substs(method_substs);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let tr_lvalue = self.const_lvalue(lvalue, span)?;

let ty = tr_lvalue.ty;
let ref_ty = tcx.mk_ref(tcx.mk_region(ty::ReStatic),
let ref_ty = tcx.mk_ref(tcx.mk_region(ty::ReErased),
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() });

let base = match tr_lvalue.base {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {

let ty = tr_lvalue.ty.to_ty(bcx.tcx());
let ref_ty = bcx.tcx().mk_ref(
bcx.tcx().mk_region(ty::ReStatic),
bcx.tcx().mk_region(ty::ReErased),
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() }
);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
impl<'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
-> Instance<'tcx> {
assert!(substs.regions.iter().all(|&r| r == ty::ReStatic));
assert!(substs.regions.iter().all(|&r| r == ty::ReErased));
Instance { def: def_id, substs: substs }
}
pub fn mono<'a>(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {
Expand Down
Loading