@@ -5,9 +5,9 @@ use rustc_errors::codes::*;
55use rustc_errors:: {
66 Applicability , Diag , ErrorGuaranteed , MultiSpan , listify, pluralize, struct_span_code_err,
77} ;
8- use rustc_hir as hir;
98use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
109use rustc_hir:: def_id:: DefId ;
10+ use rustc_hir:: { self as hir, HirId } ;
1111use rustc_middle:: bug;
1212use rustc_middle:: ty:: fast_reject:: { TreatParams , simplify_type} ;
1313use rustc_middle:: ty:: print:: { PrintPolyTraitRefExt as _, PrintTraitRefExt as _} ;
@@ -23,6 +23,7 @@ use rustc_trait_selection::traits::{
2323 FulfillmentError , dyn_compatibility_violations_for_assoc_item,
2424} ;
2525use smallvec:: SmallVec ;
26+ use tracing:: debug;
2627
2728use crate :: errors:: {
2829 self , AssocItemConstraintsNotAllowedHere , ManualImplementation , MissingTypeParams ,
@@ -34,7 +35,7 @@ use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
3435impl < ' tcx > dyn HirTyLowerer < ' tcx > + ' _ {
3536 /// On missing type parameters, emit an E0393 error and provide a structured suggestion using
3637 /// the type parameter's name as a placeholder.
37- pub ( crate ) fn complain_about_missing_type_params (
38+ pub ( crate ) fn report_missing_type_params (
3839 & self ,
3940 missing_type_params : Vec < Symbol > ,
4041 def_id : DefId ,
@@ -56,7 +57,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
5657
5758 /// When the code is using the `Fn` traits directly, instead of the `Fn(A) -> B` syntax, emit
5859 /// an error and attempt to build a reasonable structured suggestion.
59- pub ( crate ) fn complain_about_internal_fn_trait (
60+ pub ( crate ) fn report_internal_fn_trait (
6061 & self ,
6162 span : Span ,
6263 trait_def_id : DefId ,
@@ -112,7 +113,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
112113 }
113114 }
114115
115- pub ( super ) fn complain_about_assoc_item_not_found < I > (
116+ pub ( super ) fn report_unresolved_assoc_item < I > (
116117 & self ,
117118 all_candidates : impl Fn ( ) -> I ,
118119 qself : AssocItemQSelf ,
@@ -132,7 +133,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
132133 . filter_by_name_unhygienic ( assoc_ident. name )
133134 . find ( |item| tcx. hygienic_eq ( assoc_ident, item. ident ( tcx) , r. def_id ( ) ) )
134135 } ) {
135- return self . complain_about_assoc_kind_mismatch (
136+ return self . report_assoc_kind_mismatch (
136137 assoc_item,
137138 assoc_tag,
138139 assoc_ident,
@@ -331,7 +332,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
331332 self . dcx ( ) . emit_err ( err)
332333 }
333334
334- fn complain_about_assoc_kind_mismatch (
335+ fn report_assoc_kind_mismatch (
335336 & self ,
336337 assoc_item : & ty:: AssocItem ,
337338 assoc_tag : ty:: AssocTag ,
@@ -396,7 +397,173 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
396397 } )
397398 }
398399
399- pub ( super ) fn report_ambiguous_assoc (
400+ pub ( crate ) fn report_missing_self_ty_for_resolved_path (
401+ & self ,
402+ trait_def_id : DefId ,
403+ span : Span ,
404+ item_segment : & hir:: PathSegment < ' tcx > ,
405+ assoc_tag : ty:: AssocTag ,
406+ ) -> ErrorGuaranteed {
407+ let tcx = self . tcx ( ) ;
408+ let path_str = tcx. def_path_str ( trait_def_id) ;
409+
410+ let def_id = self . item_def_id ( ) ;
411+ debug ! ( item_def_id = ?def_id) ;
412+
413+ // FIXME: document why/how this is different from `tcx.local_parent(def_id)`
414+ let parent_def_id = tcx. hir_get_parent_item ( tcx. local_def_id_to_hir_id ( def_id) ) . to_def_id ( ) ;
415+ debug ! ( ?parent_def_id) ;
416+
417+ // If the trait in segment is the same as the trait defining the item,
418+ // use the `<Self as ..>` syntax in the error.
419+ let is_part_of_self_trait_constraints = def_id. to_def_id ( ) == trait_def_id;
420+ let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
421+
422+ let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
423+ vec ! [ "Self" . to_string( ) ]
424+ } else {
425+ // Find all the types that have an `impl` for the trait.
426+ tcx. all_impls ( trait_def_id)
427+ . filter_map ( |impl_def_id| tcx. impl_trait_header ( impl_def_id) )
428+ . filter ( |header| {
429+ // Consider only accessible traits
430+ tcx. visibility ( trait_def_id) . is_accessible_from ( self . item_def_id ( ) , tcx)
431+ && header. polarity != ty:: ImplPolarity :: Negative
432+ } )
433+ . map ( |header| header. trait_ref . instantiate_identity ( ) . self_ty ( ) )
434+ // We don't care about blanket impls.
435+ . filter ( |self_ty| !self_ty. has_non_region_param ( ) )
436+ . map ( |self_ty| tcx. erase_regions ( self_ty) . to_string ( ) )
437+ . collect ( )
438+ } ;
439+ // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
440+ // references the trait. Relevant for the first case in
441+ // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
442+ self . report_ambiguous_assoc_item_path (
443+ span,
444+ & type_names,
445+ & [ path_str] ,
446+ item_segment. ident . name ,
447+ assoc_tag,
448+ )
449+ }
450+
451+ pub ( super ) fn report_unresolved_type_relative_path (
452+ & self ,
453+ self_ty : Ty < ' tcx > ,
454+ hir_self_ty : & hir:: Ty < ' _ > ,
455+ assoc_tag : ty:: AssocTag ,
456+ ident : Ident ,
457+ qpath_hir_id : HirId ,
458+ span : Span ,
459+ variant_def_id : Option < DefId > ,
460+ ) -> ErrorGuaranteed {
461+ let tcx = self . tcx ( ) ;
462+ let kind_str = assoc_tag_str ( assoc_tag) ;
463+ if variant_def_id. is_some ( ) {
464+ // Variant in type position
465+ let msg = format ! ( "expected {kind_str}, found variant `{ident}`" ) ;
466+ self . dcx ( ) . span_err ( span, msg)
467+ } else if self_ty. is_enum ( ) {
468+ let mut err = self . dcx ( ) . create_err ( errors:: NoVariantNamed {
469+ span : ident. span ,
470+ ident,
471+ ty : self_ty,
472+ } ) ;
473+
474+ let adt_def = self_ty. ty_adt_def ( ) . expect ( "enum is not an ADT" ) ;
475+ if let Some ( variant_name) = find_best_match_for_name (
476+ & adt_def. variants ( ) . iter ( ) . map ( |variant| variant. name ) . collect :: < Vec < Symbol > > ( ) ,
477+ ident. name ,
478+ None ,
479+ ) && let Some ( variant) = adt_def. variants ( ) . iter ( ) . find ( |s| s. name == variant_name)
480+ {
481+ let mut suggestion = vec ! [ ( ident. span, variant_name. to_string( ) ) ] ;
482+ if let hir:: Node :: Stmt ( & hir:: Stmt { kind : hir:: StmtKind :: Semi ( expr) , .. } )
483+ | hir:: Node :: Expr ( expr) = tcx. parent_hir_node ( qpath_hir_id)
484+ && let hir:: ExprKind :: Struct ( ..) = expr. kind
485+ {
486+ match variant. ctor {
487+ None => {
488+ // struct
489+ suggestion = vec ! [ (
490+ ident. span. with_hi( expr. span. hi( ) ) ,
491+ if variant. fields. is_empty( ) {
492+ format!( "{variant_name} {{}}" )
493+ } else {
494+ format!(
495+ "{variant_name} {{ {} }}" ,
496+ variant
497+ . fields
498+ . iter( )
499+ . map( |f| format!( "{}: /* value */" , f. name) )
500+ . collect:: <Vec <_>>( )
501+ . join( ", " )
502+ )
503+ } ,
504+ ) ] ;
505+ }
506+ Some ( ( hir:: def:: CtorKind :: Fn , def_id) ) => {
507+ // tuple
508+ let fn_sig = tcx. fn_sig ( def_id) . instantiate_identity ( ) ;
509+ let inputs = fn_sig. inputs ( ) . skip_binder ( ) ;
510+ suggestion = vec ! [ (
511+ ident. span. with_hi( expr. span. hi( ) ) ,
512+ format!(
513+ "{variant_name}({})" ,
514+ inputs
515+ . iter( )
516+ . map( |i| format!( "/* {i} */" ) )
517+ . collect:: <Vec <_>>( )
518+ . join( ", " )
519+ ) ,
520+ ) ] ;
521+ }
522+ Some ( ( hir:: def:: CtorKind :: Const , _) ) => {
523+ // unit
524+ suggestion = vec ! [ (
525+ ident. span. with_hi( expr. span. hi( ) ) ,
526+ variant_name. to_string( ) ,
527+ ) ] ;
528+ }
529+ }
530+ }
531+ err. multipart_suggestion_verbose (
532+ "there is a variant with a similar name" ,
533+ suggestion,
534+ Applicability :: HasPlaceholders ,
535+ ) ;
536+ } else {
537+ err. span_label ( ident. span , format ! ( "variant not found in `{self_ty}`" ) ) ;
538+ }
539+
540+ if let Some ( sp) = tcx. hir_span_if_local ( adt_def. did ( ) ) {
541+ err. span_label ( sp, format ! ( "variant `{ident}` not found here" ) ) ;
542+ }
543+
544+ err. emit ( )
545+ } else if let Err ( reported) = self_ty. error_reported ( ) {
546+ reported
547+ } else {
548+ match self . maybe_report_similar_assoc_fn ( span, self_ty, hir_self_ty) {
549+ Ok ( ( ) ) => { }
550+ Err ( reported) => return reported,
551+ }
552+
553+ let traits: Vec < _ > = self . probe_traits_that_match_assoc_ty ( self_ty, ident) ;
554+
555+ // Don't print `ty::Error` to the user.
556+ self . report_ambiguous_assoc_item_path (
557+ span,
558+ & [ self_ty. to_string ( ) ] ,
559+ & traits,
560+ ident. name ,
561+ assoc_tag,
562+ )
563+ }
564+ }
565+
566+ pub ( super ) fn report_ambiguous_assoc_item_path (
400567 & self ,
401568 span : Span ,
402569 types : & [ String ] ,
@@ -505,7 +672,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
505672 err. emit ( )
506673 }
507674
508- pub ( crate ) fn complain_about_ambiguous_inherent_assoc (
675+ pub ( crate ) fn report_ambiguous_inherent_assoc_item (
509676 & self ,
510677 name : Ident ,
511678 candidates : Vec < DefId > ,
@@ -518,12 +685,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
518685 "multiple applicable items in scope"
519686 ) ;
520687 err. span_label ( name. span , format ! ( "multiple `{name}` found" ) ) ;
521- self . note_ambiguous_inherent_assoc_ty ( & mut err, candidates, span) ;
688+ self . note_ambiguous_inherent_assoc_item ( & mut err, candidates, span) ;
522689 err. emit ( )
523690 }
524691
525692 // FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
526- fn note_ambiguous_inherent_assoc_ty (
693+ fn note_ambiguous_inherent_assoc_item (
527694 & self ,
528695 err : & mut Diag < ' _ > ,
529696 candidates : Vec < DefId > ,
@@ -566,7 +733,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
566733 }
567734
568735 // FIXME(inherent_associated_types): Find similarly named associated types and suggest them.
569- pub ( crate ) fn complain_about_inherent_assoc_not_found (
736+ pub ( crate ) fn report_unresolved_inherent_assoc_item (
570737 & self ,
571738 name : Ident ,
572739 self_ty : Ty < ' tcx > ,
@@ -1046,7 +1213,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10461213 }
10471214 }
10481215
1049- pub fn report_prohibit_generics_error < ' a > (
1216+ pub fn report_prohibited_generic_args < ' a > (
10501217 & self ,
10511218 segments : impl Iterator < Item = & ' a hir:: PathSegment < ' a > > + Clone ,
10521219 args_visitors : impl Iterator < Item = & ' a hir:: GenericArg < ' a > > + Clone ,
@@ -1128,7 +1295,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11281295 err. emit ( )
11291296 }
11301297
1131- pub fn report_trait_object_addition_traits_error (
1298+ pub fn report_trait_object_addition_traits (
11321299 & self ,
11331300 regular_traits : & Vec < ( ty:: PolyTraitPredicate < ' tcx > , SmallVec < [ Span ; 1 ] > ) > ,
11341301 ) -> ErrorGuaranteed {
@@ -1171,7 +1338,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11711338 err. emit ( )
11721339 }
11731340
1174- pub fn report_trait_object_with_no_traits_error (
1341+ pub fn report_trait_object_with_no_traits (
11751342 & self ,
11761343 span : Span ,
11771344 user_written_clauses : impl IntoIterator < Item = ( ty:: Clause < ' tcx > , Span ) > ,
0 commit comments