@@ -5,6 +5,7 @@ use crate::errors;
55use crate :: FnCtxt ;
66use rustc_ast:: ast:: Mutability ;
77use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8+ use rustc_errors:: StashKey ;
89use rustc_errors:: {
910 pluralize, struct_span_err, Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed ,
1011 MultiSpan ,
@@ -13,6 +14,7 @@ use rustc_hir as hir;
1314use rustc_hir:: def:: DefKind ;
1415use rustc_hir:: def_id:: DefId ;
1516use rustc_hir:: lang_items:: LangItem ;
17+ use rustc_hir:: PatKind :: Binding ;
1618use rustc_hir:: { ExprKind , Node , QPath } ;
1719use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
1820use rustc_middle:: traits:: util:: supertraits;
@@ -1407,48 +1409,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14071409 false
14081410 }
14091411
1410- pub ( crate ) fn suggest_instance_call (
1411- & self ,
1412- seg1 : & hir:: PathSegment < ' _ > ,
1413- seg2 : & hir:: PathSegment < ' _ > ,
1414- local_span : Span ,
1415- ) -> bool {
1412+ /// For code `rect::area(...)`, we try to suggest `rect.area()`
1413+ /// If `rect` is a local variable and `area` is a valid assoc method for it.
1414+ pub ( crate ) fn suggest_instance_call ( & self , path : & hir:: Path < ' _ > ) {
1415+ if path. segments . len ( ) != 2 {
1416+ return ;
1417+ }
1418+ let seg1 = & path. segments [ 0 ] ;
1419+ let seg2 = & path. segments [ 1 ] ;
1420+ let Some ( mut diag) =
1421+ self . tcx . sess . diagnostic ( ) . steal_diagnostic ( seg1. ident . span , StashKey :: CallInstanceMethod ) else { return } ;
1422+
14161423 let map = self . infcx . tcx . hir ( ) ;
14171424 let body_id = map. body_owned_by ( seg1. hir_id . owner . def_id ) ;
14181425 let body = map. body ( body_id) ;
1419-
14201426 struct LetVisitor < ' a > {
1421- local_span : Span ,
1422- result : Option < & ' a Ty < ' a > > ,
1427+ result : Option < & ' a hir :: Expr < ' a > > ,
1428+ ident_name : Symbol ,
14231429 }
14241430
1425- impl < ' v > Visitor < ' v > for LetVisitor < ' _ > {
1431+ impl < ' v > Visitor < ' v > for LetVisitor < ' v > {
14261432 fn visit_stmt ( & mut self , ex : & ' v hir:: Stmt < ' v > ) {
1427- if self . result . is_some ( ) {
1428- return ;
1429- }
1430- if let hir:: StmtKind :: Local ( hir:: Local {
1431- span, ty, init : None , ..
1432- } ) = & ex. kind && span. contains ( self . local_span ) {
1433- self . result = ty;
1433+ if let hir:: StmtKind :: Local ( hir:: Local { pat, init, .. } ) = & ex. kind {
1434+ if let Binding ( _, _, ident, ..) = pat. kind &&
1435+ ident. name == self . ident_name {
1436+ self . result = * init;
1437+ }
14341438 }
14351439 hir:: intravisit:: walk_stmt ( self , ex) ;
14361440 }
14371441 }
14381442
1439- let mut visitor = LetVisitor { local_span , result : None } ;
1443+ let mut visitor = LetVisitor { result : None , ident_name : seg1 . ident . name } ;
14401444 visitor. visit_body ( & body) ;
14411445
14421446 let parent = self . tcx . hir ( ) . get_parent_node ( seg1. hir_id ) ;
1443- let parent_expr = self . tcx . hir ( ) . find ( parent) ;
1444- debug ! ( "yukang parent_expr: {:?}" , parent_expr) ;
1445- let node = self . tcx . hir ( ) . get_parent_node ( seg1. hir_id ) ;
1446- let ty = self . typeck_results . borrow ( ) . node_type_opt ( node) ;
1447-
1448- debug ! ( "yukang suggest_instance_call ty: {:?}" , ty) ;
14491447 if let Some ( Node :: Expr ( call_expr) ) = self . tcx . hir ( ) . find ( parent) &&
1450- let Some ( self_ty ) = ty {
1451- debug ! ( "yukang trying to prob method" ) ;
1448+ let Some ( expr ) = visitor . result {
1449+ let self_ty = self . check_expr ( expr ) ;
14521450 let probe = self . lookup_probe (
14531451 seg1. ident . span ,
14541452 seg2. ident ,
@@ -1457,11 +1455,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14571455 ProbeScope :: TraitsInScope ,
14581456 ) ;
14591457
1460- if let Ok ( _pick) = probe {
1461- return true ;
1458+ if probe. is_ok ( ) {
1459+ diag. set_primary_message ( format ! (
1460+ "need to fix call instance method: {:?}" ,
1461+ seg2. ident
1462+ ) ) ;
1463+ diag. emit ( ) ;
1464+ } else {
1465+ diag. cancel ( ) ;
14621466 }
14631467 }
1464- return false ;
14651468 }
14661469
14671470 fn check_for_field_method (
0 commit comments