Skip to content

Commit 99fc56b

Browse files
authored
Rollup merge of #85937 - m-ou-se:macro-ref-suggestions, r=estebank
Fix bad suggestions for code from proc_macro Fixes #85932 This disables these suggestions for spans from external macros, while keeping them for macros defined locally: Before: ``` 3 | #[hello] | ^^^^^^^^ | | | expected `&mut i32`, found integer | help: consider mutably borrowing here: `&mut #[hello]` ``` After: ``` 3 | #[hello] | ^^^^^^^^ expected `&mut i32`, found integer ``` Unchanged: ``` 26 | macro_rules! bla { () => { x(123); } } | ^^^ | | | expected `&mut i32`, found integer | help: consider mutably borrowing here: `&mut 123` ... 29 | bla!(); | ------- in this macro invocation ```
2 parents 5b0a49e + e735f60 commit 99fc56b

File tree

4 files changed

+99
-20
lines changed

4 files changed

+99
-20
lines changed

compiler/rustc_typeck/src/check/demand.rs

+18-20
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
88
use rustc_hir as hir;
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir::{is_range_literal, Node};
11+
use rustc_middle::lint::in_external_macro;
1112
use rustc_middle::ty::adjustment::AllowTwoPhase;
1213
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
1314
use rustc_span::symbol::sym;
@@ -412,25 +413,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
412413
checked_ty: Ty<'tcx>,
413414
expected: Ty<'tcx>,
414415
) -> Option<(Span, &'static str, String, Applicability)> {
415-
let sm = self.sess().source_map();
416+
let sess = self.sess();
416417
let sp = expr.span;
417-
if sm.is_imported(sp) {
418-
// Ignore if span is from within a macro #41858, #58298. We previously used the macro
419-
// call span, but that breaks down when the type error comes from multiple calls down.
418+
419+
// If the span is from an external macro, there's no suggestion we can make.
420+
if in_external_macro(sess, sp) {
420421
return None;
421422
}
422423

424+
let sm = sess.source_map();
425+
423426
let replace_prefix = |s: &str, old: &str, new: &str| {
424427
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
425428
};
426429

427430
let is_struct_pat_shorthand_field =
428431
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, sp);
429432

430-
// If the span is from a macro, then it's hard to extract the text
431-
// and make a good suggestion, so don't bother.
432-
let is_macro = sp.from_expansion() && sp.desugaring_kind().is_none();
433-
434433
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
435434
let expr = expr.peel_drop_temps();
436435

@@ -570,10 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
570569
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
571570
_,
572571
&ty::Ref(_, checked, _),
573-
) if {
574-
self.infcx.can_sub(self.param_env, checked, &expected).is_ok() && !is_macro
575-
} =>
576-
{
572+
) if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() => {
577573
// We have `&T`, check if what was expected was `T`. If so,
578574
// we may want to suggest removing a `&`.
579575
if sm.is_imported(expr.span) {
@@ -589,13 +585,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
589585
}
590586
return None;
591587
}
592-
if let Ok(code) = sm.span_to_snippet(expr.span) {
593-
return Some((
594-
sp,
595-
"consider removing the borrow",
596-
code,
597-
Applicability::MachineApplicable,
598-
));
588+
if sp.contains(expr.span) {
589+
if let Ok(code) = sm.span_to_snippet(expr.span) {
590+
return Some((
591+
sp,
592+
"consider removing the borrow",
593+
code,
594+
Applicability::MachineApplicable,
595+
));
596+
}
599597
}
600598
}
601599
(
@@ -643,7 +641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
643641
}
644642
}
645643
}
646-
_ if sp == expr.span && !is_macro => {
644+
_ if sp == expr.span => {
647645
if let Some(steps) = self.deref_steps(checked_ty, expected) {
648646
let expr = expr.peel_blocks();
649647

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
#![crate_type = "proc-macro"]
4+
#![feature(proc_macro_quote)]
5+
6+
extern crate proc_macro;
7+
8+
use proc_macro::{quote, TokenStream};
9+
10+
#[proc_macro_attribute]
11+
pub fn hello(_: TokenStream, _: TokenStream) -> TokenStream {
12+
quote!(
13+
fn f(_: &mut i32) {}
14+
fn g() {
15+
f(123);
16+
}
17+
)
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run-check
2+
// aux-build:proc-macro-type-error.rs
3+
4+
extern crate proc_macro_type_error;
5+
6+
use proc_macro_type_error::hello;
7+
8+
#[hello] //~ERROR mismatched types
9+
fn abc() {}
10+
11+
fn x(_: &mut i32) {}
12+
13+
macro_rules! bla {
14+
() => {
15+
x(123);
16+
//~^ ERROR mismatched types
17+
//~| SUGGESTION &mut 123
18+
};
19+
($v:expr) => {
20+
x($v)
21+
}
22+
}
23+
24+
fn main() {
25+
bla!();
26+
bla!(456);
27+
//~^ ERROR mismatched types
28+
//~| SUGGESTION &mut 456
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/suggest-ref-macro.rs:8:1
3+
|
4+
LL | #[hello]
5+
| ^^^^^^^^ expected `&mut i32`, found integer
6+
|
7+
= note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/suggest-ref-macro.rs:15:11
11+
|
12+
LL | x(123);
13+
| ^^^
14+
| |
15+
| expected `&mut i32`, found integer
16+
| help: consider mutably borrowing here: `&mut 123`
17+
...
18+
LL | bla!();
19+
| ------- in this macro invocation
20+
|
21+
= note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
22+
23+
error[E0308]: mismatched types
24+
--> $DIR/suggest-ref-macro.rs:26:10
25+
|
26+
LL | bla!(456);
27+
| ^^^
28+
| |
29+
| expected `&mut i32`, found integer
30+
| help: consider mutably borrowing here: `&mut 456`
31+
32+
error: aborting due to 3 previous errors
33+
34+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)