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] change how MIR represents places #53247

Closed
wants to merge 33 commits into from
Closed

Conversation

csmoe
Copy link
Member

@csmoe csmoe commented Aug 10, 2018

#Closes #52708
r? @nikomatsakis

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 10, 2018
@nikomatsakis
Copy link
Contributor

cc @eddyb as well

hasher: &mut StableHasher<W>,
) {
self.base.hash_stable(hcx, hasher);
self.elems.hash_stable(hcx, hasher);
Copy link
Member

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()
Copy link
Member

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.

Copy link
Contributor

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>?

Copy link
Member

@nagisa nagisa Aug 11, 2018

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.

) -> Self {
Place {
base: self.base,
elems: tcx.intern_place_elems(&[elem]),
Copy link
Member

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.

Copy link
Member

@nagisa nagisa Aug 11, 2018

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)
}
},
Copy link
Member

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.

@@ -1731,7 +1737,7 @@ pub struct Projection<'tcx, B, V, T> {
pub elem: ProjectionElem<'tcx, V, T>,
}
Copy link
Member

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
Copy link
Member

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.

// if no projection returns the place itself,
// Base.[] => Base.[]
// ^^-- no projection
pub fn base_place<'cx, 'gcx>(
Copy link
Member

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.

@eddyb
Copy link
Member

eddyb commented Aug 10, 2018

@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,
Copy link
Member Author

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-matchs on old_place, I'm a bit uncertain this translation, is this correct?

Copy link
Member

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.

}

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 {
Copy link
Contributor

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>

Place::Projection(Box::new(PlaceProjection { base: self, elem }))
pub fn elem(
self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
Copy link
Contributor

Choose a reason for hiding this comment

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

...and here...etc

@csmoe csmoe force-pushed the place branch 4 times, most recently from ed44737 to 2dc5b86 Compare August 22, 2018 03:05
@memoryruins memoryruins added the A-NLL Area: Non Lexical Lifetimes (NLL) label Aug 28, 2018
} else {
false
},
"Unexpected capture place",
Copy link
Contributor

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

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.

Copy link
Contributor

@nikomatsakis nikomatsakis left a 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>,
Copy link
Contributor

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;
Copy link
Member Author

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.

@pnkfelix
Copy link
Member

closing as this PR appears to have been superseded by PR #54426

@pnkfelix pnkfelix closed this Sep 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants