Skip to content

Commit 92fbb59

Browse files
committed
first workable version
1 parent 0a551c3 commit 92fbb59

File tree

6 files changed

+34
-67
lines changed

6 files changed

+34
-67
lines changed

compiler/rustc_hir/src/intravisit.rs

-2
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,6 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id:
697697
visitor.visit_path(path, id)
698698
}
699699
QPath::TypeRelative(ref qself, ref segment) => {
700-
debug!("yukang segment: {:?}", segment);
701700
visitor.visit_ty(qself);
702701
visitor.visit_path_segment(segment);
703702
}
@@ -712,7 +711,6 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
712711
}
713712

714713
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) {
715-
debug!("yukang walk_path_segment: {:?}", segment);
716714
visitor.visit_ident(segment.ident);
717715
visitor.visit_id(segment.hir_id);
718716
if let Some(ref args) = segment.args {

compiler/rustc_hir_typeck/src/expr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
520520
args: &'tcx [hir::Expr<'tcx>],
521521
) -> Ty<'tcx> {
522522
let tcx = self.tcx;
523-
debug!("yukang check_expr_path: {:?}", qpath);
524523
let (res, opt_ty, segs) =
525524
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
526525
let ty = match res {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+2-23
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::rvalue_scopes;
44
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
55
use rustc_data_structures::captures::Captures;
66
use rustc_data_structures::fx::FxHashSet;
7-
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
7+
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
88
use rustc_hir as hir;
99
use rustc_hir::def::{CtorOf, DefKind, Res};
1010
use rustc_hir::def_id::DefId;
@@ -863,28 +863,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
863863
);
864864
let (ty, qself, item_segment) = match *qpath {
865865
QPath::Resolved(ref opt_qself, ref path) => {
866-
if path.segments.len() == 2 {
867-
debug!("yukang item_segment: {:?}", path.segments);
868-
if let [seg1, seg2] = path.segments
869-
&& let Some(mut diag) = self
870-
.tcx
871-
.sess
872-
.diagnostic()
873-
.steal_diagnostic(seg1.ident.span, StashKey::CallInstanceMethod)
874-
&& let Some(&help) = diag.children.get(0) {
875-
let local_def_span = help.span;
876-
if self.suggest_instance_call(seg1, seg2, &local_def_span) {
877-
diag.set_primary_message(format!(
878-
"need to fix call instance method: {:?}",
879-
seg2.ident
880-
));
881-
diag.emit();
882-
} else {
883-
diag.cancel();
884-
}
885-
}
886-
}
887-
866+
self.suggest_instance_call(*path);
888867
return (
889868
path.res,
890869
opt_qself.as_ref().map(|qself| self.to_ty(qself)),

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1994,7 +1994,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19941994
}
19951995
}
19961996
hir::QPath::TypeRelative(_, segment) => {
1997-
debug!("yukang point_at_path_if_possible segment={:?}", segment);
19981997
if self.point_at_generic_if_possible(error, def_id, param, segment) {
19991998
return true;
20001999
}

compiler/rustc_hir_typeck/src/method/suggest.rs

+32-29
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::errors;
55
use crate::FnCtxt;
66
use rustc_ast::ast::Mutability;
77
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8+
use rustc_errors::StashKey;
89
use rustc_errors::{
910
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
1011
MultiSpan,
@@ -13,6 +14,7 @@ use rustc_hir as hir;
1314
use rustc_hir::def::DefKind;
1415
use rustc_hir::def_id::DefId;
1516
use rustc_hir::lang_items::LangItem;
17+
use rustc_hir::PatKind::Binding;
1618
use rustc_hir::{ExprKind, Node, QPath};
1719
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1820
use 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(

compiler/rustc_resolve/src/diagnostics.rs

-11
Original file line numberDiff line numberDiff line change
@@ -2050,17 +2050,6 @@ impl<'a> Resolver<'a> {
20502050
);
20512051
err.span_warn(local_span, "ident is defined at here");
20522052
err.stash(ident.span, rustc_errors::StashKey::CallInstanceMethod);
2053-
/* suggestion = Some((
2054-
vec![(
2055-
sm.span_extend_while(id ent.span, |c| c == ':').unwrap(),
2056-
format!("{}.", ident),
2057-
)],
2058-
format!(
2059-
"`{}` is not a crate or module, maybe you meant to call instance method",
2060-
ident
2061-
),
2062-
Applicability::MaybeIncorrect,
2063-
)) */
20642053
}
20652054
};
20662055
(format!("use of undeclared crate or module `{}`", ident), suggestion)

0 commit comments

Comments
 (0)