diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 03717a4d654..2deb18484ec 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -516,6 +516,17 @@ pub fn disable_suggestions(&mut self) -> &mut Self { /// Helper for pushing to `self.suggestions`, if available (not disable). fn push_suggestion(&mut self, suggestion: CodeSuggestion) { + for subst in &suggestion.substitutions { + for part in &subst.parts { + let span = part.span; + let call_site = span.ctxt().outer_expn_data().call_site; + if span.in_derive_expansion() && span.overlaps_or_adjacent(call_site) { + // Ignore if spans is from derive macro. + return; + } + } + } + if let Ok(suggestions) = &mut self.suggestions { suggestions.push(suggestion); } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 7d95a0bc478..49ae9f16c8e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -625,6 +625,13 @@ pub fn overlaps(self, other: Span) -> bool { span.lo < other.hi && other.lo < span.hi } + /// Returns `true` if `self` touches or adjoins `other`. + pub fn overlaps_or_adjacent(self, other: Span) -> bool { + let span = self.data(); + let other = other.data(); + span.lo <= other.hi && other.lo <= span.hi + } + /// Returns `true` if the spans are equal with regards to the source text. /// /// Use this instead of `==` when either span could be generated code, diff --git a/tests/ui/proc-macro/auxiliary/issue-118809.rs b/tests/ui/proc-macro/auxiliary/issue-118809.rs new file mode 100644 index 00000000000..029b58c6d0c --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/issue-118809.rs @@ -0,0 +1,20 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Deserialize)] +pub fn deserialize_derive(input: TokenStream) -> TokenStream { + "impl Build { + fn deserialize() -> Option { + let x: Option = Some(0); + Some(x? + 1) + } + } + " + .parse() + .unwrap() +} diff --git a/tests/ui/proc-macro/issue-118809.rs b/tests/ui/proc-macro/issue-118809.rs new file mode 100644 index 00000000000..732bf19c173 --- /dev/null +++ b/tests/ui/proc-macro/issue-118809.rs @@ -0,0 +1,10 @@ +// aux-build: issue-118809.rs + +#[macro_use] +extern crate issue_118809; + +#[derive(Deserialize)] //~ ERROR mismatched types [E0308] +pub struct Build { +} + +fn main() {} diff --git a/tests/ui/proc-macro/issue-118809.stderr b/tests/ui/proc-macro/issue-118809.stderr new file mode 100644 index 00000000000..30b09fd4006 --- /dev/null +++ b/tests/ui/proc-macro/issue-118809.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-118809.rs:6:10 + | +LL | #[derive(Deserialize)] + | ^^^^^^^^^^^ + | | + | expected `u64`, found `u32` + | arguments to this enum variant are incorrect + | +help: the type constructed contains `u32` due to the type of the argument passed + --> $DIR/issue-118809.rs:6:10 + | +LL | #[derive(Deserialize)] + | ^^^^^^^^^^^ this argument influences the type of `Some` +note: tuple variant defined here + --> $SRC_DIR/core/src/option.rs:LL:COL + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.