Skip to content

Commit ec952a0

Browse files
committed
Erase regions in opaque types in typeck
1 parent ff8f1e1 commit ec952a0

File tree

6 files changed

+64
-26
lines changed

6 files changed

+64
-26
lines changed

src/librustc/infer/opaque_types/mod.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -815,32 +815,37 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
815815

816816
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
817817
match r {
818-
// ignore bound regions that appear in the type (e.g., this
819-
// would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
820-
ty::ReLateBound(..) |
818+
// Ignore bound regions that appear in the type, they don't need to
819+
// be remapped (e.g., this would ignore `'r` in a type like
820+
// `for<'r> fn(&'r u32)`.
821+
ty::ReLateBound(..)
822+
823+
// If regions have been erased, don't try to unerase them.
824+
| ty::ReErased
821825

822826
// ignore `'static`, as that can appear anywhere
823-
ty::ReStatic => return r,
827+
| ty::ReStatic => return r,
824828

825-
_ => { }
829+
_ => {}
826830
}
827831

828832
let generics = self.tcx().generics_of(self.opaque_type_def_id);
829833
match self.map.get(&r.into()).map(|k| k.unpack()) {
830834
Some(GenericArgKind::Lifetime(r1)) => r1,
831835
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
836+
None if self.map_missing_regions_to_empty || self.tainted_by_errors => {
837+
self.tcx.lifetimes.re_empty
838+
}
832839
None if generics.parent.is_some() => {
833-
if !self.map_missing_regions_to_empty && !self.tainted_by_errors {
834-
if let Some(hidden_ty) = self.hidden_ty.take() {
835-
unexpected_hidden_region_diagnostic(
836-
self.tcx,
837-
None,
838-
self.opaque_type_def_id,
839-
hidden_ty,
840-
r,
841-
)
842-
.emit();
843-
}
840+
if let Some(hidden_ty) = self.hidden_ty.take() {
841+
unexpected_hidden_region_diagnostic(
842+
self.tcx,
843+
None,
844+
self.opaque_type_def_id,
845+
hidden_ty,
846+
r,
847+
)
848+
.emit();
844849
}
845850
self.tcx.lifetimes.re_empty
846851
}

src/librustc/ty/fold.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
119119
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
120120
}
121121

122+
fn has_erased_regions(&self) -> bool {
123+
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
124+
}
125+
122126
/// True if there are any un-erased free regions.
123127
fn has_erasable_regions(&self) -> bool {
124128
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)

src/librustc/ty/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,10 +475,13 @@ bitflags! {
475475
/// if a global bound is safe to evaluate.
476476
const HAS_RE_LATE_BOUND = 1 << 11;
477477

478-
const HAS_TY_PLACEHOLDER = 1 << 12;
478+
/// Does this have any `ReErased` regions?
479+
const HAS_RE_ERASED = 1 << 12;
479480

480-
const HAS_CT_INFER = 1 << 13;
481-
const HAS_CT_PLACEHOLDER = 1 << 14;
481+
const HAS_TY_PLACEHOLDER = 1 << 13;
482+
483+
const HAS_CT_INFER = 1 << 14;
484+
const HAS_CT_PLACEHOLDER = 1 << 15;
482485

483486
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
484487
TypeFlags::HAS_RE_EARLY_BOUND.bits;
@@ -498,6 +501,7 @@ bitflags! {
498501
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
499502
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
500503
TypeFlags::HAS_RE_LATE_BOUND.bits |
504+
TypeFlags::HAS_RE_ERASED.bits |
501505
TypeFlags::HAS_TY_PLACEHOLDER.bits |
502506
TypeFlags::HAS_CT_INFER.bits |
503507
TypeFlags::HAS_CT_PLACEHOLDER.bits;

src/librustc/ty/sty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,9 @@ impl RegionKind {
16941694
ty::ReEmpty | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => {
16951695
flags = flags | TypeFlags::HAS_FREE_REGIONS;
16961696
}
1697-
ty::ReErased => {}
1697+
ty::ReErased => {
1698+
flags = flags | TypeFlags::HAS_RE_ERASED;
1699+
}
16981700
ty::ReClosureBound(..) => {
16991701
flags = flags | TypeFlags::HAS_FREE_REGIONS;
17001702
}

src/librustc_typeck/check/writeback.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
426426
fn visit_opaque_types(&mut self, span: Span) {
427427
for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
428428
let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
429-
let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id);
429+
let instantiated_ty =
430+
self.tcx().erase_regions(&self.resolve(&opaque_defn.concrete_ty, &hir_id));
430431

431432
debug_assert!(!instantiated_ty.has_escaping_bound_vars());
432433

src/librustc_typeck/collect.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use rustc::ty::subst::GenericArgKind;
3030
use rustc::ty::subst::{InternalSubsts, Subst};
3131
use rustc::ty::util::Discr;
3232
use rustc::ty::util::IntTypeExt;
33-
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
33+
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
3434
use rustc::ty::{ReprOptions, ToPredicate};
3535
use rustc_data_structures::captures::Captures;
3636
use rustc_data_structures::fx::FxHashMap;
@@ -1352,9 +1352,22 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
13521352
find_opaque_ty_constraints(tcx, def_id)
13531353
}
13541354
// Opaque types desugared from `impl Trait`.
1355-
ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
1356-
tcx.mir_borrowck(owner)
1357-
.concrete_opaque_types
1355+
ItemKind::OpaqueTy(hir::OpaqueTy {
1356+
impl_trait_fn: Some(owner), origin, ..
1357+
}) => {
1358+
let concrete_types = match origin {
1359+
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
1360+
&tcx.mir_borrowck(owner).concrete_opaque_types
1361+
}
1362+
hir::OpaqueTyOrigin::Misc => {
1363+
// We shouldn't leak borrowck results through impl Trait in bindings.
1364+
&tcx.typeck_tables_of(owner).concrete_opaque_types
1365+
}
1366+
hir::OpaqueTyOrigin::TypeAlias => {
1367+
span_bug!(item.span, "Type alias impl trait shouldn't have an owner")
1368+
}
1369+
};
1370+
let concrete_ty = concrete_types
13581371
.get(&def_id)
13591372
.map(|opaque| opaque.concrete_type)
13601373
.unwrap_or_else(|| {
@@ -1369,7 +1382,16 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
13691382
),
13701383
);
13711384
tcx.types.err
1372-
})
1385+
});
1386+
debug!("concrete_ty = {:?}", concrete_ty);
1387+
if concrete_ty.has_erased_regions() {
1388+
// FIXME(impl_trait_in_bindings) Handle this case.
1389+
tcx.sess.span_fatal(
1390+
item.span,
1391+
"lifetimes in impl Trait types in bindings are not currently supported",
1392+
);
1393+
}
1394+
concrete_ty
13731395
}
13741396
ItemKind::Trait(..)
13751397
| ItemKind::TraitAlias(..)

0 commit comments

Comments
 (0)