Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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