diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 221df4e36b296..d44e5aa2e77e8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -186,8 +186,18 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( let params = generics.map(|g| g.params).unwrap_or_default(); let type_name = params.next_type_param_name(None); + + let mut placeholder_spans: Vec = vec![]; + for span in &placeholder_types { + if placeholder_spans.iter().any(|sp| sp.source_equal(*span)) { + continue; + } else { + placeholder_spans.push(*span); + } + } + let mut sugg: Vec<_> = - placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect(); + placeholder_spans.iter().map(|sp| (*sp, (*type_name).to_string())).collect(); if let Some(generics) = generics { if let Some(arg) = params.iter().find(|arg| { diff --git a/tests/ui/errors/issue-116502-span-error.rs b/tests/ui/errors/issue-116502-span-error.rs new file mode 100644 index 0000000000000..556c7568abad1 --- /dev/null +++ b/tests/ui/errors/issue-116502-span-error.rs @@ -0,0 +1,42 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +macro_rules! Tuple { + { $A:ty,$B:ty } => { ($A, $B) } +} + +fn main() { + let x: Tuple!(i32, i32) = (1, 2); +} + +fn issue_36540() { + let _ = 0; + macro_rules! m { + () => { + _ + //~^ ERROR in expressions + //~| ERROR in expressions + //~| ERROR the placeholder `_` is not allowed + //~| ERROR the placeholder `_` is not allowed + //~| ERROR the placeholder `_` is not allowed + //~| ERROR the placeholder `_` is not allowed + }; + } + struct S(m!(), T) + where + T: Trait; + + let x: m!() = m!(); + std::cell::Cell::::new(m!()); + impl std::ops::Index for dyn Trait<(m!(), T)> + where + T: Trait, + { + type Output = m!(); + fn index(&self, i: m!()) -> &m!() { + unimplemented!() + } + } +} + +trait Trait {} +impl Trait for i32 {} diff --git a/tests/ui/errors/issue-116502-span-error.stderr b/tests/ui/errors/issue-116502-span-error.stderr new file mode 100644 index 0000000000000..01629d68db4bd --- /dev/null +++ b/tests/ui/errors/issue-116502-span-error.stderr @@ -0,0 +1,120 @@ +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ `_` not allowed here +... +LL | let x: m!() = m!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ `_` not allowed here +... +LL | std::cell::Cell::::new(m!()); + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ + | | + | not allowed in type signatures + | not allowed in type signatures + | not allowed in type signatures +... +LL | struct S(m!(), T) + | ---- ---- in this macro invocation + | | + | in this macro invocation +LL | where +LL | T: Trait; + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use type parameters instead + | +LL ~ U +LL | + ... +LL | } +LL ~ struct S(m!(), T) + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ + | | + | not allowed in type signatures + | not allowed in type signatures + | not allowed in type signatures +... +LL | impl std::ops::Index for dyn Trait<(m!(), T)> + | ---- ---- in this macro invocation + | | + | in this macro invocation +LL | where +LL | T: Trait, + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use type parameters instead + | +LL ~ U +LL | + ... +LL | std::cell::Cell::::new(m!()); +LL ~ impl std::ops::Index for dyn Trait<(m!(), T)> + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ not allowed in type signatures +... +LL | type Output = m!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-116502-span-error.rs:15:13 + | +LL | _ + | ^ + | | + | not allowed in type signatures + | not allowed in type signatures +... +LL | fn index(&self, i: m!()) -> &m!() { + | ---- ---- in this macro invocation + | | + | in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use type parameters instead + | +LL ~ T +LL | + ... +LL | type Output = m!(); +LL ~ fn index(&self, i: m!()) -> &m!() { + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | {type error} + | + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0121`.