Skip to content

Commit

Permalink
Auto merge of rust-lang#65421 - estebank:variants, r=petrochenkov
Browse files Browse the repository at this point in the history
Point at local similarly named element and tweak references to variants

Partially address rust-lang#65386.
  • Loading branch information
bors committed Oct 28, 2019
2 parents 03a50ae + b26ddb8 commit 8d78bf6
Show file tree
Hide file tree
Showing 132 changed files with 600 additions and 331 deletions.
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 @@ -849,12 +849,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 @@ -867,17 +869,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 @@ -254,18 +254,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

0 comments on commit 8d78bf6

Please sign in to comment.