Skip to content

Commit 34e6075

Browse files
authored
Rollup merge of #134244 - Enselic:no-mut-hint-for-raw-ref, r=jieyouxu
rustc_borrowck: Stop suggesting the invalid syntax `&mut raw const` A legitimate suggestion would be to change from &raw const val to &raw mut val But until we have figured out how to make that happen we should at least stop suggesting invalid syntax. I recommend review commit-by-commit. Part of #127562
2 parents a53a3cc + f6cb227 commit 34e6075

File tree

3 files changed

+70
-16
lines changed

3 files changed

+70
-16
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+53-16
Original file line numberDiff line numberDiff line change
@@ -1100,12 +1100,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11001100
}
11011101
let decl_span = local_decl.source_info.span;
11021102

1103-
let label = match *local_decl.local_info() {
1103+
let amp_mut_sugg = match *local_decl.local_info() {
11041104
LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
11051105
let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
11061106
let additional =
11071107
local_trait.map(|span| (span, suggest_ampmut_self(self.infcx.tcx, span)));
1108-
Some((true, decl_span, suggestion, additional))
1108+
Some(AmpMutSugg { has_sugg: true, span: decl_span, suggestion, additional })
11091109
}
11101110

11111111
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
@@ -1150,7 +1150,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11501150
None
11511151
}
11521152
None => {
1153-
let (has_sugg, decl_span, sugg) = if name != kw::SelfLower {
1153+
if name != kw::SelfLower {
11541154
suggest_ampmut(
11551155
self.infcx.tcx,
11561156
local_decl.ty,
@@ -1165,7 +1165,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11651165
..
11661166
})) => {
11671167
let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
1168-
(true, decl_span, sugg)
1168+
Some(AmpMutSugg {
1169+
has_sugg: true,
1170+
span: decl_span,
1171+
suggestion: sugg,
1172+
additional: None,
1173+
})
11691174
}
11701175
// explicit self (eg `self: &'a Self`)
11711176
_ => suggest_ampmut(
@@ -1176,8 +1181,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11761181
opt_ty_info,
11771182
),
11781183
}
1179-
};
1180-
Some((has_sugg, decl_span, sugg, None))
1184+
}
11811185
}
11821186
}
11831187
}
@@ -1187,15 +1191,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11871191
..
11881192
})) => {
11891193
let pattern_span: Span = local_decl.source_info.span;
1190-
suggest_ref_mut(self.infcx.tcx, pattern_span)
1191-
.map(|span| (true, span, "mut ".to_owned(), None))
1194+
suggest_ref_mut(self.infcx.tcx, pattern_span).map(|span| AmpMutSugg {
1195+
has_sugg: true,
1196+
span,
1197+
suggestion: "mut ".to_owned(),
1198+
additional: None,
1199+
})
11921200
}
11931201

11941202
_ => unreachable!(),
11951203
};
11961204

1197-
match label {
1198-
Some((true, err_help_span, suggested_code, additional)) => {
1205+
match amp_mut_sugg {
1206+
Some(AmpMutSugg {
1207+
has_sugg: true,
1208+
span: err_help_span,
1209+
suggestion: suggested_code,
1210+
additional,
1211+
}) => {
11991212
let mut sugg = vec![(err_help_span, suggested_code)];
12001213
if let Some(s) = additional {
12011214
sugg.push(s);
@@ -1217,7 +1230,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12171230
);
12181231
}
12191232
}
1220-
Some((false, err_label_span, message, _)) => {
1233+
Some(AmpMutSugg {
1234+
has_sugg: false, span: err_label_span, suggestion: message, ..
1235+
}) => {
12211236
let def_id = self.body.source.def_id();
12221237
let hir_id = if let Some(local_def_id) = def_id.as_local()
12231238
&& let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
@@ -1422,6 +1437,13 @@ fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
14221437
}
14231438
}
14241439

1440+
struct AmpMutSugg {
1441+
has_sugg: bool,
1442+
span: Span,
1443+
suggestion: String,
1444+
additional: Option<(Span, String)>,
1445+
}
1446+
14251447
// When we want to suggest a user change a local variable to be a `&mut`, there
14261448
// are three potential "obvious" things to highlight:
14271449
//
@@ -1443,7 +1465,7 @@ fn suggest_ampmut<'tcx>(
14431465
decl_span: Span,
14441466
opt_assignment_rhs_span: Option<Span>,
14451467
opt_ty_info: Option<Span>,
1446-
) -> (bool, Span, String) {
1468+
) -> Option<AmpMutSugg> {
14471469
// if there is a RHS and it starts with a `&` from it, then check if it is
14481470
// mutable, and if not, put suggest putting `mut ` to make it mutable.
14491471
// we don't have to worry about lifetime annotations here because they are
@@ -1456,6 +1478,11 @@ fn suggest_ampmut<'tcx>(
14561478
&& let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
14571479
&& let Some(stripped) = src.strip_prefix('&')
14581480
{
1481+
let is_raw_ref = stripped.trim_start().starts_with("raw ");
1482+
// We don't support raw refs yet
1483+
if is_raw_ref {
1484+
return None;
1485+
}
14591486
let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
14601487
match rest.chars().next() {
14611488
// e.g. `&mut x`
@@ -1479,7 +1506,12 @@ fn suggest_ampmut<'tcx>(
14791506

14801507
// FIXME(Ezrashaw): returning is bad because we still might want to
14811508
// update the annotated type, see #106857.
1482-
return (true, span, "mut ".to_owned());
1509+
return Some(AmpMutSugg {
1510+
has_sugg: true,
1511+
span,
1512+
suggestion: "mut ".to_owned(),
1513+
additional: None,
1514+
});
14831515
}
14841516
}
14851517

@@ -1504,18 +1536,23 @@ fn suggest_ampmut<'tcx>(
15041536
&& let Some(ws_pos) = src.find(char::is_whitespace)
15051537
{
15061538
let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
1507-
(true, span, " mut".to_owned())
1539+
Some(AmpMutSugg { has_sugg: true, span, suggestion: " mut".to_owned(), additional: None })
15081540
// if there is already a binding, we modify it to be `mut`
15091541
} else if binding_exists {
15101542
// shrink the span to just after the `&` in `&variable`
15111543
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
1512-
(true, span, "mut ".to_owned())
1544+
Some(AmpMutSugg { has_sugg: true, span, suggestion: "mut ".to_owned(), additional: None })
15131545
} else {
15141546
// otherwise, suggest that the user annotates the binding; we provide the
15151547
// type of the local.
15161548
let ty = decl_ty.builtin_deref(true).unwrap();
15171549

1518-
(false, span, format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty))
1550+
Some(AmpMutSugg {
1551+
has_sugg: false,
1552+
span,
1553+
suggestion: format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty),
1554+
additional: None,
1555+
})
15191556
}
15201557
}
15211558

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//! Regression test for invalid suggestion for `&raw const expr` reported in
2+
//! <https://github.com/rust-lang/rust/issues/127562>.
3+
4+
fn main() {
5+
let val = 2;
6+
let ptr = &raw const val;
7+
unsafe { *ptr = 3; } //~ ERROR cannot assign to `*ptr`, which is behind a `*const` pointer
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0594]: cannot assign to `*ptr`, which is behind a `*const` pointer
2+
--> $DIR/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs:7:14
3+
|
4+
LL | unsafe { *ptr = 3; }
5+
| ^^^^^^^^ `ptr` is a `*const` pointer, so the data it refers to cannot be written
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0594`.

0 commit comments

Comments
 (0)