-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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] change how MIR represents places #53247
Conversation
cc @eddyb as well |
src/librustc/ich/impls_mir.rs
Outdated
hasher: &mut StableHasher<W>, | ||
) { | ||
self.base.hash_stable(hcx, hasher); | ||
self.elems.hash_stable(hcx, hasher); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might be able to use one of the macros since this is just a struct now.
impl<'a, 'tcx> Place<'tcx> { | ||
// projection lives in the last elem. | ||
pub fn projection(&self) -> Option<&PlaceElem> { | ||
self.elems.last() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO such a method is a hazard. All users should iterate over the elems
vector.
There was a problem hiding this comment.
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 agree with "hazard", but I think a name like last_projection
would be good. Also, can the return type be Option<&'tcx PlaceElem>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a hazard to me as well. Better naming would help here, but I don’t see any reason against just inspecting the slice in-place.
src/librustc/mir/mod.rs
Outdated
) -> Self { | ||
Place { | ||
base: self.base, | ||
elems: tcx.intern_place_elems(&[elem]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This replaces the current elems
- it should instead have elem
at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit.
The builder pattern used here suggests that the Place
should be built up incrementally, but it seems to me that it would unnecessarily intern every single intermediate projection. That is, the code currently does not expose any way to construct the whole projection in one go, so one would end up doing something along the lines of
let place = Place::local(x);
let place = place.such_projection(...);
let place = place.another_projection(...);
...
and thus having every slice for each intermediate projection interned. Not sure if this is a relevant problem or whether the current code would be able to take advantage of a one-shot method, though.
ProjectionElem::Subslice { from, to } => { | ||
write!(fmt, "{:?}[{:?}:-{:?}]", data.base, from, to) | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to move this in a custom Debug
impl for Place
.
src/librustc/mir/mod.rs
Outdated
@@ -1731,7 +1737,7 @@ pub struct Projection<'tcx, B, V, T> { | |||
pub elem: ProjectionElem<'tcx, V, T>, | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Projection
struct should be removed.
// | ||
// Place: base.[] | ||
// ^^-- no projection | ||
// ^^^^-- PlaceTy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is inaccurate, it's only applying .c
but you also have .a
and .b
to apply before.
src/librustc/mir/tcx.rs
Outdated
// if no projection returns the place itself, | ||
// Base.[] => Base.[] | ||
// ^^-- no projection | ||
pub fn base_place<'cx, 'gcx>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a bad idea, because of inefficiency - you should be able to rewrite all the algorithms to work on [PlaceElem]
instead of the recursive data structure.
@csmoe It seems that there needs to be a bit more work put into avoiding looking at only the last projection element (previously recursive algorithms should now be iterative). |
match place.base { | ||
PlaceBase::Promoted(_) | ||
| PlaceBase::Static(..) => false, | ||
PlaceBase::Local(..) => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eddyb there are plenty of such pattern-match
s on old_place
, I'm a bit uncertain this translation, is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
borrow_of_local_data
is a recursive function, which means you can make it iterate over the elems
.
Furthermore, in this case specifically, if you made it iterative, you'd notice that the elems
don't change at all whether the function returns true
or false
, it just needs to look at the base.
src/librustc/mir/mod.rs
Outdated
} | ||
|
||
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> { | ||
self.elem(ProjectionElem::Downcast(adt_def, variant_index)) | ||
pub fn deref(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be tcx: TyCtxt<'_, '_, 'tcx>
src/librustc/mir/mod.rs
Outdated
Place::Projection(Box::new(PlaceProjection { base: self, elem })) | ||
pub fn elem( | ||
self, | ||
tcx: TyCtxt<'a, 'tcx, 'tcx>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and here...etc
ed44737
to
2dc5b86
Compare
} else { | ||
false | ||
}, | ||
"Unexpected capture place", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm currently getting a failure here, and I think it's because this code is not really equivalent to the old code. I think this is where a split_projection
sort of thing would be useful. In any case, the problem here I believe:
If you have something like *x.f
-- this has a tree structure like:
- deref
- field (
f
)- base:
x
- base:
- field (
but in the code here we will pull off the last projection (*
) and then look at arg_place.base
, which is x
, ignoring the field f
that comes in between.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this seems right, though as I wrote -- I would avoid the massive closure and instead have a proper fn
.
}) | ||
}) | ||
} | ||
let place_elements_conflict = |tcx: TyCtxt<'_, 'gcx, 'tcx>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, stylistically, I would prefer to keep this as a separate function. I really dislike large closures -- it's hard to distinguish what state they access from the surrounding environment.
if layout.is_llvm_immediate() || layout.is_llvm_scalar_pair() { | ||
// Recurse with the same context, instead of `Projection`, | ||
// potentially stopping at non-operand projections, | ||
// which would trigger `not_ssa` on locals. | ||
self.visit_place(&proj.base, context, location); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikomatsakis how can I rewrite this self-recursive block in iteration? I suspect my continue
rewriting is very incorrect.
closing as this PR appears to have been superseded by PR #54426 |
#Closes #52708
r? @nikomatsakis