mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 15:54:15 +00:00
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 ```
This commit is contained in:
commit
99fc56b9de
@ -8,6 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{is_range_literal, Node};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
|
||||
use rustc_span::symbol::sym;
|
||||
@ -412,14 +413,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> Option<(Span, &'static str, String, Applicability)> {
|
||||
let sm = self.sess().source_map();
|
||||
let sess = self.sess();
|
||||
let sp = expr.span;
|
||||
if sm.is_imported(sp) {
|
||||
// Ignore if span is from within a macro #41858, #58298. We previously used the macro
|
||||
// call span, but that breaks down when the type error comes from multiple calls down.
|
||||
|
||||
// If the span is from an external macro, there's no suggestion we can make.
|
||||
if in_external_macro(sess, sp) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let sm = sess.source_map();
|
||||
|
||||
let replace_prefix = |s: &str, old: &str, new: &str| {
|
||||
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
|
||||
};
|
||||
@ -427,10 +430,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let is_struct_pat_shorthand_field =
|
||||
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, sp);
|
||||
|
||||
// If the span is from a macro, then it's hard to extract the text
|
||||
// and make a good suggestion, so don't bother.
|
||||
let is_macro = sp.from_expansion() && sp.desugaring_kind().is_none();
|
||||
|
||||
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
|
||||
let expr = expr.peel_drop_temps();
|
||||
|
||||
@ -570,10 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
||||
_,
|
||||
&ty::Ref(_, checked, _),
|
||||
) if {
|
||||
self.infcx.can_sub(self.param_env, checked, &expected).is_ok() && !is_macro
|
||||
} =>
|
||||
{
|
||||
) if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() => {
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest removing a `&`.
|
||||
if sm.is_imported(expr.span) {
|
||||
@ -589,13 +585,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
return Some((
|
||||
sp,
|
||||
"consider removing the borrow",
|
||||
code,
|
||||
Applicability::MachineApplicable,
|
||||
));
|
||||
if sp.contains(expr.span) {
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
return Some((
|
||||
sp,
|
||||
"consider removing the borrow",
|
||||
code,
|
||||
Applicability::MachineApplicable,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
(
|
||||
@ -643,7 +641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if sp == expr.span && !is_macro => {
|
||||
_ if sp == expr.span => {
|
||||
if let Some(steps) = self.deref_steps(checked_ty, expected) {
|
||||
let expr = expr.peel_blocks();
|
||||
|
||||
|
18
src/test/ui/suggestions/auxiliary/proc-macro-type-error.rs
Normal file
18
src/test/ui/suggestions/auxiliary/proc-macro-type-error.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro_quote)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::{quote, TokenStream};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn hello(_: TokenStream, _: TokenStream) -> TokenStream {
|
||||
quote!(
|
||||
fn f(_: &mut i32) {}
|
||||
fn g() {
|
||||
f(123);
|
||||
}
|
||||
)
|
||||
}
|
29
src/test/ui/suggestions/suggest-ref-macro.rs
Normal file
29
src/test/ui/suggestions/suggest-ref-macro.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// run-check
|
||||
// aux-build:proc-macro-type-error.rs
|
||||
|
||||
extern crate proc_macro_type_error;
|
||||
|
||||
use proc_macro_type_error::hello;
|
||||
|
||||
#[hello] //~ERROR mismatched types
|
||||
fn abc() {}
|
||||
|
||||
fn x(_: &mut i32) {}
|
||||
|
||||
macro_rules! bla {
|
||||
() => {
|
||||
x(123);
|
||||
//~^ ERROR mismatched types
|
||||
//~| SUGGESTION &mut 123
|
||||
};
|
||||
($v:expr) => {
|
||||
x($v)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bla!();
|
||||
bla!(456);
|
||||
//~^ ERROR mismatched types
|
||||
//~| SUGGESTION &mut 456
|
||||
}
|
34
src/test/ui/suggestions/suggest-ref-macro.stderr
Normal file
34
src/test/ui/suggestions/suggest-ref-macro.stderr
Normal file
@ -0,0 +1,34 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-ref-macro.rs:8:1
|
||||
|
|
||||
LL | #[hello]
|
||||
| ^^^^^^^^ expected `&mut i32`, found integer
|
||||
|
|
||||
= note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-ref-macro.rs:15:11
|
||||
|
|
||||
LL | x(123);
|
||||
| ^^^
|
||||
| |
|
||||
| expected `&mut i32`, found integer
|
||||
| help: consider mutably borrowing here: `&mut 123`
|
||||
...
|
||||
LL | bla!();
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-ref-macro.rs:26:10
|
||||
|
|
||||
LL | bla!(456);
|
||||
| ^^^
|
||||
| |
|
||||
| expected `&mut i32`, found integer
|
||||
| help: consider mutably borrowing here: `&mut 456`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user