@@ -858,13 +858,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
858858 path. segments ,
859859 ) ;
860860 }
861- QPath :: TypeRelative ( ref qself, ref segment) => ( self . to_ty ( qself) , qself, segment) ,
861+ QPath :: TypeRelative ( ref qself, ref segment) => {
862+ // Don't use `self.to_ty`, since this will register a WF obligation.
863+ // If we're trying to call a non-existent method on a trait
864+ // (e.g. `MyTrait::missing_method`), then resolution will
865+ // give us a `QPath::TypeRelative` with a trait object as
866+ // `qself`. In that case, we want to avoid registering a WF obligation
867+ // for `dyn MyTrait`, since we don't actually need the trait
868+ // to be object-safe.
869+ // We manually call `register_wf_obligation` in the success path
870+ // below.
871+ ( <dyn AstConv < ' _ > >:: ast_ty_to_ty ( self , qself) , qself, segment)
872+ }
862873 QPath :: LangItem ( ..) => {
863874 bug ! ( "`resolve_ty_and_res_fully_qualified_call` called on `LangItem`" )
864875 }
865876 } ;
866877 if let Some ( & cached_result) = self . typeck_results . borrow ( ) . type_dependent_defs ( ) . get ( hir_id)
867878 {
879+ self . register_wf_obligation ( ty. into ( ) , qself. span , traits:: WellFormed ( None ) ) ;
868880 // Return directly on cache hit. This is useful to avoid doubly reporting
869881 // errors with default match binding modes. See #44614.
870882 let def = cached_result. map_or ( Res :: Err , |( kind, def_id) | Res :: Def ( kind, def_id) ) ;
@@ -878,6 +890,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
878890 method:: MethodError :: PrivateMatch ( kind, def_id, _) => Ok ( ( kind, def_id) ) ,
879891 _ => Err ( ErrorReported ) ,
880892 } ;
893+
894+ // If we have a path like `MyTrait::missing_method`, then don't register
895+ // a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise,
896+ // register a WF obligation so that we can detect any additional
897+ // errors in the self type.
898+ if !( matches ! ( error, method:: MethodError :: NoMatch ( _) ) && ty. is_trait ( ) ) {
899+ self . register_wf_obligation ( ty. into ( ) , qself. span , traits:: WellFormed ( None ) ) ;
900+ }
881901 if item_name. name != kw:: Empty {
882902 if let Some ( mut e) = self . report_method_error (
883903 span,
@@ -895,6 +915,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895915
896916 if result. is_ok ( ) {
897917 self . maybe_lint_bare_trait ( qpath, hir_id) ;
918+ self . register_wf_obligation ( ty. into ( ) , qself. span , traits:: WellFormed ( None ) ) ;
898919 }
899920
900921 // Write back the new resolution.
0 commit comments