From 00c435d9b37540d16489862446d934e98e58dfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Aug 2024 18:59:26 +0000 Subject: [PATCH] Do not ICE on non-ADT rcvr type when looking for crate version collision When looking for multiple versions of the same crate, do not blindly construct the receiver type. Follow up to #128786. Fix #129205. --- .../rustc_hir_typeck/src/method/suggest.rs | 14 ++++++++------ .../missing-method-on-type-parameter.rs | 6 ++++++ .../missing-method-on-type-parameter.stderr | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 tests/ui/methods/missing-method-on-type-parameter.rs create mode 100644 tests/ui/methods/missing-method-on-type-parameter.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index ffd46ea13b9..8b8bb29dacd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3498,7 +3498,7 @@ fn suggest_traits_to_import( err, pick.item.def_id, rcvr.hir_id, - *rcvr_ty, + Some(*rcvr_ty), ); if pick.autoderefs == 0 && !trait_in_other_version_found { err.span_label( @@ -3689,8 +3689,7 @@ fn suggest_traits_to_import( if let SelfSource::QPath(ty) = source && !valid_out_of_scope_traits.is_empty() && let hir::TyKind::Path(path) = ty.kind - && let hir::QPath::Resolved(_, path) = path - && let Some(def_id) = path.res.opt_def_id() + && let hir::QPath::Resolved(..) = path && let Some(assoc) = self .tcx .associated_items(valid_out_of_scope_traits[0]) @@ -3700,7 +3699,8 @@ fn suggest_traits_to_import( // See if the `Type::function(val)` where `function` wasn't found corresponds to a // `Trait` that is imported directly, but `Type` came from a different version of the // same crate. - let rcvr_ty = self.tcx.type_of(def_id).instantiate_identity(); + + let rcvr_ty = self.node_ty_opt(ty.hir_id); trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions( err, assoc.def_id, @@ -4080,7 +4080,7 @@ fn detect_and_explain_multiple_crate_versions( err: &mut Diag<'_>, item_def_id: DefId, hir_id: hir::HirId, - rcvr_ty: Ty<'_>, + rcvr_ty: Option>, ) -> bool { let hir_id = self.tcx.parent_hir_id(hir_id); let Some(traits) = self.tcx.in_scope_traits(hir_id) else { return false }; @@ -4110,8 +4110,10 @@ fn detect_and_explain_multiple_crate_versions( let mut multi_span: MultiSpan = trait_span.into(); multi_span.push_span_label(trait_span, format!("this is the trait that is needed")); let descr = self.tcx.associated_item(item_def_id).descr(); + let rcvr_ty = + rcvr_ty.map(|t| format!("`{t}`")).unwrap_or_else(|| "the receiver".to_string()); multi_span - .push_span_label(item_span, format!("the {descr} is available for `{rcvr_ty}` here")); + .push_span_label(item_span, format!("the {descr} is available for {rcvr_ty} here")); for (def_id, import_def_id) in candidates { if let Some(import_def_id) = import_def_id { multi_span.push_span_label( diff --git a/tests/ui/methods/missing-method-on-type-parameter.rs b/tests/ui/methods/missing-method-on-type-parameter.rs new file mode 100644 index 00000000000..cbcbeea4d4c --- /dev/null +++ b/tests/ui/methods/missing-method-on-type-parameter.rs @@ -0,0 +1,6 @@ +// Regression test for https://github.com/rust-lang/rust/issues/129205 +fn x() { + T::try_from(); //~ ERROR E0599 +} + +fn main() {} diff --git a/tests/ui/methods/missing-method-on-type-parameter.stderr b/tests/ui/methods/missing-method-on-type-parameter.stderr new file mode 100644 index 00000000000..c53d7afe4e2 --- /dev/null +++ b/tests/ui/methods/missing-method-on-type-parameter.stderr @@ -0,0 +1,19 @@ +error[E0599]: no function or associated item named `try_from` found for type parameter `T` in the current scope + --> $DIR/missing-method-on-type-parameter.rs:3:8 + | +LL | fn x() { + | - function or associated item `try_from` not found for this type parameter +LL | T::try_from(); + | ^^^^^^^^ function or associated item not found in `T` + | + = help: items from traits can only be used if the trait is in scope +help: there is an associated function `from` with a similar name + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL +help: trait `TryFrom` which provides `try_from` is implemented but not in scope; perhaps you want to import it + | +LL + use std::convert::TryFrom; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`.