Remove use of ast_map.expect_item()
and improve diagnostics (fixes #33186)
This commit is contained in:
parent
5a4e0b14e3
commit
a70e42a953
2 changed files with 49 additions and 46 deletions
|
@ -68,7 +68,7 @@ use rustc::hir::intravisit::{self, FnKind, Visitor};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
|
use rustc::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
|
||||||
use rustc::hir::Crate;
|
use rustc::hir::Crate;
|
||||||
use rustc::hir::{Expr, ExprAgain, ExprBreak, ExprCall, ExprField};
|
use rustc::hir::{Expr, ExprAgain, ExprBreak, ExprField};
|
||||||
use rustc::hir::{ExprLoop, ExprWhile, ExprMethodCall};
|
use rustc::hir::{ExprLoop, ExprWhile, ExprMethodCall};
|
||||||
use rustc::hir::{ExprPath, ExprStruct, FnDecl};
|
use rustc::hir::{ExprPath, ExprStruct, FnDecl};
|
||||||
use rustc::hir::{ForeignItemFn, ForeignItemStatic, Generics};
|
use rustc::hir::{ForeignItemFn, ForeignItemStatic, Generics};
|
||||||
|
@ -163,7 +163,7 @@ enum ResolutionError<'a> {
|
||||||
/// error E0424: `self` is not available in a static method
|
/// error E0424: `self` is not available in a static method
|
||||||
SelfNotAvailableInStaticMethod,
|
SelfNotAvailableInStaticMethod,
|
||||||
/// error E0425: unresolved name
|
/// error E0425: unresolved name
|
||||||
UnresolvedName(&'a str, &'a str, UnresolvedNameContext),
|
UnresolvedName(&'a str, &'a str, UnresolvedNameContext<'a>),
|
||||||
/// error E0426: use of undeclared label
|
/// error E0426: use of undeclared label
|
||||||
UndeclaredLabel(&'a str),
|
UndeclaredLabel(&'a str),
|
||||||
/// error E0427: cannot use `ref` binding mode with ...
|
/// error E0427: cannot use `ref` binding mode with ...
|
||||||
|
@ -186,12 +186,12 @@ enum ResolutionError<'a> {
|
||||||
|
|
||||||
/// Context of where `ResolutionError::UnresolvedName` arose.
|
/// Context of where `ResolutionError::UnresolvedName` arose.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
enum UnresolvedNameContext {
|
enum UnresolvedNameContext<'a> {
|
||||||
/// `PathIsMod(id)` indicates that a given path, used in
|
/// `PathIsMod(parent)` indicates that a given path, used in
|
||||||
/// expression context, actually resolved to a module rather than
|
/// expression context, actually resolved to a module rather than
|
||||||
/// a value. The `id` attached to the variant is the node id of
|
/// a value. The optional expression attached to the variant is the
|
||||||
/// the erroneous path expression.
|
/// the parent of the erroneous path expression.
|
||||||
PathIsMod(ast::NodeId),
|
PathIsMod(Option<&'a Expr>),
|
||||||
|
|
||||||
/// `Other` means we have no extra information about the context
|
/// `Other` means we have no extra information about the context
|
||||||
/// of the unresolved name error. (Maybe we could eliminate all
|
/// of the unresolved name error. (Maybe we could eliminate all
|
||||||
|
@ -419,39 +419,25 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||||
|
|
||||||
match context {
|
match context {
|
||||||
UnresolvedNameContext::Other => { } // no help available
|
UnresolvedNameContext::Other => { } // no help available
|
||||||
UnresolvedNameContext::PathIsMod(id) => {
|
UnresolvedNameContext::PathIsMod(parent) => {
|
||||||
let mut help_msg = String::new();
|
err.fileline_help(span, &match parent.map(|parent| &parent.node) {
|
||||||
let parent_id = resolver.ast_map.get_parent_node(id);
|
Some(&ExprField(_, ident)) => {
|
||||||
if let Some(hir_map::Node::NodeExpr(e)) = resolver.ast_map.find(parent_id) {
|
format!("To reference an item from the `{module}` module, \
|
||||||
match e.node {
|
use `{module}::{ident}`",
|
||||||
ExprField(_, ident) => {
|
module = path,
|
||||||
help_msg = format!("To reference an item from the \
|
ident = ident.node)
|
||||||
`{module}` module, use \
|
|
||||||
`{module}::{ident}`",
|
|
||||||
module = path,
|
|
||||||
ident = ident.node);
|
|
||||||
}
|
|
||||||
ExprMethodCall(ident, _, _) => {
|
|
||||||
help_msg = format!("To call a function from the \
|
|
||||||
`{module}` module, use \
|
|
||||||
`{module}::{ident}(..)`",
|
|
||||||
module = path,
|
|
||||||
ident = ident.node);
|
|
||||||
}
|
|
||||||
ExprCall(_, _) => {
|
|
||||||
help_msg = format!("No function corresponds to `{module}(..)`",
|
|
||||||
module = path);
|
|
||||||
}
|
|
||||||
_ => { } // no help available
|
|
||||||
}
|
}
|
||||||
} else {
|
Some(&ExprMethodCall(ident, _, _)) => {
|
||||||
help_msg = format!("Module `{module}` cannot be the value of an expression",
|
format!("To call a function from the `{module}` module, \
|
||||||
module = path);
|
use `{module}::{ident}(..)`",
|
||||||
}
|
module = path,
|
||||||
|
ident = ident.node)
|
||||||
if !help_msg.is_empty() {
|
}
|
||||||
err.fileline_help(span, &help_msg);
|
_ => {
|
||||||
}
|
format!("Module `{module}` cannot be used as an expression",
|
||||||
|
module = path)
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err
|
err
|
||||||
|
@ -553,7 +539,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
||||||
self.resolve_block(block);
|
self.resolve_block(block);
|
||||||
}
|
}
|
||||||
fn visit_expr(&mut self, expr: &Expr) {
|
fn visit_expr(&mut self, expr: &Expr) {
|
||||||
self.resolve_expr(expr);
|
self.resolve_expr(expr, None);
|
||||||
}
|
}
|
||||||
fn visit_local(&mut self, local: &Local) {
|
fn visit_local(&mut self, local: &Local) {
|
||||||
self.resolve_local(local);
|
self.resolve_local(local);
|
||||||
|
@ -2850,7 +2836,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
} SuggestionType::NotFound
|
} SuggestionType::NotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_expr(&mut self, expr: &Expr) {
|
fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
|
||||||
// First, record candidate traits for this expression if it could
|
// First, record candidate traits for this expression if it could
|
||||||
// result in the invocation of a method call.
|
// result in the invocation of a method call.
|
||||||
|
|
||||||
|
@ -2995,7 +2981,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
UseLexicalScope,
|
UseLexicalScope,
|
||||||
expr.span) {
|
expr.span) {
|
||||||
Success(_) => {
|
Success(_) => {
|
||||||
context = UnresolvedNameContext::PathIsMod(expr.id);
|
context = UnresolvedNameContext::PathIsMod(parent);
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
};
|
};
|
||||||
|
@ -3069,6 +3055,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExprField(ref subexpression, _) => {
|
||||||
|
self.resolve_expr(subexpression, Some(expr));
|
||||||
|
}
|
||||||
|
ExprMethodCall(_, ref types, ref arguments) => {
|
||||||
|
let mut arguments = arguments.iter();
|
||||||
|
self.resolve_expr(arguments.next().unwrap(), Some(expr));
|
||||||
|
for argument in arguments {
|
||||||
|
self.resolve_expr(argument, None);
|
||||||
|
}
|
||||||
|
for ty in types.iter() {
|
||||||
|
self.visit_ty(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
intravisit::walk_expr(self, expr);
|
intravisit::walk_expr(self, expr);
|
||||||
|
|
|
@ -47,10 +47,14 @@ fn h4() -> i32 {
|
||||||
//~| HELP To reference an item from the `a::b` module, use `a::b::J`
|
//~| HELP To reference an item from the `a::b` module, use `a::b::J`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn h5() -> i32 {
|
fn h5() {
|
||||||
a.b.f()
|
a.b.f();
|
||||||
//~^ ERROR E0425
|
//~^ ERROR E0425
|
||||||
//~| HELP To reference an item from the `a` module, use `a::b`
|
//~| HELP To reference an item from the `a` module, use `a::b`
|
||||||
|
let v = Vec::new();
|
||||||
|
v.push(a::b);
|
||||||
|
//~^ ERROR E0425
|
||||||
|
//~| HELP Module `a::b` cannot be used as an expression
|
||||||
}
|
}
|
||||||
|
|
||||||
fn h6() -> i32 {
|
fn h6() -> i32 {
|
||||||
|
@ -62,11 +66,11 @@ fn h6() -> i32 {
|
||||||
fn h7() {
|
fn h7() {
|
||||||
a::b
|
a::b
|
||||||
//~^ ERROR E0425
|
//~^ ERROR E0425
|
||||||
//~| HELP Module `a::b` cannot be the value of an expression
|
//~| HELP Module `a::b` cannot be used as an expression
|
||||||
}
|
}
|
||||||
|
|
||||||
fn h8() -> i32 {
|
fn h8() -> i32 {
|
||||||
a::b()
|
a::b()
|
||||||
//~^ ERROR E0425
|
//~^ ERROR E0425
|
||||||
//~| HELP No function corresponds to `a::b(..)`
|
//~| HELP Module `a::b` cannot be used as an expression
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue