diff options
| -rw-r--r-- | src/librustc/infer/opaque_types/mod.rs | 37 | ||||
| -rw-r--r-- | src/librustc/ty/fold.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 10 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/writeback.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 34 |
6 files changed, 65 insertions, 27 deletions
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 1d69f598256..088e57f91a7 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -814,32 +814,37 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match r { - // ignore bound regions that appear in the type (e.g., this - // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. - ty::ReLateBound(..) | + // Ignore bound regions that appear in the type, they don't need to + // be remapped (e.g., this would ignore `'r` in a type like + // `for<'r> fn(&'r u32)`. + ty::ReLateBound(..) + + // If regions have been erased, don't try to unerase them. + | ty::ReErased // ignore `'static`, as that can appear anywhere - ty::ReStatic => return r, + | ty::ReStatic => return r, - _ => { } + _ => {} } let generics = self.tcx().generics_of(self.opaque_type_def_id); match self.map.get(&r.into()).map(|k| k.unpack()) { Some(GenericArgKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), + None if self.map_missing_regions_to_empty || self.tainted_by_errors => { + self.tcx.lifetimes.re_empty + } None if generics.parent.is_some() => { - if !self.map_missing_regions_to_empty && !self.tainted_by_errors { - if let Some(hidden_ty) = self.hidden_ty.take() { - unexpected_hidden_region_diagnostic( - self.tcx, - None, - self.opaque_type_def_id, - hidden_ty, - r, - ) - .emit(); - } + if let Some(hidden_ty) = self.hidden_ty.take() { + unexpected_hidden_region_diagnostic( + self.tcx, + None, + self.opaque_type_def_id, + hidden_ty, + r, + ) + .emit(); } self.tcx.lifetimes.re_root_empty } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 1f007b970b0..5ff0d04c1ed 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -120,6 +120,10 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) } + fn has_erased_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_ERASED) + } + /// True if there are any un-erased free regions. fn has_erasable_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index b67cab65207..6d36116d782 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -474,10 +474,13 @@ bitflags! { /// if a global bound is safe to evaluate. const HAS_RE_LATE_BOUND = 1 << 11; - const HAS_TY_PLACEHOLDER = 1 << 12; + /// Does this have any `ReErased` regions? + const HAS_RE_ERASED = 1 << 12; - const HAS_CT_INFER = 1 << 13; - const HAS_CT_PLACEHOLDER = 1 << 14; + const HAS_TY_PLACEHOLDER = 1 << 13; + + const HAS_CT_INFER = 1 << 14; + const HAS_CT_PLACEHOLDER = 1 << 15; const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits; @@ -497,6 +500,7 @@ bitflags! { TypeFlags::HAS_FREE_LOCAL_NAMES.bits | TypeFlags::KEEP_IN_LOCAL_TCX.bits | TypeFlags::HAS_RE_LATE_BOUND.bits | + TypeFlags::HAS_RE_ERASED.bits | TypeFlags::HAS_TY_PLACEHOLDER.bits | TypeFlags::HAS_CT_INFER.bits | TypeFlags::HAS_CT_PLACEHOLDER.bits; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 0718853b1df..02abac975ac 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1777,7 +1777,9 @@ impl RegionKind { ty::ReEmpty(_) | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } - ty::ReErased => {} + ty::ReErased => { + flags = flags | TypeFlags::HAS_RE_ERASED; + } ty::ReClosureBound(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 758ce6b5222..3a1622f1649 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -426,7 +426,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn visit_opaque_types(&mut self, span: Span) { for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() { let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap(); - let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id); + let instantiated_ty = + self.tcx().erase_regions(&self.resolve(&opaque_defn.concrete_ty, &hir_id)); debug_assert!(!instantiated_ty.has_escaping_bound_vars()); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index cf82789482b..4448c067d34 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -33,8 +33,8 @@ use rustc::ty::subst::GenericArgKind; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; -use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness}; -use rustc::ty::{ReprOptions, ToPredicate}; +use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{ReprOptions, ToPredicate, WithConstness}; use rustc_attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; @@ -1463,9 +1463,22 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { find_opaque_ty_constraints(tcx, def_id) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(owner), .. }) => { - tcx.mir_borrowck(owner) - .concrete_opaque_types + ItemKind::OpaqueTy(hir::OpaqueTy { + impl_trait_fn: Some(owner), origin, .. + }) => { + let concrete_types = match origin { + hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { + &tcx.mir_borrowck(owner).concrete_opaque_types + } + hir::OpaqueTyOrigin::Misc => { + // We shouldn't leak borrowck results through impl Trait in bindings. + &tcx.typeck_tables_of(owner).concrete_opaque_types + } + hir::OpaqueTyOrigin::TypeAlias => { + span_bug!(item.span, "Type alias impl trait shouldn't have an owner") + } + }; + let concrete_ty = concrete_types .get(&def_id) .map(|opaque| opaque.concrete_type) .unwrap_or_else(|| { @@ -1480,7 +1493,16 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { ), ); tcx.types.err - }) + }); + debug!("concrete_ty = {:?}", concrete_ty); + if concrete_ty.has_erased_regions() { + // FIXME(impl_trait_in_bindings) Handle this case. + tcx.sess.span_fatal( + item.span, + "lifetimes in impl Trait types in bindings are not currently supported", + ); + } + concrete_ty } ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
