Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nll] borrows that must be valid for a free lifetime should explain why #54229

Merged
merged 12 commits into from
Sep 23, 2018
12 changes: 12 additions & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,18 @@ impl<'tcx> Place<'tcx> {
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
Place::Projection(Box::new(PlaceProjection { base: self, elem }))
}

/// Find the innermost `Local` from this `Place`.
pub fn local(&self) -> Option<Local> {
match self {
Place::Local(local) |
Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) => Some(*local),
_ => None,
}
}
}

impl<'tcx> Debug for Place<'tcx> {
Expand Down
17 changes: 17 additions & 0 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,23 @@ impl_stable_hash_for!(struct DebruijnIndex { private });

/// Region utilities
impl RegionKind {
/// Is this region named by the user?
pub fn has_name(&self) -> bool {
match *self {
RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
RegionKind::ReLateBound(_, br) => br.is_named(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: The difference above is... unfortunate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what you mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has_name vs is_named

RegionKind::ReFree(fr) => fr.bound_region.is_named(),
RegionKind::ReScope(..) => false,
RegionKind::ReStatic => true,
RegionKind::ReVar(..) => false,
RegionKind::ReSkolemized(_, br) => br.is_named(),
RegionKind::ReEmpty => false,
RegionKind::ReErased => false,
RegionKind::ReClosureBound(..) => false,
RegionKind::ReCanonical(..) => false,
}
}

pub fn is_late_bound(&self) -> bool {
match *self {
ty::ReLateBound(..) => true,
Expand Down
52 changes: 45 additions & 7 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,14 @@ use hir;
thread_local! {
/// Mechanism for highlighting of specific regions for display in NLL region inference errors.
/// Contains region to highlight and counter for number to use when highlighting.
static HIGHLIGHT_REGION: Cell<Option<(RegionVid, usize)>> = Cell::new(None)
static HIGHLIGHT_REGION_FOR_REGIONVID: Cell<Option<(RegionVid, usize)>> = Cell::new(None)
}

thread_local! {
/// Mechanism for highlighting of specific regions for display in NLL's 'borrow does not live
/// long enough' errors. Contains a region to highlight and a counter to use.
static HIGHLIGHT_REGION_FOR_BOUND_REGION: Cell<Option<(ty::BoundRegion, usize)>> =
Cell::new(None)
}

macro_rules! gen_display_debug_body {
Expand Down Expand Up @@ -564,12 +571,34 @@ pub fn parameterized<F: fmt::Write>(f: &mut F,
PrintContext::new().parameterized(f, substs, did, projections)
}

fn get_highlight_region() -> Option<(RegionVid, usize)> {
HIGHLIGHT_REGION.with(|hr| hr.get())
fn get_highlight_region_for_regionvid() -> Option<(RegionVid, usize)> {
HIGHLIGHT_REGION_FOR_REGIONVID.with(|hr| hr.get())
}

pub fn with_highlight_region<R>(r: RegionVid, counter: usize, op: impl FnOnce() -> R) -> R {
HIGHLIGHT_REGION.with(|hr| {
pub fn with_highlight_region_for_regionvid<R>(
r: RegionVid,
counter: usize,
op: impl FnOnce() -> R
) -> R {
HIGHLIGHT_REGION_FOR_REGIONVID.with(|hr| {
assert_eq!(hr.get(), None);
hr.set(Some((r, counter)));
let r = op();
hr.set(None);
r
})
}

fn get_highlight_region_for_bound_region() -> Option<(ty::BoundRegion, usize)> {
HIGHLIGHT_REGION_FOR_BOUND_REGION.with(|hr| hr.get())
}

pub fn with_highlight_region_for_bound_region<R>(
r: ty::BoundRegion,
counter: usize,
op: impl Fn() -> R
) -> R {
HIGHLIGHT_REGION_FOR_BOUND_REGION.with(|hr| {
assert_eq!(hr.get(), None);
hr.set(Some((r, counter)));
let r = op();
Expand Down Expand Up @@ -726,6 +755,15 @@ define_print! {
return self.print_debug(f, cx);
}

if let Some((region, counter)) = get_highlight_region_for_bound_region() {
if *self == region {
return match *self {
BrNamed(_, name) => write!(f, "{}", name),
BrAnon(_) | BrFresh(_) | BrEnv => write!(f, "'{}", counter)
};
}
}

match *self {
BrNamed(_, name) => write!(f, "{}", name),
BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
Expand All @@ -748,7 +786,7 @@ define_print! {
define_print! {
() ty::RegionKind, (self, f, cx) {
display {
if cx.is_verbose || get_highlight_region().is_some() {
if cx.is_verbose || get_highlight_region_for_regionvid().is_some() {
return self.print_debug(f, cx);
}

Expand Down Expand Up @@ -923,7 +961,7 @@ impl fmt::Debug for ty::FloatVid {

impl fmt::Debug for ty::RegionVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some((region, counter)) = get_highlight_region() {
if let Some((region, counter)) = get_highlight_region_for_regionvid() {
debug!("RegionVid.fmt: region={:?} self={:?} counter={:?}", region, self, counter);
return if *self == region {
write!(f, "'{:?}", counter)
Expand Down
Loading