Skip to content

Commit bb8c991

Browse files
committed
Erase regions in opaque types in typeck
1 parent 2fb0254 commit bb8c991

File tree

6 files changed

+65
-27
lines changed

6 files changed

+65
-27
lines changed

src/librustc/infer/opaque_types/mod.rs

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

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

821825
// ignore `'static`, as that can appear anywhere
822-
ty::ReStatic => return r,
826+
| ty::ReStatic => return r,
823827

824-
_ => { }
828+
_ => {}
825829
}
826830

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

src/librustc/ty/fold.rs

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

123+
fn has_erased_regions(&self) -> bool {
124+
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
125+
}
126+
123127
/// True if there are any un-erased free regions.
124128
fn has_erasable_regions(&self) -> bool {
125129
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
@@ -474,10 +474,13 @@ bitflags! {
474474
/// if a global bound is safe to evaluate.
475475
const HAS_RE_LATE_BOUND = 1 << 11;
476476

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

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

482485
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
483486
TypeFlags::HAS_RE_EARLY_BOUND.bits;
@@ -497,6 +500,7 @@ bitflags! {
497500
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
498501
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
499502
TypeFlags::HAS_RE_LATE_BOUND.bits |
503+
TypeFlags::HAS_RE_ERASED.bits |
500504
TypeFlags::HAS_TY_PLACEHOLDER.bits |
501505
TypeFlags::HAS_CT_INFER.bits |
502506
TypeFlags::HAS_CT_PLACEHOLDER.bits;

src/librustc/ty/sty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,9 @@ impl RegionKind {
17771777
ty::ReEmpty(_) | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => {
17781778
flags = flags | TypeFlags::HAS_FREE_REGIONS;
17791779
}
1780-
ty::ReErased => {}
1780+
ty::ReErased => {
1781+
flags = flags | TypeFlags::HAS_RE_ERASED;
1782+
}
17811783
ty::ReClosureBound(..) => {
17821784
flags = flags | TypeFlags::HAS_FREE_REGIONS;
17831785
}

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: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ use rustc::ty::subst::GenericArgKind;
3333
use rustc::ty::subst::{InternalSubsts, Subst};
3434
use rustc::ty::util::Discr;
3535
use rustc::ty::util::IntTypeExt;
36-
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness};
37-
use rustc::ty::{ReprOptions, ToPredicate};
36+
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
37+
use rustc::ty::{ReprOptions, ToPredicate, WithConstness};
3838
use rustc_attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
3939
use rustc_data_structures::captures::Captures;
4040
use rustc_data_structures::fx::FxHashMap;
@@ -1463,9 +1463,22 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
14631463
find_opaque_ty_constraints(tcx, def_id)
14641464
}
14651465
// Opaque types desugared from `impl Trait`.
1466-
ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
1467-
tcx.mir_borrowck(owner)
1468-
.concrete_opaque_types
1466+
ItemKind::OpaqueTy(hir::OpaqueTy {
1467+
impl_trait_fn: Some(owner), origin, ..
1468+
}) => {
1469+
let concrete_types = match origin {
1470+
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
1471+
&tcx.mir_borrowck(owner).concrete_opaque_types
1472+
}
1473+
hir::OpaqueTyOrigin::Misc => {
1474+
// We shouldn't leak borrowck results through impl Trait in bindings.
1475+
&tcx.typeck_tables_of(owner).concrete_opaque_types
1476+
}
1477+
hir::OpaqueTyOrigin::TypeAlias => {
1478+
span_bug!(item.span, "Type alias impl trait shouldn't have an owner")
1479+
}
1480+
};
1481+
let concrete_ty = concrete_types
14691482
.get(&def_id)
14701483
.map(|opaque| opaque.concrete_type)
14711484
.unwrap_or_else(|| {
@@ -1480,7 +1493,16 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
14801493
),
14811494
);
14821495
tcx.types.err
1483-
})
1496+
});
1497+
debug!("concrete_ty = {:?}", concrete_ty);
1498+
if concrete_ty.has_erased_regions() {
1499+
// FIXME(impl_trait_in_bindings) Handle this case.
1500+
tcx.sess.span_fatal(
1501+
item.span,
1502+
"lifetimes in impl Trait types in bindings are not currently supported",
1503+
);
1504+
}
1505+
concrete_ty
14841506
}
14851507
ItemKind::Trait(..)
14861508
| ItemKind::TraitAlias(..)

0 commit comments

Comments
 (0)