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

Disallow mutable borrow to non-mut statics #47543

Merged
merged 1 commit into from
Feb 6, 2018

Conversation

topecongiro
Copy link
Contributor

Closes #42344.

@rust-highfive
Copy link
Collaborator

r? @eddyb

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

@topecongiro
Copy link
Contributor Author

Hmm, I just realized that when nll is enabled, the error message is slightly different.
Is this acceptable?

with nll

error[E0596]: cannot borrow immutable item `*TAB[..]` as mutable
  --> test.rs:16:5
   |
16 |     TAB[0].iter_mut();
   |     ^^^^^^ cannot borrow as mutable
   |
   = note: Value not mutable causing this error: `TAB`

error: aborting due to previous error

without nll

error[E0596]: cannot borrow borrowed content of mutable binding as mutable
  --> test.rs:14:5
   |
14 |     TAB[0].iter_mut();
   |     ^^^^^^ cannot borrow as mutable

error: aborting due to previous error

@eddyb
Copy link
Member

eddyb commented Jan 18, 2018

r? @nikomatsakis

@rust-highfive rust-highfive assigned nikomatsakis and unassigned eddyb Jan 18, 2018
@nikomatsakis
Copy link
Contributor

@topecongiro that's acceptable, it's a separate issue

@nikomatsakis
Copy link
Contributor

tbh, though, I find the MIR borrowck error much easier to understand =)

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.

Thanks! =)

@@ -233,7 +233,17 @@ fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
cmt,
code: err_mutbl }))
} else {
Ok(())
match cmt.maybe_static_mutability() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Something about this check doesn't feel right. There is a specific check that is supposed to guarantee that the reference is not an "aliasable" location, and it seems to be going awry, but I feel like we should be fixing that check, and not adding a new one. This is the check I am talking about:

/// Implements the A-* rules in README.md.
fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
borrow_span: Span,
loan_cause: AliasableViolationKind,
cmt: mc::cmt<'tcx>,
req_kind: ty::BorrowKind)
-> Result<(),()> {
let aliasability = cmt.freely_aliasable();
debug!("check_aliasability aliasability={:?} req_kind={:?}",
aliasability, req_kind);
match (aliasability, req_kind) {
(mc::Aliasability::NonAliasable, _) => {
/* Uniquely accessible path -- OK for `&` and `&mut` */
Ok(())
}
(mc::Aliasability::FreelyAliasable(mc::AliasableStatic), ty::ImmBorrow) => {
// Borrow of an immutable static item.
Ok(())
}
(mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut), _) => {
// Even touching a static mut is considered unsafe. We assume the
// user knows what they're doing in these cases.
Ok(())
}
(mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) |
(mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => {
bccx.report_aliasability_violation(
borrow_span,
loan_cause,
alias_cause,
cmt);
Err(())
}
(..) => {
Ok(())
}
}
}

Can you maybe tell me what the cmt is in this case, and what the value of aliasability is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The cmt is

cmt=cmt_ {
        id: NodeId(16),
        span: test.rs:13:5: 13:11,
        cat: Deref(cmt_ {
            id: NodeId(16),
            span: test.rs:13:5: 13:11,
            cat: Interior(cmt_ {
                id: NodeId(14),
                span: test.rs:13:5: 13:8,
                cat: StaticItem,
                mutbl: McImmutable,
                ty: [&'static mut [u8]; 0],
                note: NoteNone,
            }, []),
            mutbl: McImmutable,
            ty: &'static mut [u8],
            note: NoteNone,
        }, BorrowedPtr(MutBorrow, ReStatic)),
        mutbl: McDeclared,
        ty: [u8],
        note: NoteNone
    }

and the value of aliasability is

aliasability=FreelyAliasable(AliasableStatic)

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, so I wonder in that case why this code:

(mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) |
(mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => {
bccx.report_aliasability_violation(
borrow_span,
loan_cause,
alias_cause,
cmt);
Err(())
}

doesn't execute... req_kind is ty::MutBorrow, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is because check_mutability triggers an error, and check_aliasability is no called at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh. So how come I don't see an error reporting in the original issue #42344? I see the ICE -- where does that ICE occur?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, were you asking about the behavior of the original rustc? I was talking about how rustc bahaves when this PR was applied. I am sorry for the confusion.

Using the master branch, yes, req_kind is ty::MutBorrow, and bccx.report_aliasability_violation is executed. The following error is reported.

error: internal compiler error: aliasability violation for static `cannot borrow data mutably`
 --> test.rs:3:5
  |
3 |     TAB[0].iter_mut();
  |     ^^^^^^

error: aborting due to previous error

Copy link
Contributor

Choose a reason for hiding this comment

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

@topecongiro ah, I see -- actually, I think that the delay_span_bug is just wrong and should be removed. The logic was that a case like static X: u32 = 2; &mut X should not reach there (and indeed I think it won't) -- but it overlooked the possibility of an &mut living in a static.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you update this PR to just remove the delay_span_bug call for AliasabilityReason::Static?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure! Thank your for your patience with my slow updates.

@shepmaster shepmaster added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 20, 2018
@shepmaster
Copy link
Member

Ping from triage, @topecongiro ! Will you be able to respond to the most recent set of feedback soon?

@shepmaster
Copy link
Member

Disallow mutable borrow to non-mut statics

I got excited and thought this fixed #46557 😝

@topecongiro
Copy link
Contributor Author

Oops, I missed the notification of review by @nikomatsakis. Sorry!

I will work on this today at some point.

@nikomatsakis
Copy link
Contributor

@topecongiro left another question :)

This path was considered to be unreachable. However,
`&mut` could potentially live inside `static`.
For example, `static TAB: [&mut [u8]; 0] = [];`.
@nikomatsakis
Copy link
Contributor

@bors r+

Nice =)

@bors
Copy link
Contributor

bors commented Feb 5, 2018

📌 Commit 3d114c7 has been approved by nikomatsakis

kennytm added a commit to kennytm/rust that referenced this pull request Feb 5, 2018
…akis

Disallow mutable borrow to non-mut statics

Closes rust-lang#42344.
bors added a commit that referenced this pull request Feb 6, 2018
Rollup of 10 pull requests

- Successful merges: #46030, #47496, #47543, #47704, #47753, #47807, #47948, #47959, #48003, #48007
- Failed merges:
@bors bors merged commit 3d114c7 into rust-lang:master Feb 6, 2018
@topecongiro topecongiro deleted the issue-42344 branch February 6, 2018 15:18
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.

6 participants