Skip to content

Commit

Permalink
first workable version
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Oct 28, 2022
1 parent 0a551c3 commit 92fbb59
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 67 deletions.
2 changes: 0 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,6 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id:
visitor.visit_path(path, id)
}
QPath::TypeRelative(ref qself, ref segment) => {
debug!("yukang segment: {:?}", segment);
visitor.visit_ty(qself);
visitor.visit_path_segment(segment);
}
Expand All @@ -712,7 +711,6 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
}

pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) {
debug!("yukang walk_path_segment: {:?}", segment);
visitor.visit_ident(segment.ident);
visitor.visit_id(segment.hir_id);
if let Some(ref args) = segment.args {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
args: &'tcx [hir::Expr<'tcx>],
) -> Ty<'tcx> {
let tcx = self.tcx;
debug!("yukang check_expr_path: {:?}", qpath);
let (res, opt_ty, segs) =
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
let ty = match res {
Expand Down
25 changes: 2 additions & 23 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::rvalue_scopes;
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -863,28 +863,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
let (ty, qself, item_segment) = match *qpath {
QPath::Resolved(ref opt_qself, ref path) => {
if path.segments.len() == 2 {
debug!("yukang item_segment: {:?}", path.segments);
if let [seg1, seg2] = path.segments
&& let Some(mut diag) = self
.tcx
.sess
.diagnostic()
.steal_diagnostic(seg1.ident.span, StashKey::CallInstanceMethod)
&& let Some(&help) = diag.children.get(0) {
let local_def_span = help.span;
if self.suggest_instance_call(seg1, seg2, &local_def_span) {
diag.set_primary_message(format!(
"need to fix call instance method: {:?}",
seg2.ident
));
diag.emit();
} else {
diag.cancel();
}
}
}

self.suggest_instance_call(*path);
return (
path.res,
opt_qself.as_ref().map(|qself| self.to_ty(qself)),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1994,7 +1994,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
hir::QPath::TypeRelative(_, segment) => {
debug!("yukang point_at_path_if_possible segment={:?}", segment);
if self.point_at_generic_if_possible(error, def_id, param, segment) {
return true;
}
Expand Down
61 changes: 32 additions & 29 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::errors;
use crate::FnCtxt;
use rustc_ast::ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::StashKey;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
MultiSpan,
Expand All @@ -13,6 +14,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_hir::PatKind::Binding;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::traits::util::supertraits;
Expand Down Expand Up @@ -1407,48 +1409,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}

pub(crate) fn suggest_instance_call(
&self,
seg1: &hir::PathSegment<'_>,
seg2: &hir::PathSegment<'_>,
local_span: Span,
) -> bool {
/// For code `rect::area(...)`, we try to suggest `rect.area()`
/// If `rect` is a local variable and `area` is a valid assoc method for it.
pub(crate) fn suggest_instance_call(&self, path: &hir::Path<'_>) {
if path.segments.len() != 2 {
return;
}
let seg1 = &path.segments[0];
let seg2 = &path.segments[1];
let Some(mut diag) =
self.tcx.sess.diagnostic().steal_diagnostic(seg1.ident.span, StashKey::CallInstanceMethod) else { return };

let map = self.infcx.tcx.hir();
let body_id = map.body_owned_by(seg1.hir_id.owner.def_id);
let body = map.body(body_id);

struct LetVisitor<'a> {
local_span: Span,
result: Option<&'a Ty<'a>>,
result: Option<&'a hir::Expr<'a>>,
ident_name: Symbol,
}

impl<'v> Visitor<'v> for LetVisitor<'_> {
impl<'v> Visitor<'v> for LetVisitor<'v> {
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
if self.result.is_some() {
return;
}
if let hir::StmtKind::Local(hir::Local {
span, ty, init: None, ..
}) = &ex.kind && span.contains(self.local_span) {
self.result = ty;
if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind {
if let Binding(_, _, ident, ..) = pat.kind &&
ident.name == self.ident_name {
self.result = *init;
}
}
hir::intravisit::walk_stmt(self, ex);
}
}

let mut visitor = LetVisitor { local_span, result: None };
let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name };
visitor.visit_body(&body);

let parent = self.tcx.hir().get_parent_node(seg1.hir_id);
let parent_expr = self.tcx.hir().find(parent);
debug!("yukang parent_expr: {:?}", parent_expr);
let node = self.tcx.hir().get_parent_node(seg1.hir_id);
let ty = self.typeck_results.borrow().node_type_opt(node);

debug!("yukang suggest_instance_call ty: {:?}", ty);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
let Some(self_ty) = ty {
debug!("yukang trying to prob method");
let Some(expr) = visitor.result {
let self_ty = self.check_expr(expr);
let probe = self.lookup_probe(
seg1.ident.span,
seg2.ident,
Expand All @@ -1457,11 +1455,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ProbeScope::TraitsInScope,
);

if let Ok(_pick) = probe {
return true;
if probe.is_ok() {
diag.set_primary_message(format!(
"need to fix call instance method: {:?}",
seg2.ident
));
diag.emit();
} else {
diag.cancel();
}
}
return false;
}

fn check_for_field_method(
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2050,17 +2050,6 @@ impl<'a> Resolver<'a> {
);
err.span_warn(local_span, "ident is defined at here");
err.stash(ident.span, rustc_errors::StashKey::CallInstanceMethod);
/* suggestion = Some((
vec![(
sm.span_extend_while(id ent.span, |c| c == ':').unwrap(),
format!("{}.", ident),
)],
format!(
"`{}` is not a crate or module, maybe you meant to call instance method",
ident
),
Applicability::MaybeIncorrect,
)) */
}
};
(format!("use of undeclared crate or module `{}`", ident), suggestion)
Expand Down

0 comments on commit 92fbb59

Please sign in to comment.