@@ -858,13 +858,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
858
858
path. segments ,
859
859
) ;
860
860
}
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
+ }
862
873
QPath :: LangItem ( ..) => {
863
874
bug ! ( "`resolve_ty_and_res_fully_qualified_call` called on `LangItem`" )
864
875
}
865
876
} ;
866
877
if let Some ( & cached_result) = self . typeck_results . borrow ( ) . type_dependent_defs ( ) . get ( hir_id)
867
878
{
879
+ self . register_wf_obligation ( ty. into ( ) , qself. span , traits:: WellFormed ( None ) ) ;
868
880
// Return directly on cache hit. This is useful to avoid doubly reporting
869
881
// errors with default match binding modes. See #44614.
870
882
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> {
878
890
method:: MethodError :: PrivateMatch ( kind, def_id, _) => Ok ( ( kind, def_id) ) ,
879
891
_ => Err ( ErrorReported ) ,
880
892
} ;
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
+ }
881
901
if item_name. name != kw:: Empty {
882
902
if let Some ( mut e) = self . report_method_error (
883
903
span,
@@ -895,6 +915,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895
915
896
916
if result. is_ok ( ) {
897
917
self . maybe_lint_bare_trait ( qpath, hir_id) ;
918
+ self . register_wf_obligation ( ty. into ( ) , qself. span , traits:: WellFormed ( None ) ) ;
898
919
}
899
920
900
921
// Write back the new resolution.
0 commit comments