Skip to content

Point at local similarly named element and tweak references to variants #65421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,12 +850,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
Res::Def(kind @ DefKind::Mod, def_id)
| Res::Def(kind @ DefKind::Enum, def_id)
| Res::Def(kind @ DefKind::Trait, def_id) => {
let module = self.r.new_module(parent,
ModuleKind::Def(kind, def_id, ident.name),
def_id,
expansion,
span);
self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
let module = self.r.new_module(
parent,
ModuleKind::Def(kind, def_id, ident.name),
def_id,
expansion,
span,
);
self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
}
Res::Def(DefKind::Struct, _)
| Res::Def(DefKind::Union, _)
Expand All @@ -868,17 +870,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
| Res::Def(DefKind::AssocOpaqueTy, _)
| Res::PrimTy(..)
| Res::ToolMod =>
self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)),
self.r.define(parent, ident, TypeNS, (res, vis, span, expansion)),
Res::Def(DefKind::Fn, _)
| Res::Def(DefKind::Method, _)
| Res::Def(DefKind::Static, _)
| Res::Def(DefKind::Const, _)
| Res::Def(DefKind::AssocConst, _)
| Res::Def(DefKind::Ctor(..), _) =>
self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)),
self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)),
Res::Def(DefKind::Macro(..), _)
| Res::NonMacroAttr(..) =>
self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)),
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion)),
Res::Def(DefKind::TyParam, _) | Res::Def(DefKind::ConstParam, _)
| Res::Local(..) | Res::SelfTy(..) | Res::SelfCtor(..) | Res::Err =>
bug!("unexpected resolution: {:?}", res)
Expand Down
44 changes: 28 additions & 16 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,6 @@ fn reduce_impl_span_to_impl_keyword(cm: &SourceMap, impl_span: Span) -> Span {
impl_span
}

crate fn add_typo_suggestion(
err: &mut DiagnosticBuilder<'_>, suggestion: Option<TypoSuggestion>, span: Span
) -> bool {
if let Some(suggestion) = suggestion {
let msg = format!(
"{} {} with a similar name exists", suggestion.res.article(), suggestion.res.descr()
);
err.span_suggestion(
span, &msg, suggestion.candidate.to_string(), Applicability::MaybeIncorrect
);
return true;
}
false
}

impl<'a> Resolver<'a> {
crate fn add_module_candidates(
&mut self,
Expand Down Expand Up @@ -641,7 +626,7 @@ impl<'a> Resolver<'a> {
let suggestion = self.early_lookup_typo_candidate(
ScopeSet::Macro(macro_kind), parent_scope, ident, is_expected
);
add_typo_suggestion(err, suggestion, ident.span);
self.add_typo_suggestion(err, suggestion, ident.span);

if macro_kind == MacroKind::Derive &&
(ident.as_str() == "Send" || ident.as_str() == "Sync") {
Expand All @@ -652,6 +637,33 @@ impl<'a> Resolver<'a> {
err.help("have you added the `#[macro_use]` on the module/import?");
}
}

crate fn add_typo_suggestion(
&self,
err: &mut DiagnosticBuilder<'_>,
suggestion: Option<TypoSuggestion>,
span: Span,
) -> bool {
if let Some(suggestion) = suggestion {
let msg = format!(
"{} {} with a similar name exists", suggestion.res.article(), suggestion.res.descr()
);
err.span_suggestion(
span, &msg, suggestion.candidate.to_string(), Applicability::MaybeIncorrect
);
let def_span = suggestion.res.opt_def_id()
.and_then(|def_id| self.definitions.opt_span(def_id));
if let Some(span) = def_span {
err.span_label(span, &format!(
"similarly named {} `{}` defined here",
suggestion.res.descr(),
suggestion.candidate.as_str(),
));
}
return true;
}
false
}
}

impl<'a, 'b> ImportResolver<'a, 'b> {
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_resolve/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,7 @@ function:
struct Foo { a: bool };

let f = Foo();
// error: expected function, found `Foo`
// error: expected function, tuple struct or tuple variant, found `Foo`
// `Foo` is a struct name, but this expression uses it like a function name
```

Expand All @@ -992,7 +992,8 @@ yield this error:

```compile_fail,E0423
println("");
// error: expected function, found macro `println`
// error: expected function, tuple struct or tuple variant,
// found macro `println`
// did you mean `println!(...)`? (notice the trailing `!`)
```

Expand Down Expand Up @@ -1592,7 +1593,7 @@ enum State {

fn print_on_failure(state: &State) {
match *state {
// error: expected unit struct/variant or constant, found tuple
// error: expected unit struct, unit variant or constant, found tuple
// variant `State::Failed`
State::Failed => println!("Failed"),
_ => ()
Expand Down
25 changes: 20 additions & 5 deletions src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,36 @@ impl<'a> PathSource<'a> {
}

fn descr_expected(self) -> &'static str {
match self {
match &self {
PathSource::Type => "type",
PathSource::Trait(_) => "trait",
PathSource::Pat => "unit struct/variant or constant",
PathSource::Pat => "unit struct, unit variant or constant",
PathSource::Struct => "struct, variant or union type",
PathSource::TupleStruct => "tuple struct/variant",
PathSource::TupleStruct => "tuple struct or tuple variant",
PathSource::TraitItem(ns) => match ns {
TypeNS => "associated type",
ValueNS => "method or associated constant",
MacroNS => bug!("associated macro"),
},
PathSource::Expr(parent) => match parent.map(|p| &p.kind) {
PathSource::Expr(parent) => match &parent.as_ref().map(|p| &p.kind) {
// "function" here means "anything callable" rather than `DefKind::Fn`,
// this is not precise but usually more helpful than just "value".
Some(&ExprKind::Call(..)) => "function",
Some(ExprKind::Call(call_expr, _)) => {
match &call_expr.kind {
ExprKind::Path(_, path) => {
let mut msg = "function";
if let Some(segment) = path.segments.iter().last() {
if let Some(c) = segment.ident.to_string().chars().next() {
if c.is_uppercase() {
msg = "function, tuple struct or tuple variant";
}
}
}
msg
}
_ => "function"
}
}
_ => "value",
},
}
Expand Down
21 changes: 11 additions & 10 deletions src/librustc_resolve/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
use crate::path_names_to_string;
use crate::diagnostics::{add_typo_suggestion, ImportSuggestion, TypoSuggestion};
use crate::diagnostics::{ImportSuggestion, TypoSuggestion};
use crate::late::{LateResolutionVisitor, RibKind};

use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
Expand Down Expand Up @@ -237,18 +237,19 @@ impl<'a> LateResolutionVisitor<'a, '_> {
}

// Try Levenshtein algorithm.
let levenshtein_worked = add_typo_suggestion(
&mut err, self.lookup_typo_candidate(path, ns, is_expected, span), ident_span
);
let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected, span);
let levenshtein_worked = self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span);

// Try context-dependent help if relaxed lookup didn't work.
if let Some(res) = res {
if self.smart_resolve_context_dependent_help(&mut err,
span,
source,
res,
&path_str,
&fallback_label) {
if self.smart_resolve_context_dependent_help(
&mut err,
span,
source,
res,
&path_str,
&fallback_label,
) {
return (err, candidates);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,7 @@ pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], i

fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
span_err!(tcx.sess, span, E0533,
"expected unit struct/variant or constant, found {} `{}`",
"expected unit struct, unit variant or constant, found {} `{}`",
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
}
Expand Down
8 changes: 5 additions & 3 deletions src/librustc_typeck/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
let report_unexpected_res = |res: Res| {
let msg = format!("expected tuple struct/variant, found {} `{}`",
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
let msg = format!(
"expected tuple struct or tuple variant, found {} `{}`",
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)),
);
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
match (res, &pat.kind) {
(Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_typeck/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4346,11 +4346,12 @@ enum X {
Entry,
}

X::Entry(); // error: expected function, found `X::Entry`
X::Entry(); // error: expected function, tuple struct or tuple variant,
// found `X::Entry`

// Or even simpler:
let x = 0i32;
x(); // error: expected function, found `i32`
x(); // error: expected function, tuple struct or tuple variant, found `i32`
```

Only functions and methods can be called using `()`. Example:
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/associated-types/associated-types-eq-1.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0412]: cannot find type `A` in this scope
--> $DIR/associated-types-eq-1.rs:10:12
|
LL | fn foo2<I: Foo>(x: I) {
| - similarly named type parameter `I` defined here
LL | let _: A = x.boo();
| ^ help: a type parameter with a similar name exists: `I`

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/class-missing-self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ impl Cat {
fn meow(&self) {
println!("Meow");
meows += 1; //~ ERROR cannot find value `meows` in this scope
sleep(); //~ ERROR cannot find function `sleep` in this scope
sleep(); //~ ERROR cannot find function `sleep` in this
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ error[E0573]: expected type, found const parameter `C`
--> $DIR/struct-with-invalid-const-param.rs:4:23
|
LL | struct S<const C: u8>(C);
| ^ help: a struct with a similar name exists: `S`
| ----------------------^--
| | |
| | help: a struct with a similar name exists: `S`
| similarly named struct `S` defined here

warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/struct-with-invalid-const-param.rs:1:12
Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ enum ManyVariants {
}

fn result_test() {
let x = Option(1); //~ ERROR expected function, found enum
let x = Option(1); //~ ERROR expected function, tuple struct or tuple variant, found enum

if let Option(_) = x { //~ ERROR expected tuple struct/variant, found enum
if let Option(_) = x { //~ ERROR expected tuple struct or tuple variant, found enum
println!("It is OK.");
}

let y = Example::Ex(String::from("test"));

if let Example(_) = y { //~ ERROR expected tuple struct/variant, found enum
if let Example(_) = y { //~ ERROR expected tuple struct or tuple variant, found enum
println!("It is OK.");
}

let y = Void(); //~ ERROR expected function, found enum
let y = Void(); //~ ERROR expected function, tuple struct or tuple variant, found enum

let z = ManyVariants(); //~ ERROR expected function, found enum
let z = ManyVariants(); //~ ERROR expected function, tuple struct or tuple variant, found enum
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0423]: expected function, found enum `Option`
error[E0423]: expected function, tuple struct or tuple variant, found enum `Option`
--> $DIR/issue-43871-enum-instead-of-variant.rs:19:13
|
LL | let x = Option(1);
Expand All @@ -11,7 +11,7 @@ LL | let x = std::option::Option::None(1);
LL | let x = std::option::Option::Some(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0532]: expected tuple struct/variant, found enum `Option`
error[E0532]: expected tuple struct or tuple variant, found enum `Option`
--> $DIR/issue-43871-enum-instead-of-variant.rs:21:12
|
LL | if let Option(_) = x {
Expand All @@ -24,7 +24,7 @@ LL | if let std::option::Option::None(_) = x {
LL | if let std::option::Option::Some(_) = x {
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0532]: expected tuple struct/variant, found enum `Example`
error[E0532]: expected tuple struct or tuple variant, found enum `Example`
--> $DIR/issue-43871-enum-instead-of-variant.rs:27:12
|
LL | if let Example(_) = y {
Expand All @@ -37,13 +37,13 @@ LL | if let Example::Ex(_) = y {
LL | if let Example::NotEx(_) = y {
| ^^^^^^^^^^^^^^

error[E0423]: expected function, found enum `Void`
error[E0423]: expected function, tuple struct or tuple variant, found enum `Void`
--> $DIR/issue-43871-enum-instead-of-variant.rs:31:13
|
LL | let y = Void();
| ^^^^

error[E0423]: expected function, found enum `ManyVariants`
error[E0423]: expected function, tuple struct or tuple variant, found enum `ManyVariants`
--> $DIR/issue-43871-enum-instead-of-variant.rs:33:13
|
LL | let z = ManyVariants();
Expand Down
9 changes: 6 additions & 3 deletions src/test/ui/empty/empty-struct-braces-expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ enum E {

fn main() {
let e1 = Empty1; //~ ERROR expected value, found struct `Empty1`
let e1 = Empty1(); //~ ERROR expected function, found struct `Empty1`
let e1 = Empty1();
//~^ ERROR expected function, tuple struct or tuple variant, found struct `Empty1`
let e3 = E::Empty3; //~ ERROR expected value, found struct variant `E::Empty3`
let e3 = E::Empty3(); //~ ERROR expected function, found struct variant `E::Empty3`
let e3 = E::Empty3();
//~^ ERROR expected function, tuple struct or tuple variant, found struct variant `E::Empty3`

let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1`
let xe1 = XEmpty1();
//~^ ERROR expected function, tuple struct or tuple variant, found struct `XEmpty1`
let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for type
let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for type

Expand Down
Loading