-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
Hmm, I just realized that when nll is enabled, the error message is slightly different. with nllerror[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 nllerror[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 |
@topecongiro that's acceptable, it's a separate issue |
tbh, though, I find the MIR borrowck error much easier to understand =) |
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.
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() { |
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.
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:
rust/src/librustc_borrowck/borrowck/gather_loans/mod.rs
Lines 164 to 203 in 5965b79
/// 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?
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 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)
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.
Huh, so I wonder in that case why this code:
rust/src/librustc_borrowck/borrowck/gather_loans/mod.rs
Lines 190 to 198 in 5965b79
(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?
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.
That is because check_mutability
triggers an error, and check_aliasability
is no called at all.
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.
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?
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.
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
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.
@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
.
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.
Can you update this PR to just remove the delay_span_bug
call for AliasabilityReason::Static
?
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.
Sure! Thank your for your patience with my slow updates.
Ping from triage, @topecongiro ! Will you be able to respond to the most recent set of feedback soon? |
I got excited and thought this fixed #46557 😝 |
Oops, I missed the notification of review by @nikomatsakis. Sorry! I will work on this today at some point. |
@topecongiro left another question :) |
9c26ca7
to
ce21516
Compare
This path was considered to be unreachable. However, `&mut` could potentially live inside `static`. For example, `static TAB: [&mut [u8]; 0] = [];`.
ce21516
to
3d114c7
Compare
@bors r+ Nice =) |
📌 Commit 3d114c7 has been approved by |
…akis Disallow mutable borrow to non-mut statics Closes rust-lang#42344.
Closes #42344.