Overhaul RegionKind
and Region
.
Specifically, change `Region` from this: ``` pub type Region<'tcx> = &'tcx RegionKind; ``` to this: ``` pub struct Region<'tcx>(&'tcx Interned<RegionKind>); ``` This now matches `Ty` and `Predicate` more closely. Things to note - Regions have always been interned, but we haven't been using pointer-based `Eq` and `Hash`. This is now happening. - I chose to impl `Deref` for `Region` because it makes pattern matching a lot nicer, and `Region` can be viewed as just a smart wrapper for `RegionKind`. - Various methods are moved from `RegionKind` to `Region`. - There is a lot of tedious sigil changes. - A couple of types like `HighlightBuilder`, `RegionHighlightMode` now have a `'tcx` lifetime because they hold a `Ty<'tcx>`, so they can call `mk_region`. - A couple of test outputs change slightly, I'm not sure why, but the new outputs are a little better.
This commit is contained in:
parent
925ec0d3c7
commit
7024dc523a
80 changed files with 443 additions and 346 deletions
|
@ -194,7 +194,7 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
|
||||
fn visit_region(&mut self,
|
||||
region: & $($mutability)? ty::Region<'tcx>,
|
||||
region: $(& $mutability)? ty::Region<'tcx>,
|
||||
_: Location) {
|
||||
self.super_region(region);
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ macro_rules! make_mir_visitor {
|
|||
Rvalue::ThreadLocalRef(_) => {}
|
||||
|
||||
Rvalue::Ref(r, bk, path) => {
|
||||
self.visit_region(r, location);
|
||||
self.visit_region($(& $mutability)? *r, location);
|
||||
let ctx = match bk {
|
||||
BorrowKind::Shared => PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::SharedBorrow
|
||||
|
@ -900,7 +900,7 @@ macro_rules! make_mir_visitor {
|
|||
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
|
||||
}
|
||||
|
||||
fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
|
||||
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
|
||||
}
|
||||
|
||||
fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
|
||||
|
|
|
@ -138,6 +138,12 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
|
||||
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
|
||||
self.kind().encode(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
|
||||
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
|
||||
e.encode_alloc_id(self)
|
||||
|
@ -156,7 +162,6 @@ macro_rules! encodable_via_deref {
|
|||
|
||||
encodable_via_deref! {
|
||||
&'tcx ty::TypeckResults<'tcx>,
|
||||
ty::Region<'tcx>,
|
||||
&'tcx traits::ImplSource<'tcx, ()>,
|
||||
&'tcx mir::Body<'tcx>,
|
||||
&'tcx mir::UnsafetyCheckResult,
|
||||
|
|
|
@ -860,10 +860,10 @@ impl<'tcx> CanonicalUserType<'tcx> {
|
|||
_ => false,
|
||||
},
|
||||
|
||||
GenericArgKind::Lifetime(r) => match r {
|
||||
GenericArgKind::Lifetime(r) => match *r {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(*debruijn, ty::INNERMOST);
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == br.var
|
||||
}
|
||||
_ => false,
|
||||
|
@ -930,7 +930,11 @@ impl<'tcx> CommonTypes<'tcx> {
|
|||
|
||||
impl<'tcx> CommonLifetimes<'tcx> {
|
||||
fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
|
||||
let mk = |r| interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0;
|
||||
let mk = |r| {
|
||||
Region(Interned::new_unchecked(
|
||||
interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
|
||||
))
|
||||
};
|
||||
|
||||
CommonLifetimes {
|
||||
re_root_empty: mk(RegionKind::ReEmpty(ty::UniverseIndex::ROOT)),
|
||||
|
@ -1680,7 +1684,7 @@ macro_rules! nop_list_lift {
|
|||
}
|
||||
|
||||
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
|
||||
nop_lift_old! {region; Region<'a> => Region<'tcx>}
|
||||
nop_lift! {region; Region<'a> => Region<'tcx>}
|
||||
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
||||
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
|
||||
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
|
||||
|
@ -2086,6 +2090,46 @@ impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
|
|||
}
|
||||
|
||||
macro_rules! direct_interners {
|
||||
($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
|
||||
$(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
|
||||
fn borrow<'a>(&'a self) -> &'a $ty {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// The `Borrow` trait requires that `x.borrow() == y.borrow()`
|
||||
// equals `x == y`.
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
|
||||
|
||||
impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
|
||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||
// The `Borrow` trait requires that `x.borrow().hash(s) ==
|
||||
// x.hash(s)`.
|
||||
self.0.hash(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn $method(self, v: $ty) -> $ret_ty {
|
||||
$ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
|
||||
InternedInSet(self.interners.arena.alloc(v))
|
||||
}).0))
|
||||
}
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
direct_interners! {
|
||||
region: mk_region(RegionKind): Region -> Region<'tcx>,
|
||||
}
|
||||
|
||||
macro_rules! direct_interners_old {
|
||||
($($name:ident: $method:ident($ty:ty),)+) => {
|
||||
$(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
|
||||
fn borrow<'a>(&'a self) -> &'a $ty {
|
||||
|
@ -2121,8 +2165,8 @@ macro_rules! direct_interners {
|
|||
}
|
||||
}
|
||||
|
||||
direct_interners! {
|
||||
region: mk_region(RegionKind),
|
||||
// FIXME: eventually these should all be converted to `direct_interners`.
|
||||
direct_interners_old! {
|
||||
const_: mk_const(Const<'tcx>),
|
||||
const_allocation: intern_const_alloc(Allocation),
|
||||
layout: intern_layout(Layout),
|
||||
|
|
|
@ -960,10 +960,10 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match r {
|
||||
ty::ReLateBound(index, br) if *index == self.binder_index => {
|
||||
match *r {
|
||||
ty::ReLateBound(index, br) if index == self.binder_index => {
|
||||
if self.bound_vars.len() <= br.var.as_usize() {
|
||||
bug!("Not enough bound vars: {:?} not found in {:?}", *br, self.bound_vars);
|
||||
bug!("Not enough bound vars: {:?} not found in {:?}", br, self.bound_vars);
|
||||
}
|
||||
let list_var = self.bound_vars[br.var.as_usize()];
|
||||
match list_var {
|
||||
|
@ -1076,9 +1076,9 @@ pub fn shift_region<'tcx>(
|
|||
region: ty::Region<'tcx>,
|
||||
amount: u32,
|
||||
) -> ty::Region<'tcx> {
|
||||
match region {
|
||||
match *region {
|
||||
ty::ReLateBound(debruijn, br) if amount > 0 => {
|
||||
tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), *br))
|
||||
tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), br))
|
||||
}
|
||||
_ => region,
|
||||
}
|
||||
|
|
|
@ -326,19 +326,11 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
|||
characteristic_def_id_of_type_cached(ty, &mut SsoHashSet::new())
|
||||
}
|
||||
|
||||
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
|
||||
type Output = P::Region;
|
||||
type Error = P::Error;
|
||||
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
|
||||
cx.print_region(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'_> {
|
||||
type Output = P::Region;
|
||||
type Error = P::Error;
|
||||
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
|
||||
cx.print_region(self)
|
||||
cx.print_region(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,11 +131,13 @@ pub fn with_no_visible_paths<F: FnOnce() -> R, R>(f: F) -> R {
|
|||
///
|
||||
/// Regions not selected by the region highlight mode are presently
|
||||
/// unaffected.
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct RegionHighlightMode {
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct RegionHighlightMode<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// If enabled, when we see the selected region, use "`'N`"
|
||||
/// instead of the ordinary behavior.
|
||||
highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
|
||||
highlight_regions: [Option<(ty::Region<'tcx>, usize)>; 3],
|
||||
|
||||
/// If enabled, when printing a "free region" that originated from
|
||||
/// the given `ty::BoundRegionKind`, print it as "`'1`". Free regions that would ordinarily
|
||||
|
@ -147,12 +149,20 @@ pub struct RegionHighlightMode {
|
|||
highlight_bound_region: Option<(ty::BoundRegionKind, usize)>,
|
||||
}
|
||||
|
||||
impl RegionHighlightMode {
|
||||
impl<'tcx> RegionHighlightMode<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||
Self {
|
||||
tcx,
|
||||
highlight_regions: Default::default(),
|
||||
highlight_bound_region: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// If `region` and `number` are both `Some`, invokes
|
||||
/// `highlighting_region`.
|
||||
pub fn maybe_highlighting_region(
|
||||
&mut self,
|
||||
region: Option<ty::Region<'_>>,
|
||||
region: Option<ty::Region<'tcx>>,
|
||||
number: Option<usize>,
|
||||
) {
|
||||
if let Some(k) = region {
|
||||
|
@ -163,24 +173,24 @@ impl RegionHighlightMode {
|
|||
}
|
||||
|
||||
/// Highlights the region inference variable `vid` as `'N`.
|
||||
pub fn highlighting_region(&mut self, region: ty::Region<'_>, number: usize) {
|
||||
pub fn highlighting_region(&mut self, region: ty::Region<'tcx>, number: usize) {
|
||||
let num_slots = self.highlight_regions.len();
|
||||
let first_avail_slot =
|
||||
self.highlight_regions.iter_mut().find(|s| s.is_none()).unwrap_or_else(|| {
|
||||
bug!("can only highlight {} placeholders at a time", num_slots,)
|
||||
});
|
||||
*first_avail_slot = Some((*region, number));
|
||||
*first_avail_slot = Some((region, number));
|
||||
}
|
||||
|
||||
/// Convenience wrapper for `highlighting_region`.
|
||||
pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
|
||||
self.highlighting_region(&ty::ReVar(vid), number)
|
||||
self.highlighting_region(self.tcx.mk_region(ty::ReVar(vid)), number)
|
||||
}
|
||||
|
||||
/// Returns `Some(n)` with the number to use for the given region, if any.
|
||||
fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
|
||||
self.highlight_regions.iter().find_map(|h| match h {
|
||||
Some((r, n)) if r == region => Some(*n),
|
||||
Some((r, n)) if *r == region => Some(*n),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
@ -1054,7 +1064,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
|
||||
// Don't print `'_` if there's no unerased regions.
|
||||
let print_regions = args.iter().any(|arg| match arg.unpack() {
|
||||
GenericArgKind::Lifetime(r) => *r != ty::ReErased,
|
||||
GenericArgKind::Lifetime(r) => !r.is_erased(),
|
||||
_ => false,
|
||||
});
|
||||
let mut args = args.iter().cloned().filter(|arg| match arg.unpack() {
|
||||
|
@ -1536,7 +1546,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
|
|||
binder_depth: usize,
|
||||
printed_type_count: usize,
|
||||
|
||||
pub region_highlight_mode: RegionHighlightMode,
|
||||
pub region_highlight_mode: RegionHighlightMode<'tcx>,
|
||||
|
||||
pub name_resolver: Option<Box<&'a dyn Fn(ty::TyVid) -> Option<String>>>,
|
||||
}
|
||||
|
@ -1566,7 +1576,7 @@ impl<'a, 'tcx, F> FmtPrinter<'a, 'tcx, F> {
|
|||
region_index: 0,
|
||||
binder_depth: 0,
|
||||
printed_type_count: 0,
|
||||
region_highlight_mode: RegionHighlightMode::default(),
|
||||
region_highlight_mode: RegionHighlightMode::new(tcx),
|
||||
name_resolver: None,
|
||||
}))
|
||||
}
|
||||
|
@ -1802,7 +1812,7 @@ impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||
// Don't print `'_` if there's no unerased regions.
|
||||
let print_regions = self.tcx.sess.verbose()
|
||||
|| args.iter().any(|arg| match arg.unpack() {
|
||||
GenericArgKind::Lifetime(r) => *r != ty::ReErased,
|
||||
GenericArgKind::Lifetime(r) => !r.is_erased(),
|
||||
_ => false,
|
||||
});
|
||||
let args = args.iter().cloned().filter(|arg| match arg.unpack() {
|
||||
|
@ -2061,7 +2071,7 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let name = &mut self.name;
|
||||
let region = match *r {
|
||||
ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
|
||||
ty::ReLateBound(_, br) => *self.region_map.entry(br).or_insert_with(|| name(br)),
|
||||
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
|
||||
// If this is an anonymous placeholder, don't rename. Otherwise, in some
|
||||
// async fns, we get a `for<'r> Send` bound
|
||||
|
@ -2070,7 +2080,7 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
|||
_ => {
|
||||
// Index doesn't matter, since this is just for naming and these never get bound
|
||||
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
|
||||
self.region_map.entry(br).or_insert_with(|| name(br))
|
||||
*self.region_map.entry(br).or_insert_with(|| name(br))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2272,7 +2282,7 @@ impl<'tcx, F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
|||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
trace!("address: {:p}", r);
|
||||
trace!("address: {:p}", r.0.0);
|
||||
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
|
||||
self.used_region_names.insert(name);
|
||||
} else if let ty::RePlaceholder(ty::PlaceholderRegion {
|
||||
|
@ -2369,7 +2379,7 @@ macro_rules! define_print_and_forward_display {
|
|||
}
|
||||
|
||||
// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
|
||||
impl fmt::Display for ty::RegionKind {
|
||||
impl<'tcx> fmt::Display for ty::Region<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ty::tls::with(|tcx| {
|
||||
self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, Typ
|
|||
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv};
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::vec::Idx;
|
||||
|
@ -21,8 +22,9 @@ use rustc_target::abi::VariantIdx;
|
|||
use rustc_target::spec::abi;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
use std::ops::{Deref, Range};
|
||||
use ty::util::IntTypeExt;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
|
@ -1391,7 +1393,24 @@ impl ParamConst {
|
|||
}
|
||||
}
|
||||
|
||||
pub type Region<'tcx> = &'tcx RegionKind;
|
||||
/// Use this rather than `TyKind`, whenever possible.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
|
||||
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
|
||||
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind>);
|
||||
|
||||
impl<'tcx> Deref for Region<'tcx> {
|
||||
type Target = RegionKind;
|
||||
|
||||
fn deref(&self) -> &RegionKind {
|
||||
&self.0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for Region<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self.kind())
|
||||
}
|
||||
}
|
||||
|
||||
/// Representation of regions. Note that the NLL checker uses a distinct
|
||||
/// representation of regions. For this reason, it internally replaces all the
|
||||
|
@ -1399,6 +1418,9 @@ pub type Region<'tcx> = &'tcx RegionKind;
|
|||
/// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
|
||||
/// module for more information.
|
||||
///
|
||||
/// Note: operations are on the wrapper `Region` type, which is interned,
|
||||
/// rather than this type.
|
||||
///
|
||||
/// ## The Region lattice within a given function
|
||||
///
|
||||
/// In general, the region lattice looks like
|
||||
|
@ -1655,9 +1677,13 @@ impl<'tcx> PolyExistentialProjection<'tcx> {
|
|||
}
|
||||
|
||||
/// Region utilities
|
||||
impl RegionKind {
|
||||
impl<'tcx> Region<'tcx> {
|
||||
pub fn kind(self) -> RegionKind {
|
||||
*self.0.0
|
||||
}
|
||||
|
||||
/// Is this region named by the user?
|
||||
pub fn has_name(&self) -> bool {
|
||||
pub fn has_name(self) -> bool {
|
||||
match *self {
|
||||
RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
|
||||
RegionKind::ReLateBound(_, br) => br.kind.is_named(),
|
||||
|
@ -1671,24 +1697,39 @@ impl RegionKind {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_late_bound(&self) -> bool {
|
||||
pub fn is_static(self) -> bool {
|
||||
matches!(*self, ty::ReStatic)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_erased(self) -> bool {
|
||||
matches!(*self, ty::ReErased)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_late_bound(self) -> bool {
|
||||
matches!(*self, ty::ReLateBound(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_placeholder(&self) -> bool {
|
||||
pub fn is_placeholder(self) -> bool {
|
||||
matches!(*self, ty::RePlaceholder(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bound_at_or_above_binder(&self, index: ty::DebruijnIndex) -> bool {
|
||||
pub fn is_empty(self) -> bool {
|
||||
matches!(*self, ty::ReEmpty(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
||||
match *self {
|
||||
ty::ReLateBound(debruijn, _) => debruijn >= index,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_flags(&self) -> TypeFlags {
|
||||
pub fn type_flags(self) -> TypeFlags {
|
||||
let mut flags = TypeFlags::empty();
|
||||
|
||||
match *self {
|
||||
|
@ -1746,8 +1787,8 @@ impl RegionKind {
|
|||
/// of the impl, and for all the other highlighted regions, it
|
||||
/// would return the `DefId` of the function. In other cases (not shown), this
|
||||
/// function might return the `DefId` of a closure.
|
||||
pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
|
||||
match self {
|
||||
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
|
||||
match *self {
|
||||
ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(),
|
||||
ty::ReFree(fr) => fr.scope,
|
||||
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
|
||||
|
|
|
@ -26,6 +26,9 @@ use std::ops::ControlFlow;
|
|||
/// To reduce memory usage, a `GenericArg` is an interned pointer,
|
||||
/// with the lowest 2 bits being reserved for a tag to
|
||||
/// indicate the type (`Ty`, `Region`, or `Const`) it points to.
|
||||
///
|
||||
/// Note: the `PartialEq`, `Eq` and `Hash` derives are only valid because `Ty`,
|
||||
/// `Region` and `Const` are all interned.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct GenericArg<'tcx> {
|
||||
ptr: NonZeroUsize,
|
||||
|
@ -49,8 +52,8 @@ impl<'tcx> GenericArgKind<'tcx> {
|
|||
let (tag, ptr) = match self {
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
// Ensure we can use the tag bits.
|
||||
assert_eq!(mem::align_of_val(lt) & TAG_MASK, 0);
|
||||
(REGION_TAG, lt as *const ty::RegionKind as usize)
|
||||
assert_eq!(mem::align_of_val(lt.0.0) & TAG_MASK, 0);
|
||||
(REGION_TAG, lt.0.0 as *const ty::RegionKind as usize)
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
// Ensure we can use the tag bits.
|
||||
|
@ -117,9 +120,9 @@ impl<'tcx> GenericArg<'tcx> {
|
|||
// and this is just going in the other direction.
|
||||
unsafe {
|
||||
match ptr & TAG_MASK {
|
||||
REGION_TAG => {
|
||||
GenericArgKind::Lifetime(&*((ptr & !TAG_MASK) as *const ty::RegionKind))
|
||||
}
|
||||
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
|
||||
&*((ptr & !TAG_MASK) as *const ty::RegionKind),
|
||||
))),
|
||||
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
|
||||
&*((ptr & !TAG_MASK) as *const ty::TyS<'tcx>),
|
||||
))),
|
||||
|
|
|
@ -5,8 +5,9 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFolder};
|
|||
use crate::ty::layout::IntegerExt;
|
||||
use crate::ty::query::TyCtxtAt;
|
||||
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{self, DebruijnIndex, DefIdTree, List, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::{
|
||||
self, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*, TypeFoldable,
|
||||
};
|
||||
use rustc_apfloat::Float as _;
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
|
||||
|
@ -390,7 +391,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
let result = iter::zip(item_substs, impl_substs)
|
||||
.filter(|&(_, k)| {
|
||||
match k.unpack() {
|
||||
GenericArgKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => {
|
||||
GenericArgKind::Lifetime(Region(Interned(ReEarlyBound(ref ebr), _))) => {
|
||||
!impl_generics.region_param(ebr, self).pure_wrt_drop
|
||||
}
|
||||
GenericArgKind::Type(Ty(Interned(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue