Skip to content

Commit b73cdf1

Browse files
committed
special case removing & suggestion
1 parent ca1178f commit b73cdf1

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

compiler/rustc_hir/src/hir.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,14 @@ impl Expr<'_> {
17871787
expr
17881788
}
17891789

1790+
pub fn peel_borrows(&self) -> &Self {
1791+
let mut expr = self;
1792+
while let ExprKind::AddrOf(.., inner) = &expr.kind {
1793+
expr = inner;
1794+
}
1795+
expr
1796+
}
1797+
17901798
pub fn can_have_side_effects(&self) -> bool {
17911799
match self.peel_drop_temps().kind {
17921800
ExprKind::Path(_) | ExprKind::Lit(_) => false,

compiler/rustc_hir_typeck/src/cast.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use super::FnCtxt;
3232

3333
use crate::type_error_struct;
34+
use hir::ExprKind;
3435
use rustc_errors::{
3536
struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
3637
};
@@ -237,12 +238,23 @@ impl<'a, 'tcx> CastCheck<'tcx> {
237238
fcx,
238239
);
239240

240-
err.span_suggestion_verbose(
241-
self.expr_span.shrink_to_lo(),
242-
"dereference the expression",
243-
"*",
244-
Applicability::MachineApplicable,
245-
);
241+
if matches!(self.expr.kind, ExprKind::AddrOf(..)) {
242+
// get just the borrow part of the expression
243+
let span = self.expr_span.with_hi(self.expr.peel_borrows().span.lo());
244+
err.span_suggestion_verbose(
245+
span,
246+
"remove the unneeded borrow",
247+
"",
248+
Applicability::MachineApplicable,
249+
);
250+
} else {
251+
err.span_suggestion_verbose(
252+
self.expr_span.shrink_to_lo(),
253+
"dereference the expression",
254+
"*",
255+
Applicability::MachineApplicable,
256+
);
257+
}
246258

247259
err.emit();
248260
}

tests/ui/error-codes/E0606.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
fn main() {
2-
&0u8 as u8; //~ ERROR E0606
2+
let x = &(&0u8 as u8); //~ ERROR E0606
3+
x as u8; //~ casting `&u8` as `u8` is invalid [E0606]
34
}

tests/ui/error-codes/E0606.stderr

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
error[E0606]: casting `&u8` as `u8` is invalid
2-
--> $DIR/E0606.rs:2:5
2+
--> $DIR/E0606.rs:2:14
33
|
4-
LL | &0u8 as u8;
5-
| ^^^^^^^^^^
4+
LL | let x = &(&0u8 as u8);
5+
| ^^^^^^^^^^^^
6+
|
7+
help: remove the unneeded borrow
8+
|
9+
LL - let x = &(&0u8 as u8);
10+
LL + let x = &(0u8 as u8);
11+
|
12+
13+
error[E0606]: casting `&u8` as `u8` is invalid
14+
--> $DIR/E0606.rs:3:5
15+
|
16+
LL | x as u8;
17+
| ^^^^^^^
618
|
719
help: dereference the expression
820
|
9-
LL | *&0u8 as u8;
21+
LL | *x as u8;
1022
| +
1123

12-
error: aborting due to previous error
24+
error: aborting due to 2 previous errors
1325

1426
For more information about this error, try `rustc --explain E0606`.

0 commit comments

Comments
 (0)