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

MIR-borrowck: add permisson checks to fn access_lvalue #45436

Merged
merged 3 commits into from
Nov 14, 2017

Conversation

zilbuz
Copy link
Contributor

@zilbuz zilbuz commented Oct 21, 2017

Fix #44837

@rust-highfive
Copy link
Collaborator

r? @pnkfelix

(rust_highfive has picked a reviewer for you, use r? to override)

@kennytm kennytm added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Oct 22, 2017
@carols10cents
Copy link
Member

Triage ping @zilbuz! How's it going? Have any questions/need any help?

@bors
Copy link
Contributor

bors commented Nov 1, 2017

☔ The latest upstream changes (presumably #45538) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis
Copy link
Contributor

r? @nikomatsakis

@zilbuz zilbuz force-pushed the issue-44837 branch 2 times, most recently from 7424113 to 4652b33 Compare November 12, 2017 11:44
fn check_access_permissions(&self, (lvalue, span): (&Lvalue<'tcx>, Span), kind: ReadOrWrite) {
match kind {
Write(WriteKind::MutableBorrow(BorrowKind::Unique))
| Write(WriteKind::MutableBorrow(BorrowKind::Mut)) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: the | goes at the end of the line before under typical style.

ty::TyRef(_, tnm) => {
match tnm.mutbl {
// lvalue represent an aliased location
hir::MutImmutable => Err(lvalue),
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, it appears we do allow the use of &mut there. This example compiles:

fn foo(x: *const &mut u32) {
  unsafe {
    **x += 1;
  }
}

fn main() { }

Copy link
Contributor

Choose a reason for hiding this comment

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

So I was wrong in my writeup, we should just treat *const the same as *mut.

Copy link
Contributor

Choose a reason for hiding this comment

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

Er, I meant this for the raw pointer cases below, sorry =) comment on wrong line

/// Check the permissions for the given lvalue and read or write kind
fn check_access_permissions(&self, (lvalue, span): (&Lvalue<'tcx>, Span), kind: ReadOrWrite) {
match kind {
Write(WriteKind::MutableBorrow(BorrowKind::Unique))
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm I forgot about unique borrows when writing up those rules. They have a different set of conditions than mutable borrows. I think that this actually lines up perfectly with what I called can_host_mutable_ref, which we could perhaps just call is_unique. I forget why I changed it from that name. We should just call it is_unique, and then check that Write(WriteKind::MutableBorrow(BorrowKind::Unique)) requires is_unique.

ty::TyRawPtr(tnm) => {
match tnm.mutbl {
// `*const` is assumed to be aliasable
hir::MutImmutable => Err(lvalue),
Copy link
Contributor

Choose a reason for hiding this comment

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

That is, this should be Ok(()).

}
},
// Other projections are unique if the base is unique
_ => self.can_host_mutable_ref(&proj.base)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer to avoid the _ here and instead just write out all the cases explicitly. _ makes it much harder to audit. My usual rule is something like this:

  • If a new case were added to ProjectionKind, what is the chance that this match would be affected?

I'd say "pretty high", therefore we should avoid _.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I use bug!("Deref of unexpected type") here? Like in is_mutable()?

Copy link
Contributor

Choose a reason for hiding this comment

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

sounds good

}
},
// Other projections are unique if the base is unique
_ => self.can_host_mutable_ref(&proj.base)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here: avoid _

| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => Err(lvalue),
// In general we can move from owned content if owner is mobile
_ => self.is_mobile(&proj.base)
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid _ here too.

// dynamic drop elaboration
ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => Err(lvalue),
Copy link
Contributor

Choose a reason for hiding this comment

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

Style nit: | at end.

},
// All other projections are owned by their base path, so mutable if
// base path is mutable
_ => self.is_mutable(&proj.base)
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid _ here (see other comments for rationale).

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, in this particular case, I think we could keep the _, but write bug!("deref of unexpected type: {:?}", base_ty) -- deref should (I believe) only be for &T, *const T, or Box<T>.

},
// All other projections are owned by their base path, so mutable if
// base path is mutable
_ => self.is_mutable(&proj.base)
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid _ here (see other comments for rationale).

let local = &self.mir.local_decls[local];
if local.mutability == Mutability::Not {
Err(lvalue)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Style nit: we usually write } else {

match *lvalue {
Lvalue::Local(local) => {
let local = &self.mir.local_decls[local];
if local.mutability == Mutability::Not {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer an (exhaustive) match here, which makes it obvious that we've covered every case. I would say that we should keep if for booleans.

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.

Great! I left a bunch of comments, but they are mostly style nits.

@zilbuz zilbuz changed the title [WIP] MIR-borrowck: add permisson checks to fn access_lvalue MIR-borrowck: add permisson checks to fn access_lvalue Nov 13, 2017
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Nov 13, 2017

📌 Commit cbad2e5 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Nov 13, 2017

⌛ Testing commit cbad2e5 with merge 212d74f...

bors added a commit that referenced this pull request Nov 13, 2017
MIR-borrowck: add permisson checks to `fn access_lvalue`

WIP : Some FIXME left and some broken tests.

Fix #44837
@bors
Copy link
Contributor

bors commented Nov 14, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 212d74f to master...

@bors bors merged commit cbad2e5 into rust-lang:master Nov 14, 2017
@zilbuz zilbuz deleted the issue-44837 branch November 16, 2017 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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