From c0c69cf7d56bb11e61180aa445b3b988cdc055ca Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 3 Apr 2025 18:42:13 +0800 Subject: [PATCH 1/5] Add ui test Signed-off-by: xizheyin --- .../dont-suggest-within-macro-issue-139251.rs | 14 +++++++ ...t-suggest-within-macro-issue-139251.stderr | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/ui/macros/dont-suggest-within-macro-issue-139251.rs create mode 100644 tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr diff --git a/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs b/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs new file mode 100644 index 0000000000000..ceeb6e66950c4 --- /dev/null +++ b/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs @@ -0,0 +1,14 @@ +#[macro_export] +macro_rules! is_equal { + ($left:expr, $right:expr) => { + $left == $right //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] + }; +} + +fn main() { + let x = 1; + let y = &x; + assert!(y == 1); //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] + assert_eq!(y, 2); //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] + is_equal!(y, 2); +} diff --git a/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr b/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr new file mode 100644 index 0000000000000..68c32470ab0b6 --- /dev/null +++ b/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr @@ -0,0 +1,40 @@ +error[E0277]: can't compare `&{integer}` with `{integer}` + --> $DIR/dont-suggest-within-macro-issue-139251.rs:11:15 + | +LL | assert!(y == 1); + | ^^ no implementation for `&{integer} == {integer}` + | + = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` +help: consider dereferencing here + | +LL | assert!(*y == 1); + | + + +error[E0277]: can't compare `&{integer}` with `{integer}` + --> $DIR/dont-suggest-within-macro-issue-139251.rs:12:5 + | +LL | assert_eq!(y, 2); + | ^^^^^^^^^^^^^^^^ no implementation for `&{integer} == {integer}` + | + = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't compare `&{integer}` with `{integer}` + --> $DIR/dont-suggest-within-macro-issue-139251.rs:4:15 + | +LL | $left == $right + | ^^ no implementation for `&{integer} == {integer}` +... +LL | is_equal!(y, 2); + | --------------- in this macro invocation + | + = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` + = note: this error originates in the macro `is_equal` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider dereferencing here + | +LL | is_equal!(*y, 2); + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. From 7753df37def68b78d1fb2cfb5ecd1e99d0cc1c10 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sat, 5 Apr 2025 11:19:09 +0800 Subject: [PATCH 2/5] Suppress suggestions on deref in macro when == is in extern macro Signed-off-by: xizheyin --- .../src/error_reporting/traits/suggestions.rs | 4 ++++ .../dont-suggest-within-macro-issue-139251.stderr | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index dc8022b95c313..55010f613aa1e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -449,6 +449,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { + if obligation.cause.span.in_external_macro(self.infcx.tcx.sess.source_map()) { + return false; + } + let mut code = obligation.cause.code(); if let ObligationCauseCode::FunctionArg { arg_hir_id, call_hir_id, .. } = code && let Some(typeck_results) = &self.typeck_results diff --git a/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr b/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr index 68c32470ab0b6..e4e9b16999414 100644 --- a/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr +++ b/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr @@ -17,6 +17,16 @@ LL | assert_eq!(y, 2); | ^^^^^^^^^^^^^^^^ no implementation for `&{integer} == {integer}` | = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` + = help: the following other types implement trait `PartialEq`: + f128 + f16 + f32 + f64 + i128 + i16 + i32 + i64 + and 8 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&{integer}` with `{integer}` From fd7029dd9e60a99eb2412481487161ab3f3f05c9 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 14 Apr 2025 20:17:12 +0800 Subject: [PATCH 3/5] Suppress suggestions while span is in external library Signed-off-by: xizheyin --- compiler/rustc_errors/src/emitter.rs | 18 +++++++ .../src/error_reporting/traits/suggestions.rs | 4 -- .../dont-suggest-within-macro-issue-139251.rs | 14 ------ ...t-suggest-within-macro-issue-139251.stderr | 50 ------------------- 4 files changed, 18 insertions(+), 68 deletions(-) delete mode 100644 tests/ui/macros/dont-suggest-within-macro-issue-139251.rs delete mode 100644 tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index fe01e289334cc..e3ae64c346d60 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1996,6 +1996,14 @@ impl HumanEmitter { return Ok(()); }; + if suggestion + .substitutions + .iter() + .any(|s| s.parts.iter().any(|p| is_external_library(sm, p.span))) + { + return Ok(()); + } + // Render the replacements for each suggestion let suggestions = suggestion.splice_lines(sm); debug!(?suggestions); @@ -3532,3 +3540,13 @@ pub(crate) fn should_show_source_code( .map(|path| ignored_directories.iter().all(|dir| !path.starts_with(dir))) .unwrap_or(true) } + +fn is_external_library(sm: &SourceMap, span: Span) -> bool { + let filename = sm.span_to_filename(span); + if let Some(path) = filename.into_local_path() { + path.to_string_lossy().contains(".cargo/registry/src/") + || path.to_string_lossy().contains(".rustup/toolchains/") + } else { + false + } +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 55010f613aa1e..dc8022b95c313 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -449,10 +449,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { - if obligation.cause.span.in_external_macro(self.infcx.tcx.sess.source_map()) { - return false; - } - let mut code = obligation.cause.code(); if let ObligationCauseCode::FunctionArg { arg_hir_id, call_hir_id, .. } = code && let Some(typeck_results) = &self.typeck_results diff --git a/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs b/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs deleted file mode 100644 index ceeb6e66950c4..0000000000000 --- a/tests/ui/macros/dont-suggest-within-macro-issue-139251.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[macro_export] -macro_rules! is_equal { - ($left:expr, $right:expr) => { - $left == $right //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] - }; -} - -fn main() { - let x = 1; - let y = &x; - assert!(y == 1); //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] - assert_eq!(y, 2); //~ ERROR can't compare `&{integer}` with `{integer}` [E0277] - is_equal!(y, 2); -} diff --git a/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr b/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr deleted file mode 100644 index e4e9b16999414..0000000000000 --- a/tests/ui/macros/dont-suggest-within-macro-issue-139251.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error[E0277]: can't compare `&{integer}` with `{integer}` - --> $DIR/dont-suggest-within-macro-issue-139251.rs:11:15 - | -LL | assert!(y == 1); - | ^^ no implementation for `&{integer} == {integer}` - | - = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` -help: consider dereferencing here - | -LL | assert!(*y == 1); - | + - -error[E0277]: can't compare `&{integer}` with `{integer}` - --> $DIR/dont-suggest-within-macro-issue-139251.rs:12:5 - | -LL | assert_eq!(y, 2); - | ^^^^^^^^^^^^^^^^ no implementation for `&{integer} == {integer}` - | - = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` - = help: the following other types implement trait `PartialEq`: - f128 - f16 - f32 - f64 - i128 - i16 - i32 - i64 - and 8 others - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: can't compare `&{integer}` with `{integer}` - --> $DIR/dont-suggest-within-macro-issue-139251.rs:4:15 - | -LL | $left == $right - | ^^ no implementation for `&{integer} == {integer}` -... -LL | is_equal!(y, 2); - | --------------- in this macro invocation - | - = help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}` - = note: this error originates in the macro `is_equal` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider dereferencing here - | -LL | is_equal!(*y, 2); - | + - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. From 6b0c39ee3a173a5ec20e8d2ccd7da455123daabc Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 14 Apr 2025 21:53:35 +0800 Subject: [PATCH 4/5] use env variables to avoid hardcode, and use paltform independent path Signed-off-by: xizheyin --- compiler/rustc_errors/src/emitter.rs | 31 ++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index e3ae64c346d60..1a32f2e94c691 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -3544,8 +3544,35 @@ pub(crate) fn should_show_source_code( fn is_external_library(sm: &SourceMap, span: Span) -> bool { let filename = sm.span_to_filename(span); if let Some(path) = filename.into_local_path() { - path.to_string_lossy().contains(".cargo/registry/src/") - || path.to_string_lossy().contains(".rustup/toolchains/") + // use env variable to get path, avoid hardcode + // use platform independent path + + let cargo_home = match std::env::var("CARGO_HOME") { + Ok(dir) => std::path::PathBuf::from(dir), + Err(_) => { + if let Ok(home) = std::env::var("HOME") { + std::path::PathBuf::from(home).join(".cargo") + } else { + return false; + } + } + }; + + let rustup_home = match std::env::var("RUSTUP_HOME") { + Ok(dir) => std::path::PathBuf::from(dir), + Err(_) => { + if let Ok(home) = std::env::var("HOME") { + std::path::PathBuf::from(home).join(".rustup") + } else { + return false; + } + } + }; + + let registry_path = cargo_home.join("registry").join("src"); + let toolchain_path = rustup_home.join("toolchains"); + + path.starts_with(®istry_path) || path.starts_with(&toolchain_path) } else { false } From 6cbd2d30f18d45877dd1ea853826133163aa6b6d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 14 Apr 2025 22:28:06 +0800 Subject: [PATCH 5/5] Add support for rustc sysroot Signed-off-by: xizheyin --- compiler/rustc_errors/src/emitter.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 1a32f2e94c691..4bec8615cd017 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -3569,10 +3569,17 @@ fn is_external_library(sm: &SourceMap, span: Span) -> bool { } }; + let sysroot = match std::env::var("RUSTC_SYSROOT") { + Ok(dir) => Some(std::path::PathBuf::from(dir)), + Err(_) => None, + }; + let registry_path = cargo_home.join("registry").join("src"); let toolchain_path = rustup_home.join("toolchains"); - path.starts_with(®istry_path) || path.starts_with(&toolchain_path) + path.starts_with(®istry_path) + || path.starts_with(&toolchain_path) + || sysroot.as_ref().map_or(false, |sr| path.starts_with(sr)) } else { false }