From 8ecb35bd5127b3c6775999f1c79e9318298d20c2 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 15 Aug 2017 17:44:47 +0200 Subject: [PATCH] Make ReScope values opaque when exporting to crate metadata. --- src/librustc/ich/impls_ty.rs | 3 ++ src/librustc/infer/combine.rs | 1 + src/librustc/infer/error_reporting/mod.rs | 1 + src/librustc/infer/freshen.rs | 1 + src/librustc/infer/region_inference/mod.rs | 4 +- src/librustc/ty/fold.rs | 46 +++++++++++++++++++ src/librustc/ty/sty.rs | 8 ++++ src/librustc/ty/util.rs | 1 + src/librustc/util/ppaux.rs | 5 ++ .../borrowck/gather_loans/mod.rs | 1 + src/librustc_metadata/encoder.rs | 29 +++++++----- src/librustc_typeck/check/writeback.rs | 1 + src/librustc_typeck/variance/constraints.rs | 1 + src/librustdoc/clean/mod.rs | 1 + 14 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 45b2a4a1e9667..34c07439ffc34 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -68,6 +68,9 @@ for ty::RegionKind { ty::ReScope(code_extent) => { code_extent.hash_stable(hcx, hasher); } + ty::ReScopeAnon(ref fingerprint) => { + fingerprint.hash_stable(hcx, hasher); + } ty::ReFree(ref free_region) => { free_region.hash_stable(hcx, hasher); } diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 40e933b26a257..92111c633fc43 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -453,6 +453,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' ty::ReEmpty | ty::ReStatic | ty::ReScope(..) | + ty::ReScopeAnon(..) | ty::ReVar(..) | ty::ReEarlyBound(..) | ty::ReFree(..) => { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index b5390da7e852d..52bdcae956309 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -244,6 +244,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ReSkolemized(..) | ty::ReVar(_) | ty::ReLateBound(..) | + ty::ReScopeAnon(..) | ty::ReErased => { (format!("lifetime {:?}", region), None) } diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 41858088f7e70..08e39127f61e3 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -94,6 +94,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::ReEarlyBound(..) | ty::ReFree(_) | ty::ReScope(_) | + ty::ReScopeAnon(_) | ty::ReVar(_) | ty::ReSkolemized(..) | ty::ReEmpty | diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 5588b6d9add16..f9aa72ab34afa 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -26,7 +26,7 @@ use middle::free_region::RegionRelations; use ty::{self, Ty, TyCtxt}; use ty::{Region, RegionVid}; use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased}; -use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh}; +use ty::{ReLateBound, ReScope, ReScopeAnon, ReVar, ReSkolemized, BrFresh}; use std::cell::{Cell, RefCell}; use std::fmt; @@ -905,6 +905,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { match (a, b) { (&ReLateBound(..), _) | (_, &ReLateBound(..)) | + (&ReScopeAnon(..), _) | + (_, &ReScopeAnon(..)) | (&ReErased, _) | (_, &ReErased) => { bug!("cannot relate region: LUB({:?}, {:?})", a, b); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index a1cd92c760915..2ebaa7d9c7aca 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -654,3 +654,49 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { false } } + +/////////////////////////////////////////////////////////////////////////// +// ReScope Anonymizer + +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { + + /// Transforms RegionKind::ReScope values into equivalent + /// RegionKind::ReScopeAnon values. This should be done before exporting to + /// crate metadata (as long as we can't use erase_regions() on everything + /// that is exported). + pub fn anonymize_scope_regions(self, value: &T) -> T + where T : TypeFoldable<'tcx> + { + use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; + use ich::{StableHashingContext, Fingerprint}; + + let hcx = StableHashingContext::new(self); + + return value.fold_with(&mut AnonReScopes { + tcx: self, + hcx, + }); + + struct AnonReScopes<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + hcx: StableHashingContext<'a, 'gcx, 'tcx>, + } + + impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AnonReScopes<'a, 'gcx, 'tcx> { + + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + match *r { + ty::ReScope(code_extent) => { + let mut hasher = StableHasher::new(); + code_extent.hash_stable(&mut self.hcx, &mut hasher); + let code_extent_fingerprint: Fingerprint = hasher.finish(); + self.tcx.mk_region(ty::ReScopeAnon(code_extent_fingerprint)) + }, + _ => r, + } + } + } + } +} diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 389c581ebe314..bc472f37e4580 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -29,6 +29,7 @@ use util::nodemap::FxHashMap; use serialize; use hir; +use ich; use self::InferTy::*; use self::TypeVariants::*; @@ -785,6 +786,13 @@ pub enum RegionKind { /// current function. ReScope(region::CodeExtent), + /// The same as ReScope but with the CodeExtent transformed into a opaque, + /// stable representation. Any ReScope that gets exported to crate metadata + /// should be transformed into such a ReScopeAnon in order to avoid mixing + /// NodeIds from different crates. Note that ReScopeAnon values can still + /// safely be hashed and compared for equality. + ReScopeAnon(ich::Fingerprint), + /// Static data that has an "infinite" lifetime. Top in the region lattice. ReStatic, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 9cd6aa2111873..3a54bea2f1f50 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -753,6 +753,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> ty::ReLateBound(..) | ty::ReFree(..) | ty::ReScope(..) | + ty::ReScopeAnon(..) | ty::ReVar(..) | ty::ReSkolemized(..) => { bug!("TypeIdHasher: unexpected region {:?}", r) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 184fd75135e47..cae20fce11c31 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -481,6 +481,10 @@ impl fmt::Debug for ty::RegionKind { write!(f, "ReScope({:?})", id) } + ty::ReScopeAnon(fingerprint) => { + write!(f, "ReScopeAnon({:?})", fingerprint) + } + ty::ReStatic => write!(f, "ReStatic"), ty::ReVar(ref vid) => { @@ -543,6 +547,7 @@ impl fmt::Display for ty::RegionKind { write!(f, "'{}rv", region_vid.index) } ty::ReScope(_) | + ty::ReScopeAnon(_) | ty::ReVar(_) | ty::ReErased => Ok(()), ty::ReStatic => write!(f, "'static"), diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 4ff603b7eae01..7824051dbc91c 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -367,6 +367,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { ty::ReLateBound(..) | ty::ReVar(..) | ty::ReSkolemized(..) | + ty::ReScopeAnon(..) | ty::ReErased => { span_bug!( cmt.span, diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 1dc5d695348c1..ec19d13e2e2d0 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -482,7 +482,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { fn encode_item_type(&mut self, def_id: DefId) -> Lazy> { let tcx = self.tcx; - let ty = tcx.type_of(def_id); + let ty = tcx.anonymize_scope_regions(&tcx.type_of(def_id)); debug!("IsolatedEncoder::encode_item_type({:?}) => {:?}", def_id, ty); self.lazy(&ty) } @@ -506,7 +506,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { discr: variant.discr, struct_ctor: None, ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(&tcx.fn_sig(def_id))) + Some(self.encode_fn_sig(def_id)) } else { None } @@ -633,7 +633,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { discr: variant.discr, struct_ctor: Some(def_id.index), ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(&tcx.fn_sig(def_id))) + Some(self.encode_fn_sig(def_id)) } else { None } @@ -683,7 +683,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { fn encode_predicates(&mut self, def_id: DefId) -> Lazy> { debug!("IsolatedEncoder::encode_predicates({:?})", def_id); let tcx = self.tcx; - self.lazy(&tcx.predicates_of(def_id)) + self.lazy(&tcx.anonymize_scope_regions(&tcx.predicates_of(def_id))) + } + + fn encode_fn_sig(&mut self, def_id: DefId) -> Lazy> { + debug!("IsolatedEncoder::encode_fn_sig({:?})", def_id); + let tcx = self.tcx; + self.lazy(&tcx.anonymize_scope_regions(&tcx.fn_sig(def_id))) } fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> { @@ -720,7 +726,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { FnData { constness: hir::Constness::NotConst, arg_names, - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.encode_fn_sig(def_id), } } else { bug!() @@ -776,7 +782,6 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id); - let tcx = self.tcx; let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); let ast_item = self.tcx.hir.expect_impl_item(node_id); @@ -799,7 +804,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { FnData { constness: sig.constness, arg_names: self.encode_fn_arg_names_for_body(body), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.encode_fn_sig(def_id), } } else { bug!() @@ -917,7 +922,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let data = FnData { constness, arg_names: self.encode_fn_arg_names_for_body(body), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.encode_fn_sig(def_id), }; EntryKind::Fn(self.lazy(&data)) @@ -1013,7 +1018,9 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { unsafety: trait_def.unsafety, paren_sugar: trait_def.paren_sugar, has_default_impl: tcx.trait_has_default_impl(def_id), - super_predicates: self.lazy(&tcx.super_predicates_of(def_id)), + super_predicates: self.lazy( + &tcx.anonymize_scope_regions(&tcx.super_predicates_of(def_id)) + ), }; EntryKind::Trait(self.lazy(&data)) @@ -1215,7 +1222,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let data = ClosureData { kind: tcx.closure_kind(def_id), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.encode_fn_sig(def_id), }; Entry { @@ -1403,7 +1410,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let data = FnData { constness: hir::Constness::NotConst, arg_names: self.encode_fn_arg_names(names), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.encode_fn_sig(def_id), }; EntryKind::ForeignFn(self.lazy(&data)) } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 36c72fc4b19d6..bb98b74d47c31 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -289,6 +289,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { ty::ReFree(_) | ty::ReLateBound(..) | ty::ReScope(_) | + ty::ReScopeAnon(_) | ty::ReSkolemized(..) => { let span = node_id.to_span(&self.fcx.tcx); span_err!(self.tcx().sess, span, E0564, diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 40474a7933f80..1170a12c2aff3 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -455,6 +455,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::ReFree(..) | ty::ReScope(..) | + ty::ReScopeAnon(..) | ty::ReVar(..) | ty::ReSkolemized(..) | ty::ReEmpty | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8548942d89b75..048269a0ee9fc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -873,6 +873,7 @@ impl Clean> for ty::RegionKind { ty::ReLateBound(..) | ty::ReFree(..) | ty::ReScope(..) | + ty::ReScopeAnon(..) | ty::ReVar(..) | ty::ReSkolemized(..) | ty::ReEmpty |