From 154cd9419763f35c0f38b1cb044f43eeece1ebf0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 4 Dec 2017 05:11:36 -0500 Subject: [PATCH] rework region flags: 'static can be erased too The existing flags did not consider `'static` to be "free". This then fed into what was "erasable" -- but `'static` is most certainly erasable. --- src/librustc/ty/fold.rs | 17 +++++++++++------ src/librustc/ty/mod.rs | 10 ++++++++++ src/librustc/ty/sty.rs | 17 ++++++++++++++--- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 069dc0275cbb..c5b82730e488 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -97,14 +97,19 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn has_closure_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_CLOSURE) } - fn has_erasable_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND | - TypeFlags::HAS_RE_INFER | - TypeFlags::HAS_FREE_REGIONS) + /// "Free" regions in this context means that it has any region + /// that is not (a) erased or (b) late-bound. + fn has_free_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) } + + /// True if there any any un-erased free regions. + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) + } + fn is_normalized_for_trans(&self) -> bool { - !self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND | - TypeFlags::HAS_RE_INFER | + !self.has_type_flags(TypeFlags::HAS_RE_INFER | TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_TY_INFER | TypeFlags::HAS_PARAMS | diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4e1a79d4613e..9d088b95bbbb 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -421,8 +421,18 @@ bitflags! { const HAS_TY_INFER = 1 << 2; const HAS_RE_INFER = 1 << 3; const HAS_RE_SKOL = 1 << 4; + + /// Does this have any `ReEarlyBound` regions? Used to + /// determine whether substitition is required, since those + /// represent regions that are bound in a `ty::Generics` and + /// hence may be substituted. const HAS_RE_EARLY_BOUND = 1 << 5; + + /// Does this have any region that "appears free" in the type? + /// Basically anything but `ReLateBound` and `ReErased`. const HAS_FREE_REGIONS = 1 << 6; + + /// Is an error type reachable? const HAS_TY_ERR = 1 << 7; const HAS_PROJECTION = 1 << 8; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e085d1311c3f..2f72b3dde42f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1184,18 +1184,29 @@ impl RegionKind { match *self { ty::ReVar(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_RE_INFER; flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX; } ty::ReSkolemized(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_RE_INFER; flags = flags | TypeFlags::HAS_RE_SKOL; flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX; } ty::ReLateBound(..) => { } - ty::ReEarlyBound(..) => { flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; } - ty::ReStatic | ty::ReErased => { } - _ => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } + ty::ReEarlyBound(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; + } + ty::ReEmpty | + ty::ReStatic | + ty::ReFree { .. } | + ty::ReScope { .. } => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + } + ty::ReErased => { + } } match *self {