about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/opaque_types/mod.rs37
-rw-r--r--src/librustc/ty/fold.rs4
-rw-r--r--src/librustc/ty/mod.rs10
-rw-r--r--src/librustc/ty/sty.rs4
-rw-r--r--src/librustc_typeck/check/writeback.rs3
-rw-r--r--src/librustc_typeck/collect.rs34
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(..)