diff options
| author | bors <bors@rust-lang.org> | 2016-12-26 13:32:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-26 13:32:13 +0000 |
| commit | 65c043fdd291a9e683b834c800204ec68c9988f1 (patch) | |
| tree | 69ad7b800bf171a6117dae0efaace2f1839253df | |
| parent | 8493dbed6c29b30844830d6e50a33493c6ea70af (diff) | |
| parent | 09aba18e109d7246e3b61c6642747139ee116c48 (diff) | |
| download | rust-65c043fdd291a9e683b834c800204ec68c9988f1.tar.gz rust-65c043fdd291a9e683b834c800204ec68c9988f1.zip | |
Auto merge of #38154 - petrochenkov:altname, r=jseyfried
More systematic error reporting in path resolution
Path resolution for types, expressions and patterns used various heuristics to give more helpful messages on unresolved or incorrectly resolved paths.
This PR combines these heuristics and applies them to all non-import paths.
First a path is resolved in all namespaces, starting from its primary namespace (to give messages like "expected function, found macro, you probably forgot `!`").
If this resolution doesn't give a desired result we create a base error - either "path is not resolved" or "path is resolved, but the resolution is not acceptable in this context".
Other helps and notes are applied to this base error using heuristics.
Here's the list of heuristics for a path with a last segment `name` in order.
First we issue special messages for unresolved `Self` and `self`.
Second we try to find free items named `name` in other modules and suggest to import them.
Then we try to find fields and associated items named `name` and suggest `self.name` or `Self::name`.
After that we try several deterministic context dependent heuristics like "expected value, found struct, you probably forgot `{}`".
If nothing of the above works we try to find candidates with other names using Levenshtein distance.
---
Some alternatives/notes/unresolved questions:
- ~~I had a strong desire to migrate all affected tests to `test/ui`, diagnostics comparison becomes much more meaningful, but I did this only for few tests so far.~~ (Done)
- ~~Labels for "unresolved path" errors are mostly useless now, it may make sense to move some help/notes to these labels, help becomes closer to the error this way.~~ (Done)
- ~~Currently only the first successful heuristic results in additional message shown to the user, it may make sense to print them all, they are rarely compatible, so the diagnostics bloat is unlikely.~~ (Done)
- Now when https://github.com/rust-lang/rust/pull/38014 landed `resolve_path` can potentially be replaced with `smart_resolve_path` in couple more places - e.g. ~~visibilities~~ (done), ~~import prefixes~~ (done), HIR paths.
---
Some additional fixes:
- Associated suggestions and typo suggestions are filtered with a context specific predicate to avoid inapplicable suggestions.
- `adjust_local_def` works properly in speculative resolution.
- I also fixed a recently introduced ICE in partially resolved UFCS paths (see test `ufcs-partially-resolved.rs`). Minimal reproduction:
```
enum E {}
fn main() {
<u8 as E>::A;
}
```
Fixes https://github.com/rust-lang/rust/issues/38409, fixes https://github.com/rust-lang/rust/issues/38504 (duplicates).
- Some bugs in resolution of visibilities are fixed - `pub(Enum)`, `pub(Trait)`, `pub(non::local::path)`.
- Fixes https://github.com/rust-lang/rust/issues/38012.
---
r? @jseyfried for technical details + @jonathandturner for diagnostics changes
How to read the patch: `smart_resolve_path(_fragment)/resolve_qpath_anywhere` are written anew and replace `resolve_trait_reference`/`resolve_type`/`resolve_pattern_path`/`resolve_struct_path`/`resolve_expr` for `ExprKind::Path`, everything else can be read as a diff.
164 files changed, 2291 insertions, 1335 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 9f9c6fd87aa..d0003693eef 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -298,8 +298,7 @@ pub trait CrateStore<'tcx> { // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option<DefId>; - fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<ty::AssociatedItem>; + fn associated_item(&self, def: DefId) -> Option<ty::AssociatedItem>; // flags fn is_const_fn(&self, did: DefId) -> bool; @@ -456,8 +455,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") } - fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<ty::AssociatedItem> { bug!("associated_item") } + fn associated_item(&self, def: DefId) -> Option<ty::AssociatedItem> { bug!("associated_item") } // flags fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 89e976598bf..2ab10d0446b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2071,7 +2071,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn associated_item(self, def_id: DefId) -> AssociatedItem { self.associated_items.memoize(def_id, || { if !def_id.is_local() { - return self.sess.cstore.associated_item(self.global_tcx(), def_id) + return self.sess.cstore.associated_item(def_id) .expect("missing AssociatedItem in metadata"); } @@ -2526,8 +2526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// ID of the impl that the method belongs to. Otherwise, return `None`. pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> { if def_id.krate != LOCAL_CRATE { - return self.sess.cstore.associated_item(self.global_tcx(), def_id) - .and_then(|item| { + return self.sess.cstore.associated_item(def_id).and_then(|item| { match item.container { TraitContainer(_) => None, ImplContainer(def_id) => Some(def_id), diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5c96d7f1826..0ac3ffd5cb9 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -188,8 +188,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index) } - fn associated_item<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<ty::AssociatedItem> + fn associated_item(&self, def: DefId) -> Option<ty::AssociatedItem> { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_associated_item(def.index) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 758b93aed67..1b3791355d2 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -417,28 +417,18 @@ impl<'a> Resolver<'a> { let ident = Ident::with_empty_ctxt(child.name); let def = child.def; let def_id = def.def_id(); - let vis = match def { - Def::Macro(..) => ty::Visibility::Public, - _ if parent.is_trait() => ty::Visibility::Public, - _ => self.session.cstore.visibility(def_id), - }; + let vis = self.session.cstore.visibility(def_id); match def { Def::Mod(..) | Def::Enum(..) => { let module = self.new_module(parent, ModuleKind::Def(def, ident.name), def_id); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root())); } - Def::Variant(..) => { + Def::Variant(..) | Def::TyAlias(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root())); } - Def::VariantCtor(..) => { - self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root())); - } - Def::Fn(..) | - Def::Static(..) | - Def::Const(..) | - Def::AssociatedConst(..) | - Def::Method(..) => { + Def::Fn(..) | Def::Static(..) | Def::Const(..) | + Def::VariantCtor(..) | Def::StructCtor(..) => { self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root())); } Def::Trait(..) => { @@ -446,29 +436,19 @@ impl<'a> Resolver<'a> { let module = self.new_module(parent, module_kind, parent.normal_ancestor_id); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root())); - // If this is a trait, add all the trait item names to the trait info. - let trait_item_def_ids = self.session.cstore.associated_item_def_ids(def_id); - for trait_item_def_id in trait_item_def_ids { - let trait_item_name = self.session.cstore.def_key(trait_item_def_id) - .disambiguated_data.data.get_opt_name() - .expect("opt_item_name returned None for trait"); - self.trait_item_map.insert((trait_item_name, def_id), false); - } - } - Def::TyAlias(..) | Def::AssociatedTy(..) => { - self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root())); - } - Def::Struct(..) => { - self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root())); + for child in self.session.cstore.item_children(def_id) { + let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS }; + let ident = Ident::with_empty_ctxt(child.name); + self.define(module, ident, ns, (child.def, ty::Visibility::Public, + DUMMY_SP, Mark::root())); - // Record field names for error reporting. - let field_names = self.session.cstore.struct_field_names(def_id); - self.insert_field_names(def_id, field_names); - } - Def::StructCtor(..) => { - self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root())); + let has_self = self.session.cstore.associated_item(child.def.def_id()) + .map_or(false, |item| item.method_has_self_argument); + self.trait_item_map.insert((def_id, child.name, ns), (child.def, has_self)); + } + module.populated.set(true); } - Def::Union(..) => { + Def::Struct(..) | Def::Union(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root())); // Record field names for error reporting. @@ -478,15 +458,7 @@ impl<'a> Resolver<'a> { Def::Macro(..) => { self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, Mark::root())); } - Def::Local(..) | - Def::PrimTy(..) | - Def::TyParam(..) | - Def::Upvar(..) | - Def::Label(..) | - Def::SelfTy(..) | - Def::Err => { - bug!("unexpected definition: {:?}", def); - } + _ => bug!("unexpected definition: {:?}", def) } } @@ -751,18 +723,15 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { // Add the item to the trait info. let item_def_id = self.resolver.definitions.local_def_id(item.id); - let mut is_static_method = false; - let (def, ns) = match item.node { - TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS), - TraitItemKind::Method(ref sig, _) => { - is_static_method = !sig.decl.has_self(); - (Def::Method(item_def_id), ValueNS) - } - TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS), + let (def, ns, has_self) = match item.node { + TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS, false), + TraitItemKind::Method(ref sig, _) => + (Def::Method(item_def_id), ValueNS, sig.decl.has_self()), + TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS, false), TraitItemKind::Macro(_) => bug!(), // handled above }; - self.resolver.trait_item_map.insert((item.ident.name, def_id), is_static_method); + self.resolver.trait_item_map.insert((def_id, item.ident.name, ns), (def, has_self)); let vis = ty::Visibility::Public; self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion)); diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index d54f4e7b20c..2fada8a9ec2 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -860,6 +860,26 @@ match (A, B, C) { ``` "##, +E0422: r##" +You are trying to use an identifier that is either undefined or not a struct. +Erroneous code example: +``` compile_fail,E0422 +fn main () { + let x = Foo { x: 1, y: 2 }; +} +``` +In this case, `Foo` is undefined, so it inherently isn't anything, and +definitely not a struct. +```compile_fail +fn main () { + let foo = 1; + let x = foo { x: 1, y: 2 }; +} +``` +In this case, `foo` is defined, but is not a struct, so Rust can't use it as +one. +"##, + E0423: r##" A `struct` variant name was used like a function name. @@ -1519,7 +1539,12 @@ register_diagnostics! { // E0419, merged into 531 // E0420, merged into 532 // E0421, merged into 531 -// E0422, merged into 531/532 E0531, // unresolved pattern path kind `name` // E0427, merged into 530 + E0573, + E0574, + E0575, + E0576, + E0577, + E0578, } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 905d77eed31..a0af4c45653 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -33,7 +33,6 @@ extern crate arena; extern crate rustc; use self::Namespace::*; -use self::FallbackSuggestion::*; use self::TypeParameters::*; use self::RibKind::*; @@ -83,16 +82,16 @@ mod check_unused; mod build_reduced_graph; mod resolve_imports; -enum SuggestionType { - Macro(String), - Function(Symbol), - NotFound, +/// A free importable items suggested in case of resolution failure. +struct ImportSuggestion { + path: Path, } -/// Candidates for a name resolution failure -struct SuggestedCandidates { - name: String, - candidates: Vec<Path>, +/// A field or associated item from self type suggested in case of resolution failure. +enum AssocSuggestion { + Field, + MethodWithSelf, + AssocItem, } enum ResolutionError<'a> { @@ -102,10 +101,6 @@ enum ResolutionError<'a> { OuterTypeParameterContext, /// error E0403: the name is already used for a type parameter in this type parameter list NameAlreadyUsedInTypeParameterList(Name, &'a Span), - /// error E0404: is not a trait - IsNotATrait(&'a str, &'a str), - /// error E0405: use of undeclared trait name - UndeclaredTraitName(&'a str, SuggestedCandidates), /// error E0407: method is not a member of trait MethodNotMemberOfTrait(Name, &'a str), /// error E0437: type is not a member of trait @@ -116,27 +111,10 @@ enum ResolutionError<'a> { VariableNotBoundInPattern(Name, usize, usize), /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1 VariableBoundWithDifferentMode(Name, usize, Span), - /// error E0411: use of `Self` outside of an impl or trait - SelfUsedOutsideImplOrTrait, - /// error E0412: use of undeclared - UseOfUndeclared(&'a str, &'a str, SuggestedCandidates), /// error E0415: identifier is bound more than once in this parameter list IdentifierBoundMoreThanOnceInParameterList(&'a str), /// error E0416: identifier is bound more than once in the same pattern IdentifierBoundMoreThanOnceInSamePattern(&'a str), - /// error E0423: is a struct variant name, but this expression uses it like a function name - StructVariantUsedAsFunction(&'a str), - /// error E0424: `self` is not available in a static method - SelfNotAvailableInStaticMethod, - /// error E0425: unresolved name - UnresolvedName { - path: &'a str, - message: &'a str, - context: UnresolvedNameContext<'a>, - is_static_method: bool, - is_field: bool, - def: Def, - }, /// error E0426: use of undeclared label UndeclaredLabel(&'a str), /// error E0429: `self` imports are only allowed within a { } list @@ -155,37 +133,18 @@ enum ResolutionError<'a> { AttemptToUseNonConstantValueInConstant, /// error E0530: X bindings cannot shadow Ys BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>), - /// error E0531: unresolved pattern path kind `name` - PatPathUnresolved(&'a str, &'a Path), - /// error E0532: expected pattern path kind, found another pattern path kind - PatPathUnexpected(&'a str, &'a str, &'a Path), -} - -/// Context of where `ResolutionError::UnresolvedName` arose. -#[derive(Clone, PartialEq, Eq, Debug)] -enum UnresolvedNameContext<'a> { - /// `PathIsMod(parent)` indicates that a given path, used in - /// expression context, actually resolved to a module rather than - /// a value. The optional expression attached to the variant is the - /// the parent of the erroneous path expression. - PathIsMod(Option<&'a Expr>), - - /// `Other` means we have no extra information about the context - /// of the unresolved name error. (Maybe we could eliminate all - /// such cases; but for now, this is an information-free default.) - Other, } -fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, - span: syntax_pos::Span, - resolution_error: ResolutionError<'c>) { +fn resolve_error<'sess, 'a>(resolver: &'sess Resolver, + span: Span, + resolution_error: ResolutionError<'a>) { resolve_struct_error(resolver, span, resolution_error).emit(); } -fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, - span: syntax_pos::Span, - resolution_error: ResolutionError<'c>) - -> DiagnosticBuilder<'a> { +fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, + span: Span, + resolution_error: ResolutionError<'a>) + -> DiagnosticBuilder<'sess> { match resolution_error { ResolutionError::TypeParametersFromOuterFunction => { let mut err = struct_span_err!(resolver.session, @@ -212,26 +171,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(span, &format!("already used")); err.span_label(first_use_span.clone(), &format!("first use of `{}`", name)); err - - } - ResolutionError::IsNotATrait(name, kind_name) => { - let mut err = struct_span_err!(resolver.session, - span, - E0404, - "`{}` is not a trait", - name); - err.span_label(span, &format!("expected trait, found {}", kind_name)); - err - } - ResolutionError::UndeclaredTraitName(name, candidates) => { - let mut err = struct_span_err!(resolver.session, - span, - E0405, - "trait `{}` is not in scope", - name); - show_candidates(&mut err, &candidates); - err.span_label(span, &format!("`{}` is not in scope", name)); - err } ResolutionError::MethodNotMemberOfTrait(method, trait_) => { let mut err = struct_span_err!(resolver.session, @@ -288,25 +227,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(first_binding_span, &format!("first binding")); err } - ResolutionError::SelfUsedOutsideImplOrTrait => { - let mut err = struct_span_err!(resolver.session, - span, - E0411, - "use of `Self` outside of an impl or trait"); - err.span_label(span, &format!("used outside of impl or trait")); - err - } - ResolutionError::UseOfUndeclared(kind, name, candidates) => { - let mut err = struct_span_err!(resolver.session, - span, - E0412, - "{} `{}` is undefined or not in scope", - kind, - name); - show_candidates(&mut err, &candidates); - err.span_label(span, &format!("undefined or not in scope")); - err - } ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { let mut err = struct_span_err!(resolver.session, span, @@ -325,69 +245,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(span, &format!("used in a pattern more than once")); err } - ResolutionError::StructVariantUsedAsFunction(path_name) => { - let mut err = struct_span_err!(resolver.session, - span, - E0423, - "`{}` is the name of a struct or struct variant, but this expression \ - uses it like a function name", - path_name); - err.span_label(span, &format!("struct called like a function")); - err - } - ResolutionError::SelfNotAvailableInStaticMethod => { - let mut err = struct_span_err!(resolver.session, - span, - E0424, - "`self` is not available in a static method"); - err.span_label(span, &format!("not available in static method")); - err.note(&format!("maybe a `self` argument is missing?")); - err - } - ResolutionError::UnresolvedName { path, message: msg, context, is_static_method, - is_field, def } => { - let mut err = struct_span_err!(resolver.session, - span, - E0425, - "unresolved name `{}`", - path); - if msg != "" { - err.span_label(span, &msg); - } else { - err.span_label(span, &format!("unresolved name")); - } - - match context { - UnresolvedNameContext::Other => { - if msg.is_empty() && is_static_method && is_field { - err.help("this is an associated function, you don't have access to \ - this type's fields or methods"); - } - } - UnresolvedNameContext::PathIsMod(parent) => { - err.help(&match parent.map(|parent| &parent.node) { - Some(&ExprKind::Field(_, ident)) => { - format!("to reference an item from the `{module}` module, \ - use `{module}::{ident}`", - module = path, - ident = ident.node) - } - Some(&ExprKind::MethodCall(ident, ..)) => { - format!("to call a function from the `{module}` module, \ - use `{module}::{ident}(..)`", - module = path, - ident = ident.node) - } - _ => { - format!("{def} `{module}` cannot be used as an expression", - def = def.kind_name(), - module = path) - } - }); - } - } - err - } ResolutionError::UndeclaredLabel(name) => { let mut err = struct_span_err!(resolver.session, span, @@ -462,23 +319,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(binding.span, msg); err } - ResolutionError::PatPathUnresolved(expected_what, path) => { - struct_span_err!(resolver.session, - span, - E0531, - "unresolved {} `{}`", - expected_what, - path) - } - ResolutionError::PatPathUnexpected(expected_what, found_what, path) => { - struct_span_err!(resolver.session, - span, - E0532, - "expected {}, found {} `{}`", - expected_what, - found_what, - path) - } } } @@ -520,6 +360,163 @@ impl PatternSource { } } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum PathSource<'a> { + // Type paths `Path`. + Type, + // Trait paths in bounds or impls. + Trait, + // Expression paths `path`, with optional parent context. + Expr(Option<&'a ExprKind>), + // Paths in path patterns `Path`. + Pat, + // Paths in struct expressions and patterns `Path { .. }`. + Struct, + // Paths in tuple struct patterns `Path(..)`. + TupleStruct, + // `m::A::B` in `<T as m::A>::B::C`. + TraitItem(Namespace), + // Path in `pub(path)` + Visibility, + // Path in `use a::b::{...};` + ImportPrefix, +} + +impl<'a> PathSource<'a> { + fn namespace(self) -> Namespace { + match self { + PathSource::Type | PathSource::Trait | PathSource::Struct | + PathSource::Visibility | PathSource::ImportPrefix => TypeNS, + PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS, + PathSource::TraitItem(ns) => ns, + } + } + + fn global_by_default(self) -> bool { + match self { + PathSource::Visibility | PathSource::ImportPrefix => true, + PathSource::Type | PathSource::Expr(..) | PathSource::Pat | + PathSource::Struct | PathSource::TupleStruct | + PathSource::Trait | PathSource::TraitItem(..) => false, + } + } + + fn defer_to_typeck(self) -> bool { + match self { + PathSource::Type | PathSource::Expr(..) | PathSource::Pat | + PathSource::Struct | PathSource::TupleStruct => true, + PathSource::Trait | PathSource::TraitItem(..) | + PathSource::Visibility | PathSource::ImportPrefix => false, + } + } + + fn descr_expected(self) -> &'static str { + match self { + PathSource::Type => "type", + PathSource::Trait => "trait", + PathSource::Pat => "unit struct/variant or constant", + PathSource::Struct => "struct, variant or union type", + PathSource::TupleStruct => "tuple struct/variant", + PathSource::Visibility => "module", + PathSource::ImportPrefix => "module or enum", + PathSource::TraitItem(ns) => match ns { + TypeNS => "associated type", + ValueNS => "method or associated constant", + MacroNS => bug!("associated macro"), + }, + PathSource::Expr(parent) => match parent { + // "function" here means "anything callable" rather than `Def::Fn`, + // this is not precise but usually more helpful than just "value". + Some(&ExprKind::Call(..)) => "function", + _ => "value", + }, + } + } + + fn is_expected(self, def: Def) -> bool { + match self { + PathSource::Type => match def { + Def::Struct(..) | Def::Union(..) | Def::Enum(..) | + Def::Trait(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | + Def::PrimTy(..) | Def::TyParam(..) | Def::SelfTy(..) => true, + _ => false, + }, + PathSource::Trait => match def { + Def::Trait(..) => true, + _ => false, + }, + PathSource::Expr(..) => match def { + Def::StructCtor(_, CtorKind::Const) | Def::StructCtor(_, CtorKind::Fn) | + Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) | + Def::Const(..) | Def::Static(..) | Def::Local(..) | Def::Upvar(..) | + Def::Fn(..) | Def::Method(..) | Def::AssociatedConst(..) => true, + _ => false, + }, + PathSource::Pat => match def { + Def::StructCtor(_, CtorKind::Const) | + Def::VariantCtor(_, CtorKind::Const) | + Def::Const(..) | Def::AssociatedConst(..) => true, + _ => false, + }, + PathSource::TupleStruct => match def { + Def::StructCtor(_, CtorKind::Fn) | Def::VariantCtor(_, CtorKind::Fn) => true, + _ => false, + }, + PathSource::Struct => match def { + Def::Struct(..) | Def::Union(..) | Def::Variant(..) | + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true, + _ => false, + }, + PathSource::TraitItem(ns) => match def { + Def::AssociatedConst(..) | Def::Method(..) if ns == ValueNS => true, + Def::AssociatedTy(..) if ns == TypeNS => true, + _ => false, + }, + PathSource::ImportPrefix => match def { + Def::Mod(..) | Def::Enum(..) => true, + _ => false, + }, + PathSource::Visibility => match def { + Def::Mod(..) => true, + _ => false, + }, + } + } + + fn error_code(self, has_unexpected_resolution: bool) -> &'static str { + __diagnostic_used!(E0404); + __diagnostic_used!(E0405); + __diagnostic_used!(E0412); + __diagnostic_used!(E0422); + __diagnostic_used!(E0423); + __diagnostic_used!(E0425); + __diagnostic_used!(E0531); + __diagnostic_used!(E0532); + __diagnostic_used!(E0573); + __diagnostic_used!(E0574); + __diagnostic_used!(E0575); + __diagnostic_used!(E0576); + __diagnostic_used!(E0577); + __diagnostic_used!(E0578); + match (self, has_unexpected_resolution) { + (PathSource::Trait, true) => "E0404", + (PathSource::Trait, false) => "E0405", + (PathSource::Type, true) => "E0573", + (PathSource::Type, false) => "E0412", + (PathSource::Struct, true) => "E0574", + (PathSource::Struct, false) => "E0422", + (PathSource::Expr(..), true) => "E0423", + (PathSource::Expr(..), false) => "E0425", + (PathSource::Pat, true) | (PathSource::TupleStruct, true) => "E0532", + (PathSource::Pat, false) | (PathSource::TupleStruct, false) => "E0531", + (PathSource::TraitItem(..), true) => "E0575", + (PathSource::TraitItem(..), false) => "E0576", + (PathSource::Visibility, true) | (PathSource::ImportPrefix, true) => "E0577", + (PathSource::Visibility, false) | (PathSource::ImportPrefix, false) => "E0578", + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Namespace { TypeNS, @@ -572,15 +569,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { self.resolve_local(local); } fn visit_ty(&mut self, ty: &'tcx Ty) { - self.resolve_type(ty); + if let TyKind::Path(ref qself, ref path) = ty.node { + self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); + } + visit::walk_ty(self, ty); } fn visit_poly_trait_ref(&mut self, tref: &'tcx ast::PolyTraitRef, m: &'tcx ast::TraitBoundModifier) { - let ast::Path { ref segments, span } = tref.trait_ref.path; - let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect(); - let def = self.resolve_trait_reference(&path, None, span); - self.record_def(tref.trait_ref.ref_id, def); + self.smart_resolve_path(tref.trait_ref.ref_id, None, + &tref.trait_ref.path, PathSource::Trait); visit::walk_poly_trait_ref(self, tref, m); } fn visit_variant(&mut self, @@ -666,13 +664,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { pub type ErrorMessage = Option<(Span, String)>; -enum FallbackSuggestion { - NoSuggestion, - Field, - TraitItem, - TraitMethod(String), -} - #[derive(Copy, Clone)] enum TypeParameters<'a, 'b> { NoTypeParameters, @@ -732,7 +723,7 @@ impl<'a> Rib<'a> { } /// A definition along with the index of the rib it was found on -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] struct LocalDef { ribs: Option<(Namespace, usize)>, def: Def, @@ -1025,7 +1016,7 @@ pub struct Resolver<'a> { prelude: Option<Module<'a>>, - trait_item_map: FxHashMap<(Name, DefId), bool /* is static method? */>, + trait_item_map: FxHashMap<(DefId, Name, Namespace), (Def, bool /* has self */)>, // Names of fields of an item `DefId` accessible with dot syntax. // Used for hints during error reporting. @@ -1391,11 +1382,9 @@ impl<'a> Resolver<'a> { for i in (0 .. self.ribs[ns].len()).rev() { if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() { // The ident resolves to a type parameter or local variable. - return Some(LexicalScopeBinding::Def(if let Some(span) = record_used { - self.adjust_local_def(LocalDef { ribs: Some((ns, i)), def: def }, span) - } else { - def - })); + return Some(LexicalScopeBinding::Def( + self.adjust_local_def(LocalDef { ribs: Some((ns, i)), def: def }, record_used) + )); } if let ModuleRibKind(module) = self.ribs[ns][i].kind { @@ -1521,7 +1510,7 @@ impl<'a> Resolver<'a> { } ItemKind::DefaultImpl(_, ref trait_ref) => { - self.with_optional_trait_ref(Some(trait_ref), |_, _| {}, None); + self.with_optional_trait_ref(Some(trait_ref), |_, _| {}); } ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => self.resolve_implementation(generics, @@ -1586,33 +1575,9 @@ impl<'a> Resolver<'a> { ItemKind::Use(ref view_path) => { match view_path.node { - ast::ViewPathList(ref prefix, ref items) => { - let path: Vec<_> = - prefix.segments.iter().map(|seg| seg.identifier).collect(); - // Resolve prefix of an import with empty braces (issue #28388) - if items.is_empty() && !prefix.segments.is_empty() { - let span = prefix.span; - // FIXME(#38012) This should be a module path, not anything in TypeNS. - let result = self.resolve_path(&path, Some(TypeNS), Some(span)); - let (def, msg) = match result { - PathResult::Module(module) => (module.def().unwrap(), None), - PathResult::NonModule(res) if res.depth == 0 => - (res.base_def, None), - PathResult::NonModule(_) => { - // Resolve a module path for better errors - match self.resolve_path(&path, None, Some(span)) { - PathResult::Failed(msg, _) => (Def::Err, Some(msg)), - _ => unreachable!(), - } - } - PathResult::Indeterminate => unreachable!(), - PathResult::Failed(msg, _) => (Def::Err, Some(msg)), - }; - if let Some(msg) = msg { - resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); - } - self.record_def(item.id, PathResolution::new(def)); - } + ast::ViewPathList(ref prefix, ref items) if items.is_empty() => { + // Resolve prefix of an import with empty braces (issue #28388). + self.smart_resolve_path(item.id, None, prefix, PathSource::ImportPrefix); } _ => {} } @@ -1685,54 +1650,6 @@ impl<'a> Resolver<'a> { self.ribs[ValueNS].pop(); } - fn resolve_trait_reference(&mut self, - path: &[Ident], - generics: Option<&Generics>, - span: Span) - -> PathResolution { - let def = match self.resolve_path(path, None, Some(span)) { - PathResult::Module(module) => Some(module.def().unwrap()), - PathResult::NonModule(..) => return err_path_resolution(), - PathResult::Failed(msg, false) => { - resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); - return err_path_resolution(); - } - _ => match self.resolve_path(path, Some(TypeNS), None) { - PathResult::NonModule(path_resolution) => Some(path_resolution.base_def), - _ => None, - }, - }; - - if let Some(def) = def { - if let Def::Trait(_) = def { - return PathResolution::new(def); - } - - let mut err = resolve_struct_error(self, span, { - ResolutionError::IsNotATrait(&names_to_string(path), def.kind_name()) - }); - if let Some(generics) = generics { - if let Some(span) = generics.span_for_name(&names_to_string(path)) { - err.span_label(span, &"type parameter defined here"); - } - } - - // If it's a typedef, give a note - if let Def::TyAlias(..) = def { - err.note(&format!("type aliases cannot be used for traits")); - } - err.emit(); - } else { - // find possible candidates - let is_trait = |def| match def { Def::Trait(_) => true, _ => false }; - let candidates = self.lookup_candidates(path.last().unwrap().name, TypeNS, is_trait); - - let path = names_to_string(path); - resolve_error(self, span, ResolutionError::UndeclaredTraitName(&path, candidates)); - } - err_path_resolution() - } - fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where F: FnOnce(&mut Resolver) -> T { @@ -1743,24 +1660,17 @@ impl<'a> Resolver<'a> { result } - fn with_optional_trait_ref<T, F>(&mut self, - opt_trait_ref: Option<&TraitRef>, - f: F, - generics: Option<&Generics>) - -> T + fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T where F: FnOnce(&mut Resolver, Option<DefId>) -> T { let mut new_val = None; let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { - let ast::Path { ref segments, span } = trait_ref.path; - let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect(); - let path_res = self.resolve_trait_reference(&path, generics, span); - assert!(path_res.depth == 0); - self.record_def(trait_ref.ref_id, path_res); - if path_res.base_def != Def::Err { - new_val = Some((path_res.base_def.def_id(), trait_ref.clone())); - new_id = Some(path_res.base_def.def_id()); + let def = self.smart_resolve_path(trait_ref.ref_id, None, + &trait_ref.path, PathSource::Trait).base_def; + if def != Def::Err { + new_val = Some((def.def_id(), trait_ref.clone())); + new_id = Some(def.def_id()); } visit::walk_trait_ref(self, trait_ref); } @@ -1808,6 +1718,7 @@ impl<'a> Resolver<'a> { // If this is a trait impl, ensure the const // exists in trait this.check_trait_item(impl_item.ident.name, + ValueNS, impl_item.span, |n, s| ResolutionError::ConstNotMemberOfTrait(n, s)); visit::walk_impl_item(this, impl_item); @@ -1816,6 +1727,7 @@ impl<'a> Resolver<'a> { // If this is a trait impl, ensure the method // exists in trait this.check_trait_item(impl_item.ident.name, + ValueNS, impl_item.span, |n, s| ResolutionError::MethodNotMemberOfTrait(n, s)); @@ -1832,6 +1744,7 @@ impl<'a> Resolver<'a> { // If this is a trait impl, ensure the type // exists in trait this.check_trait_item(impl_item.ident.name, + TypeNS, impl_item.span, |n, s| ResolutionError::TypeNotMemberOfTrait(n, s)); @@ -1842,18 +1755,18 @@ impl<'a> Resolver<'a> { } }); }); - }, Some(&generics)); + }); }); } - fn check_trait_item<F>(&self, name: Name, span: Span, err: F) + fn check_trait_item<F>(&self, name: Name, ns: Namespace, span: Span, err: F) where F: FnOnce(Name, &str) -> ResolutionError { // If there is a TraitRef in scope for an impl, then the method must be in the // trait. if let Some((did, ref trait_ref)) = self.current_trait_ref { - if !self.trait_item_map.contains_key(&(name, did)) { - let path_str = path_names_to_string(&trait_ref.path, 0); + if !self.trait_item_map.contains_key(&(did, name, ns)) { + let path_str = path_names_to_string(&trait_ref.path); resolve_error(self, span, err(name, &path_str)); } } @@ -1993,58 +1906,6 @@ impl<'a> Resolver<'a> { debug!("(resolving block) leaving block"); } - fn resolve_type(&mut self, ty: &Ty) { - if let TyKind::Path(ref maybe_qself, ref path) = ty.node { - // This is a path in the type namespace. Walk through scopes looking for it. - if let Some(def) = - self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(), path, TypeNS) { - match def.base_def { - Def::Mod(..) if def.depth == 0 => { - self.session.span_err(path.span, "expected type, found module"); - self.record_def(ty.id, err_path_resolution()); - } - _ => { - // Write the result into the def map. - debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}", - path_names_to_string(path, 0), ty.id, def); - self.record_def(ty.id, def); - } - } - } else { - self.record_def(ty.id, err_path_resolution()); - // Keep reporting some errors even if they're ignored above. - let kind = if maybe_qself.is_some() { "associated type" } else { "type name" }; - let is_invalid_self_type_name = { - path.segments.len() > 0 && - maybe_qself.is_none() && - path.segments[0].identifier.name == keywords::SelfType.name() - }; - - if is_invalid_self_type_name { - resolve_error(self, ty.span, ResolutionError::SelfUsedOutsideImplOrTrait); - } else { - let type_name = path.segments.last().unwrap().identifier.name; - let candidates = self.lookup_candidates(type_name, TypeNS, |def| { - match def { - Def::Trait(_) | - Def::Enum(_) | - Def::Struct(_) | - Def::Union(_) | - Def::TyAlias(_) => true, - _ => false, - } - }); - - let name = &path_names_to_string(path, 0); - let error = ResolutionError::UseOfUndeclared(kind, name, candidates); - resolve_error(self, ty.span, error); - } - } - } - // Resolve embedded types. - visit::walk_ty(self, ty); - } - fn fresh_binding(&mut self, ident: &SpannedIdent, pat_id: NodeId, @@ -2098,61 +1959,6 @@ impl<'a> Resolver<'a> { PathResolution::new(def) } - fn resolve_pattern_path<ExpectedFn>(&mut self, - pat_id: NodeId, - qself: Option<&QSelf>, - path: &Path, - namespace: Namespace, - expected_fn: ExpectedFn, - expected_what: &str) - where ExpectedFn: FnOnce(Def) -> bool - { - let resolution = if let Some(resolution) = self.resolve_possibly_assoc_item(pat_id, - qself, path, namespace) { - if resolution.depth == 0 { - if expected_fn(resolution.base_def) || resolution.base_def == Def::Err { - resolution - } else { - resolve_error( - self, - path.span, - ResolutionError::PatPathUnexpected(expected_what, - resolution.kind_name(), path) - ); - err_path_resolution() - } - } else { - // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B` - // or `<T>::A::B`. If `B` should be resolved in value namespace then - // it needs to be added to the trait map. - if namespace == ValueNS { - let item_name = path.segments.last().unwrap().identifier.name; - let traits = self.get_traits_containing_item(item_name); - self.trait_map.insert(pat_id, traits); - } - resolution - } - } else { - let error = ResolutionError::PatPathUnresolved(expected_what, path); - resolve_error(self, path.span, error); - err_path_resolution() - }; - - self.record_def(pat_id, resolution); - } - - fn resolve_struct_path(&mut self, node_id: NodeId, path: &Path) { - // Resolution logic is equivalent for expressions and patterns, - // reuse `resolve_pattern_path` for both. - self.resolve_pattern_path(node_id, None, path, TypeNS, |def| { - match def { - Def::Struct(..) | Def::Union(..) | Def::Variant(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true, - _ => false, - } - }, "struct, variant or union type"); - } - fn resolve_pattern(&mut self, pat: &Pat, pat_src: PatternSource, @@ -2208,28 +2014,15 @@ impl<'a> Resolver<'a> { } PatKind::TupleStruct(ref path, ..) => { - self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| { - match def { - Def::StructCtor(_, CtorKind::Fn) | - Def::VariantCtor(_, CtorKind::Fn) => true, - _ => false, - } - }, "tuple struct/variant"); + self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct); } PatKind::Path(ref qself, ref path) => { - self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| { - match def { - Def::StructCtor(_, CtorKind::Const) | - Def::VariantCtor(_, CtorKind::Const) | - Def::Const(..) | Def::AssociatedConst(..) => true, - _ => false, - } - }, "unit struct/variant or constant"); + self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat); } PatKind::Struct(ref path, ..) => { - self.resolve_struct_path(pat.id, path); + self.smart_resolve_path(pat.id, None, path, PathSource::Struct); } _ => {} @@ -2240,33 +2033,245 @@ impl<'a> Resolver<'a> { visit::walk_pat(self, pat); } - /// Handles paths that may refer to associated items - fn resolve_possibly_assoc_item(&mut self, + // High-level and context dependent path resolution routine. + // Resolves the path and records the resolution into definition map. + // If resolution fails tries several techniques to find likely + // resolution candidates, suggest imports or other help, and report + // errors in user friendly way. + fn smart_resolve_path(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &Path, + source: PathSource) + -> PathResolution { + let segments = &path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>(); + self.smart_resolve_path_fragment(id, qself, segments, path.span, source) + } + + fn smart_resolve_path_fragment(&mut self, id: NodeId, - maybe_qself: Option<&QSelf>, - path: &Path, - ns: Namespace) - -> Option<PathResolution> { - let ast::Path { ref segments, span } = *path; - let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect(); - - if let Some(qself) = maybe_qself { + qself: Option<&QSelf>, + path: &[Ident], + span: Span, + source: PathSource) + -> PathResolution { + let ns = source.namespace(); + let is_expected = &|def| source.is_expected(def); + + // Base error is amended with one short label and possibly some longer helps/notes. + let report_errors = |this: &mut Self, def: Option<Def>| { + // Make the base error. + let expected = source.descr_expected(); + let path_str = names_to_string(path); + let code = source.error_code(def.is_some()); + let base_msg = if let Some(def) = def { + format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str) + } else { + format!("unresolved {} `{}`", expected, path_str) + }; + let mut err = this.session.struct_span_err_with_code(span, &base_msg, code); + + // Emit special messages for unresolved `Self` and `self`. + if is_self_type(path, ns) { + __diagnostic_used!(E0411); + err.code("E0411".into()); + err.span_label(span, &format!("`Self` is only available in traits and impls")); + return err; + } + if is_self_value(path, ns) { + __diagnostic_used!(E0424); + err.code("E0424".into()); + err.span_label(span, &format!("`self` value is only available in \ + methods with `self` parameter")); + return err; + } + + // Try to lookup the name in more relaxed fashion for better error reporting. + let name = path.last().unwrap().name; + let candidates = this.lookup_import_candidates(name, ns, is_expected); + if !candidates.is_empty() { + // Report import candidates as help and proceed searching for labels. + show_candidates(&mut err, &candidates, def.is_some()); + } + if path.len() == 1 && this.self_type_is_available() { + if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) { + let self_is_available = this.self_value_is_available(path[0].ctxt); + match candidate { + AssocSuggestion::Field => { + err.span_label(span, &format!("did you mean `self.{}`?", path_str)); + if !self_is_available { + err.span_label(span, &format!("`self` value is only available in \ + methods with `self` parameter")); + } + } + AssocSuggestion::MethodWithSelf if self_is_available => { + err.span_label(span, &format!("did you mean `self.{}(...)`?", + path_str)); + } + AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { + err.span_label(span, &format!("did you mean `Self::{}`?", path_str)); + } + } + return err; + } + } + + // Try context dependent help if relaxed lookup didn't work. + if let Some(def) = def { + match (def, source) { + (Def::Macro(..), _) => { + err.span_label(span, &format!("did you mean `{}!(...)`?", path_str)); + return err; + } + (Def::TyAlias(..), PathSource::Trait) => { + err.span_label(span, &format!("type aliases cannot be used for traits")); + return err; + } + (Def::Mod(..), PathSource::Expr(Some(parent))) => match *parent { + ExprKind::Field(_, ident) => { + err.span_label(span, &format!("did you mean `{}::{}`?", + path_str, ident.node)); + return err; + } + ExprKind::MethodCall(ident, ..) => { + err.span_label(span, &format!("did you mean `{}::{}(...)`?", + path_str, ident.node)); + return err; + } + _ => {} + }, + _ if ns == ValueNS && is_struct_like(def) => { + err.span_label(span, &format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + return err; + } + _ => {} + } + } + + // Try Levenshtein if nothing else worked. + if path.len() == 1 { + if let Some(candidate) = this.lookup_typo_candidate(name, ns, is_expected) { + err.span_label(span, &format!("did you mean `{}`?", candidate)); + return err; + } + } + + // Fallback labels. + if def.is_some() { + err.span_label(span, &format!("not a {}", expected)); + } else { + err.span_label(span, &format!("no resolution found")); + } + err + }; + let report_errors = |this: &mut Self, def: Option<Def>| { + report_errors(this, def).emit(); + err_path_resolution() + }; + + let resolution = match self.resolve_qpath_anywhere(id, qself, path, ns, span, + source.defer_to_typeck(), + source.global_by_default()) { + Some(resolution) if resolution.depth == 0 => { + if is_expected(resolution.base_def) || resolution.base_def == Def::Err { + resolution + } else { + report_errors(self, Some(resolution.base_def)) + } + } + Some(resolution) if source.defer_to_typeck() => { + // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B` + // or `<T>::A::B`. If `B` should be resolved in value namespace then + // it needs to be added to the trait map. + if ns == ValueNS { + let item_name = path.last().unwrap().name; + let traits = self.get_traits_containing_item(item_name, ns); + self.trait_map.insert(id, traits); + } + resolution + } + _ => report_errors(self, None) + }; + + if let PathSource::TraitItem(..) = source {} else { + // Avoid recording definition of `A::B` in `<T as A>::B::C`. + self.record_def(id, resolution); + } + resolution + } + + fn self_type_is_available(&mut self) -> bool { + let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(), TypeNS, None); + if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } + } + + fn self_value_is_available(&mut self, ctxt: SyntaxContext) -> bool { + let ident = Ident { name: keywords::SelfValue.name(), ctxt: ctxt }; + let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None); + if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } + } + + // Resolve in alternative namespaces if resolution in the primary namespace fails. + fn resolve_qpath_anywhere(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Ident], + primary_ns: Namespace, + span: Span, + defer_to_typeck: bool, + global_by_default: bool) + -> Option<PathResolution> { + let mut fin_res = None; + // FIXME: can't resolve paths in macro namespace yet, macros are + // processed by the little special hack below. + for (i, ns) in [primary_ns, TypeNS, ValueNS, /*MacroNS*/].iter().cloned().enumerate() { + if i == 0 || ns != primary_ns { + match self.resolve_qpath(id, qself, path, ns, span, global_by_default) { + // If defer_to_typeck, then resolution > no resolution, + // otherwise full resolution > partial resolution > no resolution. + Some(res) if res.depth == 0 || defer_to_typeck => return Some(res), + res => if fin_res.is_none() { fin_res = res }, + }; + } + } + if primary_ns != MacroNS && path.len() == 1 && + self.macro_names.contains(&path[0].name) { + // Return some dummy definition, it's enough for error reporting. + return Some(PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX)))); + } + fin_res + } + + /// Handles paths that may refer to associated items. + fn resolve_qpath(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Ident], + ns: Namespace, + span: Span, + global_by_default: bool) + -> Option<PathResolution> { + if let Some(qself) = qself { if qself.position == 0 { // FIXME: Create some fake resolution that can't possibly be a type. return Some(PathResolution { - base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)), + base_def: Def::Mod(DefId::local(CRATE_DEF_INDEX)), depth: path.len(), }); } - // Make sure the trait is valid. - self.resolve_trait_reference(&path[..qself.position], None, span); + // Make sure `A::B` in `<T as A>::B::C` is a trait item. + let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; + let mut res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1], + span, PathSource::TraitItem(ns)); + if res.base_def != Def::Err { + res.depth += path.len() - qself.position - 1; + } + return Some(res); } let result = match self.resolve_path(&path, Some(ns), Some(span)) { - PathResult::NonModule(path_res) => match path_res.base_def { - Def::Trait(..) if maybe_qself.is_some() => return None, - _ => path_res, - }, + PathResult::NonModule(path_res) => path_res, PathResult::Module(module) if !module.is_normal() => { PathResolution::new(module.def().unwrap()) } @@ -2287,7 +2292,7 @@ impl<'a> Resolver<'a> { self.primitive_type_table.primitive_types.contains_key(&path[0].name) => { PathResolution { base_def: Def::PrimTy(self.primitive_type_table.primitive_types[&path[0].name]), - depth: segments.len() - 1, + depth: path.len() - 1, } } PathResult::Module(module) => PathResolution::new(module.def().unwrap()), @@ -2295,10 +2300,11 @@ impl<'a> Resolver<'a> { resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); err_path_resolution() } - _ => return None, + PathResult::Failed(..) => return None, + PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"), }; - if path.len() == 1 || result.base_def == Def::Err { + if path.len() == 1 || global_by_default || result.base_def == Def::Err { return Some(result); } @@ -2399,10 +2405,10 @@ impl<'a> Resolver<'a> { let msg = if module.and_then(ModuleData::def) == self.graph_root.def() { let is_mod = |def| match def { Def::Mod(..) => true, _ => false }; let mut candidates = - self.lookup_candidates(ident.name, TypeNS, is_mod).candidates; - candidates.sort_by_key(|path| (path.segments.len(), path.to_string())); + self.lookup_import_candidates(ident.name, TypeNS, is_mod); + candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string())); if let Some(candidate) = candidates.get(0) { - format!("Did you mean `{}`?", candidate) + format!("Did you mean `{}`?", candidate.path) } else { format!("Maybe a missing `extern crate {};`?", ident) } @@ -2420,7 +2426,7 @@ impl<'a> Resolver<'a> { } // Resolve a local definition, potentially adjusting for closures. - fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Def { + fn adjust_local_def(&mut self, local_def: LocalDef, record_used: Option<Span>) -> Def { let ribs = match local_def.ribs { Some((ns, i)) => &self.ribs[ns][i + 1..], None => &[] as &[_], @@ -2428,7 +2434,7 @@ impl<'a> Resolver<'a> { let mut def = local_def.def; match def { Def::Upvar(..) => { - span_bug!(span, "unexpected {:?} in bindings", def) + span_bug!(record_used.unwrap_or(DUMMY_SP), "unexpected {:?} in bindings", def) } Def::Local(def_id) => { for rib in ribs { @@ -2451,28 +2457,32 @@ impl<'a> Resolver<'a> { .entry(function_id) .or_insert_with(|| vec![]); let depth = vec.len(); - vec.push(Freevar { - def: prev_def, - span: span, - }); - def = Def::Upvar(def_id, depth, function_id); - seen.insert(node_id, depth); + + if let Some(span) = record_used { + vec.push(Freevar { + def: prev_def, + span: span, + }); + seen.insert(node_id, depth); + } } ItemRibKind | MethodRibKind(_) => { // This was an attempt to access an upvar inside a // named function item. This is not allowed, so we // report an error. - resolve_error(self, - span, - ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); + if let Some(span) = record_used { + resolve_error(self, span, + ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); + } return Def::Err; } ConstantItemRibKind => { // Still doesn't deal with upvars - resolve_error(self, - span, - ResolutionError::AttemptToUseNonConstantValueInConstant); + if let Some(span) = record_used { + resolve_error(self, span, + ResolutionError::AttemptToUseNonConstantValueInConstant); + } return Def::Err; } } @@ -2488,15 +2498,18 @@ impl<'a> Resolver<'a> { ItemRibKind => { // This was an attempt to use a type parameter outside // its scope. - - resolve_error(self, - span, - ResolutionError::TypeParametersFromOuterFunction); + if let Some(span) = record_used { + resolve_error(self, span, + ResolutionError::TypeParametersFromOuterFunction); + } return Def::Err; } ConstantItemRibKind => { // see #9186 - resolve_error(self, span, ResolutionError::OuterTypeParameterContext); + if let Some(span) = record_used { + resolve_error(self, span, + ResolutionError::OuterTypeParameterContext); + } return Def::Err; } } @@ -2532,7 +2545,13 @@ impl<'a> Resolver<'a> { result } - fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion { + fn lookup_assoc_candidate<FilterFn>(&mut self, + name: Name, + ns: Namespace, + filter_fn: FilterFn) + -> Option<AssocSuggestion> + where FilterFn: Fn(Def) -> bool + { fn extract_node_id(t: &Ty) -> Option<NodeId> { match t.node { TyKind::Path(None, _) => Some(t.id), @@ -2544,51 +2563,59 @@ impl<'a> Resolver<'a> { } } - if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { - // Look for a field with the same name in the current self_type. - if let Some(resolution) = self.def_map.get(&node_id) { - match resolution.base_def { - Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => { - if let Some(field_names) = self.field_names.get(&did) { - if field_names.iter().any(|&field_name| name == field_name) { - return Field; + // Fields are generally expected in the same contexts as locals. + if filter_fn(Def::Local(DefId::local(CRATE_DEF_INDEX))) { + if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { + // Look for a field with the same name in the current self_type. + if let Some(resolution) = self.def_map.get(&node_id) { + match resolution.base_def { + Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => { + if let Some(field_names) = self.field_names.get(&did) { + if field_names.iter().any(|&field_name| name == field_name) { + return Some(AssocSuggestion::Field); + } } } + _ => {} } - _ => {} } } } - // Look for a method in the current trait. - if let Some((trait_did, ref trait_ref)) = self.current_trait_ref { - if let Some(&is_static_method) = self.trait_item_map.get(&(name, trait_did)) { - if is_static_method { - return TraitMethod(path_names_to_string(&trait_ref.path, 0)); - } else { - return TraitItem; + // Look for associated items in the current trait. + if let Some((trait_did, _)) = self.current_trait_ref { + if let Some(&(def, has_self)) = self.trait_item_map.get(&(trait_did, name, ns)) { + if filter_fn(def) { + return Some(if has_self { + AssocSuggestion::MethodWithSelf + } else { + AssocSuggestion::AssocItem + }); } } } - NoSuggestion + None } - fn find_best_match(&mut self, name: &str) -> SuggestionType { - if let Some(macro_name) = self.macro_names.iter().find(|&n| n == &name) { - return SuggestionType::Macro(format!("{}!", macro_name)); + fn lookup_typo_candidate<FilterFn>(&mut self, + name: Name, + ns: Namespace, + filter_fn: FilterFn) + -> Option<Name> + where FilterFn: Fn(Def) -> bool + { + // FIXME: bindings in ribs provide quite modest set of candidates, + // extend it with other names in scope. + let names = self.ribs[ns].iter().rev().flat_map(|rib| { + rib.bindings.iter().filter_map(|(ident, def)| { + if filter_fn(*def) { Some(&ident.name) } else { None } + }) + }); + match find_best_match_for_name(names, &name.as_str(), None) { + Some(found) if found != name => Some(found), + _ => None, } - - let names = self.ribs[ValueNS] - .iter() - .rev() - .flat_map(|rib| rib.bindings.keys().map(|ident| &ident.name)); - - if let Some(found) = find_best_match_for_name(names, name, None) { - if found != name { - return SuggestionType::Function(found); - } - } SuggestionType::NotFound } fn resolve_labeled_block(&mut self, label: Option<SpannedIdent>, id: NodeId, block: &Block) { @@ -2603,7 +2630,7 @@ impl<'a> Resolver<'a> { } } - fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) { + fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -2611,142 +2638,13 @@ impl<'a> Resolver<'a> { // Next, resolve the node. match expr.node { - ExprKind::Path(ref maybe_qself, ref path) => { - // This is a local path in the value namespace. Walk through - // scopes looking for it. - if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id, - maybe_qself.as_ref(), path, ValueNS) { - // Check if struct variant - let is_struct_variant = match path_res.base_def { - Def::VariantCtor(_, CtorKind::Fictive) => true, - _ => false, - }; - if is_struct_variant { - let path_name = path_names_to_string(path, 0); - - let mut err = resolve_struct_error(self, - expr.span, - ResolutionError::StructVariantUsedAsFunction(&path_name)); - - let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", - path_name); - err.help(&msg); - err.emit(); - self.record_def(expr.id, err_path_resolution()); - } else { - // Write the result into the def map. - debug!("(resolving expr) resolved `{}`", - path_names_to_string(path, 0)); - - // Partial resolutions will need the set of traits in scope, - // so they can be completed during typeck. - if path_res.depth != 0 { - let method_name = path.segments.last().unwrap().identifier.name; - let traits = self.get_traits_containing_item(method_name); - self.trait_map.insert(expr.id, traits); - } - - self.record_def(expr.id, path_res); - } - } else { - // Be helpful if the name refers to a struct - let path_name = path_names_to_string(path, 0); - let path: Vec<_> = path.segments.iter().map(|seg| seg.identifier).collect(); - let type_res = match self.resolve_path(&path, Some(TypeNS), None) { - PathResult::NonModule(type_res) => Some(type_res), - _ => None, - }; - - self.record_def(expr.id, err_path_resolution()); - - if let Some(Def::Struct(..)) = type_res.map(|r| r.base_def) { - let error_variant = - ResolutionError::StructVariantUsedAsFunction(&path_name); - let mut err = resolve_struct_error(self, expr.span, error_variant); - - let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", - path_name); - - err.help(&msg); - err.emit(); - } else { - // Keep reporting some errors even if they're ignored above. - let mut method_scope = false; - let mut is_static = false; - self.ribs[ValueNS].iter().rev().all(|rib| { - method_scope = match rib.kind { - MethodRibKind(is_static_) => { - is_static = is_static_; - true - } - ItemRibKind | ConstantItemRibKind => false, - _ => return true, // Keep advancing - }; - false // Stop advancing - }); - - if method_scope && keywords::SelfValue.name() == &*path_name { - let error = ResolutionError::SelfNotAvailableInStaticMethod; - resolve_error(self, expr.span, error); - } else { - let fallback = - self.find_fallback_in_self_type(path.last().unwrap().name); - let (mut msg, is_field) = match fallback { - NoSuggestion => { - // limit search to 5 to reduce the number - // of stupid suggestions - (match self.find_best_match(&path_name) { - SuggestionType::Macro(s) => { - format!("the macro `{}`", s) - } - SuggestionType::Function(s) => format!("`{}`", s), - SuggestionType::NotFound => "".to_string(), - }, false) - } - Field => { - (if is_static && method_scope { - "".to_string() - } else { - format!("`self.{}`", path_name) - }, true) - } - TraitItem => (format!("to call `self.{}`", path_name), false), - TraitMethod(path_str) => - (format!("to call `{}::{}`", path_str, path_name), false), - }; - - let mut context = UnresolvedNameContext::Other; - let mut def = Def::Err; - if !msg.is_empty() { - msg = format!("did you mean {}?", msg); - } else { - // we display a help message if this is a module - if let PathResult::Module(module) = - self.resolve_path(&path, None, None) { - def = module.def().unwrap(); - context = UnresolvedNameContext::PathIsMod(parent); - } - } - - let error = ResolutionError::UnresolvedName { - path: &path_name, - message: &msg, - context: context, - is_static_method: method_scope && is_static, - is_field: is_field, - def: def, - }; - resolve_error(self, expr.span, error); - } - } - } - + ExprKind::Path(ref qself, ref path) => { + self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent)); visit::walk_expr(self, expr); } ExprKind::Struct(ref path, ..) => { - self.resolve_struct_path(expr.id, path); - + self.smart_resolve_path(expr.id, None, path, PathSource::Struct); visit::walk_expr(self, expr); } @@ -2809,12 +2707,13 @@ impl<'a> Resolver<'a> { self.ribs[ValueNS].pop(); } + // Equivalent to `visit::walk_expr` + passing some context to children. ExprKind::Field(ref subexpression, _) => { - self.resolve_expr(subexpression, Some(expr)); + self.resolve_expr(subexpression, Some(&expr.node)); } ExprKind::MethodCall(_, ref types, ref arguments) => { let mut arguments = arguments.iter(); - self.resolve_expr(arguments.next().unwrap(), Some(expr)); + self.resolve_expr(arguments.next().unwrap(), Some(&expr.node)); for argument in arguments { self.resolve_expr(argument, None); } @@ -2822,6 +2721,12 @@ impl<'a> Resolver<'a> { self.visit_ty(ty); } } + ExprKind::Call(ref callee, ref arguments) => { + self.resolve_expr(callee, Some(&expr.node)); + for argument in arguments { + self.resolve_expr(argument, None); + } + } _ => { visit::walk_expr(self, expr); @@ -2836,13 +2741,13 @@ impl<'a> Resolver<'a> { // field, we need to add any trait methods we find that match // the field name so that we can do some nice error reporting // later on in typeck. - let traits = self.get_traits_containing_item(name.node.name); + let traits = self.get_traits_containing_item(name.node.name, ValueNS); self.trait_map.insert(expr.id, traits); } ExprKind::MethodCall(name, ..) => { debug!("(recording candidate traits for expr) recording traits for {}", expr.id); - let traits = self.get_traits_containing_item(name.node.name); + let traits = self.get_traits_containing_item(name.node.name, ValueNS); self.trait_map.insert(expr.id, traits); } _ => { @@ -2851,20 +2756,20 @@ impl<'a> Resolver<'a> { } } - fn get_traits_containing_item(&mut self, name: Name) -> Vec<TraitCandidate> { + fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<TraitCandidate> { debug!("(getting traits containing item) looking for '{}'", name); let mut found_traits = Vec::new(); // Look for the current trait. if let Some((trait_def_id, _)) = self.current_trait_ref { - if self.trait_item_map.contains_key(&(name, trait_def_id)) { + if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) { found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: None }); } } let mut search_module = self.current_module; loop { - self.get_traits_in_module_containing_item(name, search_module, &mut found_traits); + self.get_traits_in_module_containing_item(name, ns, search_module, &mut found_traits); match search_module.kind { ModuleKind::Block(..) => search_module = search_module.parent.unwrap(), _ => break, @@ -2873,7 +2778,7 @@ impl<'a> Resolver<'a> { if let Some(prelude) = self.prelude { if !search_module.no_implicit_prelude { - self.get_traits_in_module_containing_item(name, prelude, &mut found_traits); + self.get_traits_in_module_containing_item(name, ns, prelude, &mut found_traits); } } @@ -2882,6 +2787,7 @@ impl<'a> Resolver<'a> { fn get_traits_in_module_containing_item(&mut self, name: Name, + ns: Namespace, module: Module, found_traits: &mut Vec<TraitCandidate>) { let mut traits = module.traits.borrow_mut(); @@ -2898,7 +2804,7 @@ impl<'a> Resolver<'a> { for &(trait_name, binding) in traits.as_ref().unwrap().iter() { let trait_def_id = binding.def().def_id(); - if self.trait_item_map.contains_key(&(name, trait_def_id)) { + if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) { let import_id = match binding.kind { NameBindingKind::Import { directive, .. } => { self.maybe_unused_trait_imports.insert(directive.id); @@ -2919,13 +2825,14 @@ impl<'a> Resolver<'a> { /// /// NOTE: The method does not look into imports, but this is not a problem, /// since we report the definitions (thus, the de-aliased imports). - fn lookup_candidates<FilterFn>(&mut self, - lookup_name: Name, - namespace: Namespace, - filter_fn: FilterFn) -> SuggestedCandidates - where FilterFn: Fn(Def) -> bool { - - let mut lookup_results = Vec::new(); + fn lookup_import_candidates<FilterFn>(&mut self, + lookup_name: Name, + namespace: Namespace, + filter_fn: FilterFn) + -> Vec<ImportSuggestion> + where FilterFn: Fn(Def) -> bool + { + let mut candidates = Vec::new(); let mut worklist = Vec::new(); let mut seen_modules = FxHashSet(); worklist.push((self.graph_root, Vec::new(), false)); @@ -2939,6 +2846,8 @@ impl<'a> Resolver<'a> { // avoid imports entirely if name_binding.is_import() && !name_binding.is_extern_crate() { return; } + // avoid non-importable candidates as well + if !name_binding.is_importable() { return; } // collect results based on the filter function if ident.name == lookup_name && ns == namespace { @@ -2959,7 +2868,7 @@ impl<'a> Resolver<'a> { // declared as public (due to pruning, we don't explore // outside crate private modules => no need to check this) if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { - lookup_results.push(path); + candidates.push(ImportSuggestion { path: path }); } } } @@ -2981,50 +2890,40 @@ impl<'a> Resolver<'a> { }) } - SuggestedCandidates { - name: lookup_name.as_str().to_string(), - candidates: lookup_results, - } + candidates } fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) { debug!("(recording def) recording {:?} for {}", resolution, node_id); + assert!(resolution.depth == 0 || resolution.base_def != Def::Err); if let Some(prev_res) = self.def_map.insert(node_id, resolution) { panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution); } } fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { - let (segments, span, id) = match *vis { - ast::Visibility::Public => return ty::Visibility::Public, - ast::Visibility::Crate(_) => { - return ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); - } - ast::Visibility::Restricted { ref path, id } => (&path.segments, path.span, id), + match *vis { + ast::Visibility::Public => ty::Visibility::Public, + ast::Visibility::Crate(..) => ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)), ast::Visibility::Inherited => { - return ty::Visibility::Restricted(self.current_module.normal_ancestor_id); - } - }; - - let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect(); - let mut path_resolution = err_path_resolution(); - let vis = match self.resolve_path(&path, None, Some(span)) { - PathResult::Module(module) => { - path_resolution = PathResolution::new(module.def().unwrap()); - ty::Visibility::Restricted(module.normal_ancestor_id) + ty::Visibility::Restricted(self.current_module.normal_ancestor_id) } - PathResult::Failed(msg, _) => { - self.session.span_err(span, &format!("failed to resolve module path. {}", msg)); - ty::Visibility::Public + ast::Visibility::Restricted { ref path, id } => { + let def = self.smart_resolve_path(id, None, path, PathSource::Visibility).base_def; + if def == Def::Err { + ty::Visibility::Public + } else { + let vis = ty::Visibility::Restricted(def.def_id()); + if self.is_accessible(vis) { + vis + } else { + self.session.span_err(path.span, "visibilities can only be restricted \ + to ancestor modules"); + ty::Visibility::Public + } + } } - _ => ty::Visibility::Public, - }; - self.def_map.insert(id, path_resolution); - if !self.is_accessible(vis) { - let msg = format!("visibilities can only be restricted to ancestor modules"); - self.session.span_err(span, &msg); } - vis } fn is_accessible(&self, vis: ty::Visibility) -> bool { @@ -3175,79 +3074,72 @@ impl<'a> Resolver<'a> { } } -fn names_to_string(names: &[Ident]) -> String { +fn is_struct_like(def: Def) -> bool { + match def { + Def::VariantCtor(_, CtorKind::Fictive) => true, + _ => PathSource::Struct.is_expected(def), + } +} + +fn is_self_type(path: &[Ident], namespace: Namespace) -> bool { + namespace == TypeNS && path.len() == 1 && path[0].name == keywords::SelfType.name() +} + +fn is_self_value(path: &[Ident], namespace: Namespace) -> bool { + namespace == ValueNS && path.len() == 1 && path[0].name == keywords::SelfValue.name() +} + +fn names_to_string(idents: &[Ident]) -> String { let mut result = String::new(); - for (i, ident) in names.iter().enumerate() { + for (i, ident) in idents.iter().filter(|i| i.name != keywords::CrateRoot.name()).enumerate() { if i > 0 { result.push_str("::"); } - if ident.name != keywords::CrateRoot.name() { - result.push_str(&ident.name.as_str()); - } + result.push_str(&ident.name.as_str()); } result } -fn path_names_to_string(path: &Path, depth: usize) -> String { - let names: Vec<_> = - path.segments[..path.segments.len() - depth].iter().map(|seg| seg.identifier).collect(); - names_to_string(&names) +fn path_names_to_string(path: &Path) -> String { + names_to_string(&path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>()) } /// When an entity with a given name is not available in scope, we search for /// entities with that name in all crates. This method allows outputting the /// results of this search in a programmer-friendly way fn show_candidates(session: &mut DiagnosticBuilder, - candidates: &SuggestedCandidates) { - - let paths = &candidates.candidates; - - if paths.len() > 0 { - // don't show more than MAX_CANDIDATES results, so - // we're consistent with the trait suggestions - const MAX_CANDIDATES: usize = 5; - - // we want consistent results across executions, but candidates are produced - // by iterating through a hash map, so make sure they are ordered: - let mut path_strings: Vec<_> = paths.into_iter() - .map(|p| path_names_to_string(&p, 0)) - .collect(); - path_strings.sort(); - - // behave differently based on how many candidates we have: - if !paths.is_empty() { - if paths.len() == 1 { - session.help( - &format!("you can import it into scope: `use {};`.", - &path_strings[0]), - ); - } else { - session.help("you can import several candidates \ - into scope (`use ...;`):"); - let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1; - - for (idx, path_string) in path_strings.iter().enumerate() { - if idx == MAX_CANDIDATES - 1 && count > 1 { - session.help( - &format!(" and {} other candidates", count).to_string(), - ); - break; - } else { - session.help( - &format!(" `{}`", path_string).to_string(), - ); - } - } - } - } - } else { - // nothing found: - session.help( - &format!("no candidates by the name of `{}` found in your \ - project; maybe you misspelled the name or forgot to import \ - an external crate?", candidates.name.to_string()), - ); + candidates: &[ImportSuggestion], + better: bool) { + // don't show more than MAX_CANDIDATES results, so + // we're consistent with the trait suggestions + const MAX_CANDIDATES: usize = 5; + + // we want consistent results across executions, but candidates are produced + // by iterating through a hash map, so make sure they are ordered: + let mut path_strings: Vec<_> = + candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); + path_strings.sort(); + + let better = if better { "better " } else { "" }; + let msg_diff = match path_strings.len() { + 1 => " is found in another module, you can import it", + _ => "s are found in other modules, you can import them", }; + session.help(&format!("possible {}candidate{} into scope:", better, msg_diff)); + + let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1; + for (idx, path_string) in path_strings.iter().enumerate() { + if idx == MAX_CANDIDATES - 1 && count > 1 { + session.help( + &format!(" and {} other candidates", count).to_string(), + ); + break; + } else { + session.help( + &format!(" `use {};`", path_string).to_string(), + ); + } + } } /// A somewhat inefficient routine to obtain the name of a module. diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e9048b3617f..41d8f16b88d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -717,7 +717,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } // Record the destination of this import - self.def_map.insert(directive.id, PathResolution::new(module.def().unwrap())); + self.record_def(directive.id, PathResolution::new(module.def().unwrap())); } // Miscellaneous post-processing, including recording reexports, reporting conflicts, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 71270963f80..598003a3925 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1519,14 +1519,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.set_tainted_by_errors(); return self.tcx().types.err; } - _ => { - struct_span_err!(tcx.sess, span, E0248, - "found value `{}` used as a type", - tcx.item_path_str(path.def.def_id())) - .span_label(span, &format!("value used as a type")) - .emit(); - return self.tcx().types.err; - } + _ => span_bug!(span, "unexpected definition: {:?}", path.def) } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 2b17ac94b22..cea3ad43a95 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2861,25 +2861,6 @@ struct Bar<S, T> { x: Foo<S, T> } ``` "##, -E0248: r##" -This error indicates an attempt to use a value where a type is expected. For -example: - -```compile_fail,E0248 -enum Foo { - Bar(u32) -} - -fn do_something(x: Foo::Bar) { } -``` - -In this example, we're attempting to take a type of `Foo::Bar` in the -do_something function. This is not legal: `Foo::Bar` is a value of type `Foo`, -not a distinct static type. Likewise, it's not legal to attempt to -`impl Foo::Bar`: instead, you must `impl Foo` and then pattern match to specify -behavior for specific enum variants. -"##, - E0569: r##" If an impl has a generic parameter with the `#[may_dangle]` attribute, then that impl must be declared as an `unsafe impl. For example: @@ -4247,6 +4228,7 @@ register_diagnostics! { E0245, // not a trait // E0246, // invalid recursive type // E0247, +// E0248, // value used as a type, now reported earlier during resolution as E0412 // E0249, // E0319, // trait impls for defaulted traits allowed just for structs/enums E0320, // recursive overflow during dropck diff --git a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs index f563a1f88d0..b0a2859a5da 100644 --- a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs +++ b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs @@ -14,5 +14,5 @@ extern crate macro_crate_test; fn main() { - macro_crate_test::foo(); //~ ERROR unresolved name + macro_crate_test::foo(); //~ ERROR unresolved function `macro_crate_test::foo` } diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs index 8acab3369e4..149985717c6 100644 --- a/src/test/compile-fail-fulldeps/qquote.rs +++ b/src/test/compile-fail-fulldeps/qquote.rs @@ -39,6 +39,6 @@ fn main() { assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23"); - let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR unresolved name `abcd` + let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR unresolved value `abcd` assert_eq!(pprust::expr_to_string(&*expr), "2 - $abcd + 7"); } diff --git a/src/test/compile-fail/E0033.rs b/src/test/compile-fail/E0033.rs index 44f73e10e25..03d47472093 100644 --- a/src/test/compile-fail/E0033.rs +++ b/src/test/compile-fail/E0033.rs @@ -14,8 +14,8 @@ trait SomeTrait { fn main() { let trait_obj: &SomeTrait = SomeTrait; - //~^ ERROR E0425 - //~| NOTE unresolved name + //~^ ERROR expected value, found trait `SomeTrait` + //~| NOTE not a value //~| ERROR E0038 //~| method `foo` has no receiver //~| NOTE the trait `SomeTrait` cannot be made into an object diff --git a/src/test/compile-fail/E0423.rs b/src/test/compile-fail/E0423.rs index 98b700984a7..f5fea77cf96 100644 --- a/src/test/compile-fail/E0423.rs +++ b/src/test/compile-fail/E0423.rs @@ -12,5 +12,4 @@ fn main () { struct Foo { a: bool }; let f = Foo(); //~ ERROR E0423 - //~^ struct called like a function } diff --git a/src/test/compile-fail/E0424.rs b/src/test/compile-fail/E0424.rs index 911007113d3..445d0c5f3ed 100644 --- a/src/test/compile-fail/E0424.rs +++ b/src/test/compile-fail/E0424.rs @@ -14,10 +14,7 @@ impl Foo { fn bar(self) {} fn foo() { - self.bar(); - //~^ ERROR `self` is not available in a static method [E0424] - //~| NOTE not available in static method - //~| NOTE maybe a `self` argument is missing? + self.bar(); //~ ERROR E0424 } } diff --git a/src/test/compile-fail/E0425.rs b/src/test/compile-fail/E0425.rs index 70f4b1107ad..3786282031f 100644 --- a/src/test/compile-fail/E0425.rs +++ b/src/test/compile-fail/E0425.rs @@ -10,7 +10,7 @@ trait Foo { fn bar() { - Self; //~ ERROR E0425 + elf; //~ ERROR E0425 } } diff --git a/src/test/compile-fail/associated-path-shl.rs b/src/test/compile-fail/associated-path-shl.rs index 6bc110239cd..0295d4248e5 100644 --- a/src/test/compile-fail/associated-path-shl.rs +++ b/src/test/compile-fail/associated-path-shl.rs @@ -11,10 +11,10 @@ // Check that associated paths starting with `<<` are successfully parsed. fn main() { - let _: <<A>::B>::C; //~ ERROR type name `A` is undefined or not in scope - let _ = <<A>::B>::C; //~ ERROR type name `A` is undefined or not in scope - let <<A>::B>::C; //~ ERROR type name `A` is undefined or not in scope - let 0 ... <<A>::B>::C; //~ ERROR type name `A` is undefined or not in scope + let _: <<A>::B>::C; //~ ERROR unresolved type `A` + let _ = <<A>::B>::C; //~ ERROR unresolved type `A` + let <<A>::B>::C; //~ ERROR unresolved type `A` + let 0 ... <<A>::B>::C; //~ ERROR unresolved type `A` //~^ ERROR only char and numeric types are allowed in range patterns - <<A>::B>::C; //~ ERROR type name `A` is undefined or not in scope + <<A>::B>::C; //~ ERROR unresolved type `A` } diff --git a/src/test/compile-fail/associated-types-eq-1.rs b/src/test/compile-fail/associated-types-eq-1.rs index 59d87146097..46d5633c8dd 100644 --- a/src/test/compile-fail/associated-types-eq-1.rs +++ b/src/test/compile-fail/associated-types-eq-1.rs @@ -17,7 +17,7 @@ pub trait Foo { } fn foo2<I: Foo>(x: I) { - let _: A = x.boo(); //~ERROR undefined or not in scope + let _: A = x.boo(); //~ ERROR unresolved type `A` } pub fn main() {} diff --git a/src/test/compile-fail/auxiliary/lint_stability.rs b/src/test/compile-fail/auxiliary/lint_stability.rs index 1049bcd1564..5e3cb606ce0 100644 --- a/src/test/compile-fail/auxiliary/lint_stability.rs +++ b/src/test/compile-fail/auxiliary/lint_stability.rs @@ -132,6 +132,10 @@ pub struct UnstableStruct { pub struct StableStruct { #[stable(feature = "test_feature", since = "1.0.0")] pub i: isize } +#[unstable(feature = "test_feature", issue = "0")] +pub enum UnstableEnum {} +#[stable(feature = "rust1", since = "1.0.0")] +pub enum StableEnum {} #[stable(feature = "test_feature", since = "1.0.0")] #[rustc_deprecated(since = "1.0.0", reason = "text")] diff --git a/src/test/compile-fail/bad-expr-path.rs b/src/test/compile-fail/bad-expr-path.rs index c18a3183477..05400a0eb65 100644 --- a/src/test/compile-fail/bad-expr-path.rs +++ b/src/test/compile-fail/bad-expr-path.rs @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `m1::arguments` - mod m1 {} -fn main(arguments: Vec<String>) { log(debug, m1::arguments); } +fn main(arguments: Vec<String>) { //~ ERROR main function has wrong type + log(debug, m1::arguments); + //~^ ERROR unresolved function `log` + //~| ERROR unresolved value `debug` + //~| ERROR unresolved value `m1::arguments` +} diff --git a/src/test/compile-fail/bad-expr-path2.rs b/src/test/compile-fail/bad-expr-path2.rs index e1c1afb0049..867166134b2 100644 --- a/src/test/compile-fail/bad-expr-path2.rs +++ b/src/test/compile-fail/bad-expr-path2.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `m1::arguments` - mod m1 { pub mod arguments {} } -fn main(arguments: Vec<String>) { +fn main(arguments: Vec<String>) { //~ ERROR main function has wrong type log(debug, m1::arguments); + //~^ ERROR unresolved function `log` + //~| ERROR unresolved value `debug` + //~| ERROR expected value, found module `m1::arguments` } diff --git a/src/test/compile-fail/class-missing-self.rs b/src/test/compile-fail/class-missing-self.rs index ab76af1cbe6..cab46ec1fbf 100644 --- a/src/test/compile-fail/class-missing-self.rs +++ b/src/test/compile-fail/class-missing-self.rs @@ -16,8 +16,8 @@ impl cat { fn sleep(&self) { loop{} } fn meow(&self) { println!("Meow"); - meows += 1; //~ ERROR unresolved name - sleep(); //~ ERROR unresolved name + meows += 1; //~ ERROR unresolved value `meows` + sleep(); //~ ERROR unresolved function `sleep` } } diff --git a/src/test/compile-fail/coherence-error-suppression.rs b/src/test/compile-fail/coherence-error-suppression.rs index b33f27fbc8a..7c7782b9b44 100644 --- a/src/test/compile-fail/coherence-error-suppression.rs +++ b/src/test/compile-fail/coherence-error-suppression.rs @@ -16,7 +16,7 @@ impl Foo for i8 {} impl Foo for i16 {} impl Foo for i32 {} impl Foo for i64 {} -impl Foo for DoesNotExist {} //~ ERROR `DoesNotExist` is undefined +impl Foo for DoesNotExist {} //~ ERROR unresolved type `DoesNotExist` impl Foo for u8 {} impl Foo for u16 {} impl Foo for u32 {} diff --git a/src/test/compile-fail/derived-errors/issue-31997.rs b/src/test/compile-fail/derived-errors/issue-31997.rs index cf283f6d3e4..2a294a4e31f 100644 --- a/src/test/compile-fail/derived-errors/issue-31997.rs +++ b/src/test/compile-fail/derived-errors/issue-31997.rs @@ -20,7 +20,7 @@ fn closure<F, T>(x: F) -> Result<T, ()> } fn foo() -> Result<(), ()> { - try!(closure(|| bar(0 as *mut _))); //~ ERROR unresolved name `bar` + try!(closure(|| bar(0 as *mut _))); //~ ERROR unresolved function `bar` Ok(()) } diff --git a/src/test/compile-fail/does-nothing.rs b/src/test/compile-fail/does-nothing.rs index c0cd406f062..96e14d2fb22 100644 --- a/src/test/compile-fail/does-nothing.rs +++ b/src/test/compile-fail/does-nothing.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `this_does_nothing_what_the` fn main() { println!("doing"); this_does_nothing_what_the; println!("boing"); } +//~^ ERROR unresolved value `this_does_nothing_what_the` diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs index 1c86af30c79..d4e85e9744d 100644 --- a/src/test/compile-fail/empty-struct-braces-expr.rs +++ b/src/test/compile-fail/empty-struct-braces-expr.rs @@ -22,13 +22,13 @@ enum E { } fn main() { - let e1 = Empty1; //~ ERROR `Empty1` is the name of a struct or struct variant - let e1 = Empty1(); //~ ERROR `Empty1` is the name of a struct or struct variant - let e3 = E::Empty3; //~ ERROR `E::Empty3` is the name of a struct or struct variant - let e3 = E::Empty3(); //~ ERROR `E::Empty3` is the name of a struct or struct variant + let e1 = Empty1; //~ ERROR expected value, found struct `Empty1` + let e1 = Empty1(); //~ ERROR expected function, 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 xe1 = XEmpty1; //~ ERROR `XEmpty1` is the name of a struct or struct variant - let xe1 = XEmpty1(); //~ ERROR `XEmpty1` is the name of a struct or struct variant + let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` + let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1` let xe3 = XE::Empty3; //~ ERROR no associated item named `Empty3` found for type let xe3 = XE::Empty3(); //~ ERROR no associated item named `Empty3` found for type } diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs index 4349e72c5d7..d3b13457dc6 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-2.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs @@ -22,15 +22,15 @@ fn main() { let xe1 = XEmpty1 {}; match e1 { - Empty1() => () //~ ERROR unresolved tuple struct/variant `Empty1` + Empty1() => () //~ ERROR expected tuple struct/variant, found struct `Empty1` } match xe1 { - XEmpty1() => () //~ ERROR unresolved tuple struct/variant `XEmpty1` + XEmpty1() => () //~ ERROR expected tuple struct/variant, found struct `XEmpty1` } match e1 { - Empty1(..) => () //~ ERROR unresolved tuple struct/variant `Empty1` + Empty1(..) => () //~ ERROR expected tuple struct/variant, found struct `Empty1` } match xe1 { - XEmpty1(..) => () //~ ERROR unresolved tuple struct/variant `XEmpty1` + XEmpty1(..) => () //~ ERROR expected tuple struct/variant, found struct `XEmpty1` } } diff --git a/src/test/compile-fail/enum-variant-type-2.rs b/src/test/compile-fail/enum-variant-type-2.rs index eef4bea1df1..258bfd1e3ba 100644 --- a/src/test/compile-fail/enum-variant-type-2.rs +++ b/src/test/compile-fail/enum-variant-type-2.rs @@ -14,6 +14,6 @@ enum Foo { Bar } -fn foo(x: Foo::Bar) {} //~ERROR found value `Foo::Bar` used as a type +fn foo(x: Foo::Bar) {} //~ ERROR expected type, found variant `Foo::Bar` fn main() {} diff --git a/src/test/compile-fail/export-fully-qualified.rs b/src/test/compile-fail/export-fully-qualified.rs index 166ef7ab87f..19fa13f8377 100644 --- a/src/test/compile-fail/export-fully-qualified.rs +++ b/src/test/compile-fail/export-fully-qualified.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: failed to resolve. Use of undeclared type or module `foo` - // In this test baz isn't resolved when called as foo.baz even though // it's called from inside foo. This is somewhat surprising and may // want to change eventually. mod foo { - pub fn bar() { foo::baz(); } + pub fn bar() { foo::baz(); } //~ ERROR failed to resolve. Use of undeclared type or module `foo` fn baz() { } } diff --git a/src/test/compile-fail/export.rs b/src/test/compile-fail/export.rs index 3a391e7c609..a412cac699f 100644 --- a/src/test/compile-fail/export.rs +++ b/src/test/compile-fail/export.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name mod foo { pub fn x(y: isize) { log(debug, y); } + //~^ ERROR unresolved function `log` + //~| ERROR unresolved value `debug` fn z(y: isize) { log(debug, y); } + //~^ ERROR unresolved function `log` + //~| ERROR unresolved value `debug` } -fn main() { foo::z(10); } +fn main() { foo::z(10); } //~ ERROR function `z` is private diff --git a/src/test/compile-fail/export2.rs b/src/test/compile-fail/export2.rs index f7b1400aa45..dc96ce7f504 100644 --- a/src/test/compile-fail/export2.rs +++ b/src/test/compile-fail/export2.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: failed to resolve. Use of undeclared type or module `bar` - mod foo { - pub fn x() { bar::x(); } + pub fn x() { bar::x(); } //~ ERROR failed to resolve. Use of undeclared type or module `bar` } mod bar { diff --git a/src/test/compile-fail/extern-with-type-bounds.rs b/src/test/compile-fail/extern-with-type-bounds.rs index d8bdd5974c7..0f8ad8d5388 100644 --- a/src/test/compile-fail/extern-with-type-bounds.rs +++ b/src/test/compile-fail/extern-with-type-bounds.rs @@ -24,7 +24,7 @@ extern "rust-intrinsic" { // Unresolved bounds should still error. fn align_of<T: NoSuchTrait>() -> usize; - //~^ ERROR trait `NoSuchTrait` is not in scope + //~^ ERROR unresolved trait `NoSuchTrait` } fn main() {} diff --git a/src/test/compile-fail/for-expn.rs b/src/test/compile-fail/for-expn.rs index 43776d75a47..a051789ec98 100644 --- a/src/test/compile-fail/for-expn.rs +++ b/src/test/compile-fail/for-expn.rs @@ -13,7 +13,7 @@ fn main() { // Odd formatting to make sure we get the right span. for t in & - foo //~ ERROR unresolved name `foo` + foo //~ ERROR unresolved value `foo` { } } diff --git a/src/test/compile-fail/for-loop-hygiene.rs b/src/test/compile-fail/for-loop-hygiene.rs index f06882875fd..2135ad6e73c 100644 --- a/src/test/compile-fail/for-loop-hygiene.rs +++ b/src/test/compile-fail/for-loop-hygiene.rs @@ -13,6 +13,6 @@ fn main() { for _ in 0..10 { - iter.next(); //~ error: unresolved name `iter` + iter.next(); //~ ERROR unresolved value `iter` } } diff --git a/src/test/compile-fail/glob-resolve1.rs b/src/test/compile-fail/glob-resolve1.rs index 1e5662aa172..58e67796586 100644 --- a/src/test/compile-fail/glob-resolve1.rs +++ b/src/test/compile-fail/glob-resolve1.rs @@ -29,13 +29,13 @@ mod bar { fn foo<T>() {} fn main() { - fpriv(); //~ ERROR: unresolved - epriv(); //~ ERROR: unresolved - B; //~ ERROR: unresolved - C; //~ ERROR: unresolved - import(); //~ ERROR: unresolved - - foo::<A>(); //~ ERROR: not in scope - foo::<C>(); //~ ERROR: not in scope - foo::<D>(); //~ ERROR: not in scope + fpriv(); //~ ERROR unresolved function `fpriv` + epriv(); //~ ERROR unresolved function `epriv` + B; //~ ERROR expected value, found enum `B` + C; //~ ERROR unresolved value `C` + import(); //~ ERROR: unresolved function `import` + + foo::<A>(); //~ ERROR: unresolved type `A` + foo::<C>(); //~ ERROR: unresolved type `C` + foo::<D>(); //~ ERROR: unresolved type `D` } diff --git a/src/test/compile-fail/import-glob-0.rs b/src/test/compile-fail/import-glob-0.rs index 21aa811ea71..12e45cfa2cb 100644 --- a/src/test/compile-fail/import-glob-0.rs +++ b/src/test/compile-fail/import-glob-0.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name - use module_of_many_things::*; mod module_of_many_things { @@ -23,6 +21,6 @@ mod module_of_many_things { fn main() { f1(); f2(); - f999(); // 'export' currently doesn't work? + f999(); //~ ERROR unresolved function `f999` f4(); } diff --git a/src/test/compile-fail/issue-14254.rs b/src/test/compile-fail/issue-14254.rs deleted file mode 100644 index c7bd343bc9a..00000000000 --- a/src/test/compile-fail/issue-14254.rs +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait Foo { - fn bar(&self); - fn baz(&self) { } - fn bah(_: Option<&Self>) { } -} - -struct BarTy { - x : isize, - y : f64, -} - -impl BarTy { - fn a() {} - fn b(&self) {} -} - -impl Foo for *const BarTy { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - a; - //~^ ERROR: unresolved name `a` - //~| NOTE unresolved name - } -} - -impl<'a> Foo for &'a BarTy { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - x; - //~^ ERROR: unresolved name `x` - //~| NOTE did you mean `self.x`? - y; - //~^ ERROR: unresolved name `y` - //~| NOTE did you mean `self.y`? - a; - //~^ ERROR: unresolved name `a` - //~| NOTE unresolved name - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - b; - //~^ ERROR: unresolved name `b` - //~| NOTE unresolved name - } -} - -impl<'a> Foo for &'a mut BarTy { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - x; - //~^ ERROR: unresolved name `x` - //~| NOTE did you mean `self.x`? - y; - //~^ ERROR: unresolved name `y` - //~| NOTE did you mean `self.y`? - a; - //~^ ERROR: unresolved name `a` - //~| NOTE unresolved name - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - b; - //~^ ERROR: unresolved name `b` - //~| NOTE unresolved name - } -} - -impl Foo for Box<BarTy> { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - } -} - -impl Foo for *const isize { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - } -} - -impl<'a> Foo for &'a isize { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - } -} - -impl<'a> Foo for &'a mut isize { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - } -} - -impl Foo for Box<isize> { - fn bar(&self) { - baz(); - //~^ ERROR: unresolved name `baz` - //~| NOTE did you mean to call `self.baz`? - bah; - //~^ ERROR: unresolved name `bah` - //~| NOTE did you mean to call `Foo::bah`? - } -} diff --git a/src/test/compile-fail/issue-1476.rs b/src/test/compile-fail/issue-1476.rs index 73a0e0c0775..b7797cf5b36 100644 --- a/src/test/compile-fail/issue-1476.rs +++ b/src/test/compile-fail/issue-1476.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - println!("{}", x); //~ ERROR unresolved name `x` + println!("{}", x); //~ ERROR unresolved value `x` } diff --git a/src/test/compile-fail/issue-15167.rs b/src/test/compile-fail/issue-15167.rs index 2bd7da91d2c..4e77636b379 100644 --- a/src/test/compile-fail/issue-15167.rs +++ b/src/test/compile-fail/issue-15167.rs @@ -11,10 +11,10 @@ // macro f should not be able to inject a reference to 'n'. macro_rules! f { () => (n) } -//~^ ERROR unresolved name `n` -//~| ERROR unresolved name `n` -//~| ERROR unresolved name `n` -//~| ERROR unresolved name `n` +//~^ ERROR unresolved value `n` +//~| ERROR unresolved value `n` +//~| ERROR unresolved value `n` +//~| ERROR unresolved value `n` fn main() -> (){ for n in 0..1 { diff --git a/src/test/compile-fail/issue-17546.rs b/src/test/compile-fail/issue-17546.rs index e640ba3f00f..fe125b973d9 100644 --- a/src/test/compile-fail/issue-17546.rs +++ b/src/test/compile-fail/issue-17546.rs @@ -20,7 +20,7 @@ mod foo { } fn new() -> NoResult<MyEnum, String> { - //~^ ERROR: found value `foo::MyEnum::NoResult` used as a type + //~^ ERROR expected type, found variant `NoResult` unimplemented!() } } @@ -30,18 +30,18 @@ mod bar { use foo; fn new() -> Result<foo::MyEnum, String> { - //~^ ERROR: found value `foo::MyEnum::Result` used as a type + //~^ ERROR expected type, found variant `Result` unimplemented!() } } fn new() -> Result<foo::MyEnum, String> { - //~^ ERROR: found value `foo::MyEnum::Result` used as a type + //~^ ERROR expected type, found variant `Result` unimplemented!() } fn newer() -> NoResult<foo::MyEnum, String> { - //~^ ERROR: found value `foo::MyEnum::NoResult` used as a type + //~^ ERROR expected type, found variant `NoResult` unimplemented!() } diff --git a/src/test/compile-fail/issue-18058.rs b/src/test/compile-fail/issue-18058.rs index 0447cf781ff..1611cc418fb 100644 --- a/src/test/compile-fail/issue-18058.rs +++ b/src/test/compile-fail/issue-18058.rs @@ -9,6 +9,6 @@ // except according to those terms. impl Undefined {} -//~^ ERROR type name `Undefined` is undefined or not in scope +//~^ ERROR unresolved type `Undefined` fn main() {} diff --git a/src/test/compile-fail/issue-18119.rs b/src/test/compile-fail/issue-18119.rs index f06496463e4..412f7566f47 100644 --- a/src/test/compile-fail/issue-18119.rs +++ b/src/test/compile-fail/issue-18119.rs @@ -13,10 +13,10 @@ static Y: u8 = 1; fn foo() {} impl X {} -//~^ ERROR type name `X` is undefined or not in scope +//~^ ERROR expected type, found constant `X` impl Y {} -//~^ ERROR type name `Y` is undefined or not in scope +//~^ ERROR expected type, found static `Y` impl foo {} -//~^ ERROR type name `foo` is undefined or not in scope +//~^ ERROR expected type, found function `foo` fn main() {} diff --git a/src/test/compile-fail/issue-19883.rs b/src/test/compile-fail/issue-19883.rs index 3a7a1692f38..6fc5fa03c58 100644 --- a/src/test/compile-fail/issue-19883.rs +++ b/src/test/compile-fail/issue-19883.rs @@ -17,7 +17,7 @@ trait From<Src> { trait To: Sized { fn to<Dst: From<Self>>(self) -> <Dst as From<Self>>::Dst - //~^ ERROR associated type `From::Dst` is undefined or not in scope + //~^ ERROR unresolved associated type `From::Dst` { From::from(self) } diff --git a/src/test/compile-fail/issue-22037.rs b/src/test/compile-fail/issue-22037.rs index 74f1be95420..2a81b55dc7b 100644 --- a/src/test/compile-fail/issue-22037.rs +++ b/src/test/compile-fail/issue-22037.rs @@ -11,7 +11,7 @@ trait A { type Output; fn a(&self) -> <Self as A>::X; -//~^ ERROR: associated type `A::X` is undefined or not in scope + //~^ ERROR unresolved associated type `A::X` } impl A for u32 { diff --git a/src/test/compile-fail/issue-22384.rs b/src/test/compile-fail/issue-22384.rs index 46a43bdfcb8..ad42a7e4a97 100644 --- a/src/test/compile-fail/issue-22384.rs +++ b/src/test/compile-fail/issue-22384.rs @@ -14,5 +14,5 @@ trait Trait { fn main() { <<i32 as Copy>::foobar as Trait>::foo(); - //~^ ERROR associated type `Copy::foobar` is undefined or not in scope + //~^ ERROR unresolved associated type `Copy::foobar` } diff --git a/src/test/compile-fail/issue-2281-part1.rs b/src/test/compile-fail/issue-2281-part1.rs index f59252dd315..8d21650ed6f 100644 --- a/src/test/compile-fail/issue-2281-part1.rs +++ b/src/test/compile-fail/issue-2281-part1.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `foobar` - -fn main() { println!("{}", foobar); } +fn main() { println!("{}", foobar); } //~ ERROR unresolved value `foobar` diff --git a/src/test/compile-fail/issue-2330.rs b/src/test/compile-fail/issue-2330.rs index 63f146a21d9..f1a282695ac 100644 --- a/src/test/compile-fail/issue-2330.rs +++ b/src/test/compile-fail/issue-2330.rs @@ -15,7 +15,7 @@ trait channel<T> { } // `chan` is not a trait, it's an enum -impl chan for isize { //~ ERROR `chan` is not a trait +impl chan for isize { //~ ERROR expected trait, found enum `chan` fn send(&self, v: isize) { panic!() } } diff --git a/src/test/compile-fail/issue-2356.rs b/src/test/compile-fail/issue-2356.rs deleted file mode 100644 index d7635d7bc94..00000000000 --- a/src/test/compile-fail/issue-2356.rs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait Groom { - fn shave(other: usize); -} - -pub struct cat { - whiskers: isize, -} - -pub enum MaybeDog { - Dog, - NoDog -} - -impl MaybeDog { - fn bark() { - // If this provides a suggestion, it's a bug as MaybeDog doesn't impl Groom - shave(); - //~^ ERROR: unresolved name `shave` - //~| NOTE unresolved name - } -} - -impl Groom for cat { - fn shave(other: usize) { - whiskers -= other; - //~^ ERROR: unresolved name `whiskers` - //~| NOTE unresolved name - //~| HELP this is an associated function - shave(4); - //~^ ERROR: unresolved name `shave` - //~| NOTE did you mean to call `Groom::shave`? - purr(); - //~^ ERROR: unresolved name `purr` - //~| NOTE unresolved name - } -} - -impl cat { - fn static_method() {} - - fn purr_louder() { - static_method(); - //~^ ERROR: unresolved name `static_method` - //~| NOTE unresolved name - purr(); - //~^ ERROR: unresolved name `purr` - //~| NOTE unresolved name - purr(); - //~^ ERROR: unresolved name `purr` - //~| NOTE unresolved name - purr(); - //~^ ERROR: unresolved name `purr` - //~| NOTE unresolved name - } -} - -impl cat { - fn meow() { - if self.whiskers > 3 { - //~^ ERROR `self` is not available in a static method [E0424] - //~| NOTE not available in static method - //~| NOTE maybe a `self` argument is missing? - println!("MEOW"); - } - } - - fn purr(&self) { - grow_older(); - //~^ ERROR: unresolved name `grow_older` - //~| NOTE unresolved name - shave(); - //~^ ERROR: unresolved name `shave` - //~| NOTE unresolved name - } - - fn burn_whiskers(&mut self) { - whiskers = 0; - //~^ ERROR: unresolved name `whiskers` - //~| NOTE did you mean `self.whiskers`? - } - - pub fn grow_older(other:usize) { - whiskers = 4; - //~^ ERROR: unresolved name `whiskers` - //~| NOTE unresolved name - //~| HELP this is an associated function - purr_louder(); - //~^ ERROR: unresolved name `purr_louder` - //~| NOTE unresolved name - } -} - -fn main() { - self += 1; - //~^ ERROR: unresolved name `self` - //~| NOTE unresolved name - //~| HELP: module `self` - // it's a bug if this suggests a missing `self` as we're not in a method -} diff --git a/src/test/compile-fail/issue-28388-1.rs b/src/test/compile-fail/issue-28388-1.rs index ed7851ec0f1..334fdee00a0 100644 --- a/src/test/compile-fail/issue-28388-1.rs +++ b/src/test/compile-fail/issue-28388-1.rs @@ -10,8 +10,6 @@ // Prefix in imports with empty braces should be resolved and checked privacy, stability, etc. -use foo::{}; -//~^ ERROR failed to resolve. Maybe a missing `extern crate foo;`? -//~| NOTE foo +use foo::{}; //~ ERROR unresolved module or enum `foo` fn main() {} diff --git a/src/test/compile-fail/issue-28388-3.rs b/src/test/compile-fail/issue-28388-3.rs index 4baaa16e772..12357779b51 100644 --- a/src/test/compile-fail/issue-28388-3.rs +++ b/src/test/compile-fail/issue-28388-3.rs @@ -14,8 +14,7 @@ extern crate lint_stability; -use lint_stability::UnstableStruct::{}; -//~^ ERROR use of unstable library feature 'test_feature' -use lint_stability::StableStruct::{}; // OK +use lint_stability::UnstableEnum::{}; //~ ERROR use of unstable library feature 'test_feature' +use lint_stability::StableEnum::{}; // OK fn main() {} diff --git a/src/test/compile-fail/issue-30535.rs b/src/test/compile-fail/issue-30535.rs index 93f3086d057..90f5220a623 100644 --- a/src/test/compile-fail/issue-30535.rs +++ b/src/test/compile-fail/issue-30535.rs @@ -13,7 +13,7 @@ extern crate issue_30535 as foo; fn bar( - _: foo::Foo::FooV //~ ERROR value `foo::Foo::FooV` used as a type + _: foo::Foo::FooV //~ ERROR expected type, found variant `foo::Foo::FooV` ) {} fn main() {} diff --git a/src/test/compile-fail/issue-30589.rs b/src/test/compile-fail/issue-30589.rs index 32765d5acb4..dd5fac9bed1 100644 --- a/src/test/compile-fail/issue-30589.rs +++ b/src/test/compile-fail/issue-30589.rs @@ -10,7 +10,7 @@ use std::fmt; -impl fmt::Display for DecoderError { //~ ERROR E0412 +impl fmt::Display for DecoderError { //~ ERROR unresolved type `DecoderError` fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Missing data: {}", self.0) } diff --git a/src/test/compile-fail/issue-31845.rs b/src/test/compile-fail/issue-31845.rs index 344a1117254..32e004af1f3 100644 --- a/src/test/compile-fail/issue-31845.rs +++ b/src/test/compile-fail/issue-31845.rs @@ -14,7 +14,7 @@ fn f() { fn g() {} mod foo { fn h() { - g(); //~ ERROR unresolved name + g(); //~ ERROR unresolved function `g` } } } diff --git a/src/test/compile-fail/issue-34334.rs b/src/test/compile-fail/issue-34334.rs index ffcd052369d..fa672557c5e 100644 --- a/src/test/compile-fail/issue-34334.rs +++ b/src/test/compile-fail/issue-34334.rs @@ -11,5 +11,5 @@ fn main () { let sr: Vec<(u32, _, _) = vec![]; //~ ERROR expected one of `+`, `,`, or `>`, found `=` let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); - //~^ ERROR unresolved name `sr` + //~^ ERROR unresolved value `sr` } diff --git a/src/test/compile-fail/issue-35075.rs b/src/test/compile-fail/issue-35075.rs index a70452dcbd0..39d06312aa7 100644 --- a/src/test/compile-fail/issue-35075.rs +++ b/src/test/compile-fail/issue-35075.rs @@ -9,11 +9,11 @@ // except according to those terms. struct Bar<T> { - inner: Foo<T> //~ ERROR type name `Foo` is undefined or not in scope + inner: Foo<T> //~ ERROR unresolved type `Foo` } enum Baz<T> { - Foo(Foo<T>) //~ ERROR type name `Foo` is undefined or not in scope + Foo(Foo<T>) //~ ERROR unresolved type `Foo` } fn main() {} diff --git a/src/test/compile-fail/issue-37534.rs b/src/test/compile-fail/issue-37534.rs index eb676601e89..1a6d92166d7 100644 --- a/src/test/compile-fail/issue-37534.rs +++ b/src/test/compile-fail/issue-37534.rs @@ -9,8 +9,8 @@ // except according to those terms. struct Foo<T: ?Hash> { } -//~^ ERROR trait `Hash` is not in scope [E0405] -//~^^ ERROR parameter `T` is never used [E0392] +//~^ ERROR unresolved trait `Hash` +//~^^ ERROR parameter `T` is never used //~^^^ WARN default bound relaxed for a type parameter, but this does nothing fn main() { } diff --git a/src/test/compile-fail/issue-4366-2.rs b/src/test/compile-fail/issue-4366-2.rs index a6fe719509c..687720a130c 100644 --- a/src/test/compile-fail/issue-4366-2.rs +++ b/src/test/compile-fail/issue-4366-2.rs @@ -23,7 +23,7 @@ mod a { pub mod sub { use a::b::*; fn sub() -> bar { 1 } - //~^ ERROR: type name `bar` is undefined or not in scope + //~^ ERROR unresolved type `bar` } } @@ -32,5 +32,5 @@ mod m1 { } fn main() { - foo(); //~ ERROR: unresolved name + foo(); //~ ERROR expected function, found module `foo` } diff --git a/src/test/compile-fail/issue-4366.rs b/src/test/compile-fail/issue-4366.rs index 5625ac00c85..18e55ee3c2a 100644 --- a/src/test/compile-fail/issue-4366.rs +++ b/src/test/compile-fail/issue-4366.rs @@ -25,7 +25,7 @@ mod a { } pub mod sub { use a::b::*; - fn sub() -> isize { foo(); 1 } //~ ERROR: unresolved name `foo` + fn sub() -> isize { foo(); 1 } //~ ERROR unresolved function `foo` } } diff --git a/src/test/compile-fail/issue-5099.rs b/src/test/compile-fail/issue-5099.rs index c2e1fc615cc..e78b54bd411 100644 --- a/src/test/compile-fail/issue-5099.rs +++ b/src/test/compile-fail/issue-5099.rs @@ -9,6 +9,6 @@ // except according to those terms. -trait B < A > { fn a() -> A { this.a } } //~ ERROR unresolved name +trait B < A > { fn a() -> A { this.a } } //~ ERROR unresolved value `this` fn main() {} diff --git a/src/test/compile-fail/issue-5927.rs b/src/test/compile-fail/issue-5927.rs index 7668a2117a2..c421dbd1eb3 100644 --- a/src/test/compile-fail/issue-5927.rs +++ b/src/test/compile-fail/issue-5927.rs @@ -12,7 +12,7 @@ fn main() { let z = match 3 { x(1) => x(1) //~ ERROR unresolved tuple struct/variant `x` - //~^ ERROR unresolved name `x` + //~^ ERROR unresolved function `x` }; assert!(z == 3); } diff --git a/src/test/compile-fail/issue-7607-1.rs b/src/test/compile-fail/issue-7607-1.rs index 96ac2de1762..e7b7decbdb0 100644 --- a/src/test/compile-fail/issue-7607-1.rs +++ b/src/test/compile-fail/issue-7607-1.rs @@ -12,7 +12,7 @@ struct Foo { x: isize } -impl Fo { //~ ERROR type name `Fo` is undefined or not in scope +impl Fo { //~ ERROR unresolved type `Fo` fn foo() {} } diff --git a/src/test/compile-fail/issue-8767.rs b/src/test/compile-fail/issue-8767.rs index 1c97c0c886d..318eab92252 100644 --- a/src/test/compile-fail/issue-8767.rs +++ b/src/test/compile-fail/issue-8767.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -impl B { //~ ERROR type name `B` is undefined or not in scope +impl B { //~ ERROR unresolved type `B` } fn main() { diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/compile-fail/keyword-super-as-identifier.rs index 531705563e2..62649ba8a0f 100644 --- a/src/test/compile-fail/keyword-super-as-identifier.rs +++ b/src/test/compile-fail/keyword-super-as-identifier.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let super = "foo"; //~ ERROR unresolved unit struct/variant or constant `super` + let super = "foo"; //~ ERROR failed to resolve. There are too many initial `super`s } diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/compile-fail/keyword-super.rs index 9ac9e800c84..02047bd639f 100644 --- a/src/test/compile-fail/keyword-super.rs +++ b/src/test/compile-fail/keyword-super.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let super: isize; //~ ERROR unresolved unit struct/variant or constant `super` + let super: isize; //~ ERROR failed to resolve. There are too many initial `super`s } diff --git a/src/test/compile-fail/macro-outer-attributes.rs b/src/test/compile-fail/macro-outer-attributes.rs index 0469a9d1cc8..70a50d83904 100644 --- a/src/test/compile-fail/macro-outer-attributes.rs +++ b/src/test/compile-fail/macro-outer-attributes.rs @@ -25,6 +25,6 @@ test!(b, // test1!(#[bar]) #[qux] fn main() { - a::bar(); //~ ERROR unresolved name `a::bar` + a::bar(); //~ ERROR unresolved function `a::bar` b::bar(); } diff --git a/src/test/compile-fail/macro-parameter-span.rs b/src/test/compile-fail/macro-parameter-span.rs index 2ef69759128..dc5a2deab42 100644 --- a/src/test/compile-fail/macro-parameter-span.rs +++ b/src/test/compile-fail/macro-parameter-span.rs @@ -18,6 +18,6 @@ macro_rules! foo { // not to the macro variable '$id' fn main() { foo!( - x //~ ERROR unresolved name `x` + x //~ ERROR unresolved value `x` ); } diff --git a/src/test/compile-fail/match-join.rs b/src/test/compile-fail/match-join.rs index 4ec426fd3aa..3f6304db957 100644 --- a/src/test/compile-fail/match-join.rs +++ b/src/test/compile-fail/match-join.rs @@ -16,6 +16,6 @@ fn my_panic() -> ! { panic!(); } fn main() { match true { false => { my_panic(); } true => { } } - println!("{}", x); //~ ERROR unresolved name `x` + println!("{}", x); //~ ERROR unresolved value `x` let x: isize; } diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 596cec167c2..4cf8eea78cf 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -34,7 +34,7 @@ fn main() { [0, 1, 2, 3, x..] => {} //~ ERROR pattern requires }; - match does_not_exist { //~ ERROR unresolved name + match does_not_exist { //~ ERROR unresolved value `does_not_exist` [] => {} }; } diff --git a/src/test/compile-fail/mod_file_correct_spans.rs b/src/test/compile-fail/mod_file_correct_spans.rs index f8ea5dda183..c64b22a7f41 100644 --- a/src/test/compile-fail/mod_file_correct_spans.rs +++ b/src/test/compile-fail/mod_file_correct_spans.rs @@ -13,5 +13,5 @@ mod mod_file_aux; fn main() { - assert!(mod_file_aux::bar() == 10); //~ ERROR unresolved name + assert!(mod_file_aux::bar() == 10); //~ ERROR unresolved function `mod_file_aux::bar` } diff --git a/src/test/compile-fail/name-clash-nullary.rs b/src/test/compile-fail/name-clash-nullary.rs index 4c76c4b8b02..359417aee52 100644 --- a/src/test/compile-fail/name-clash-nullary.rs +++ b/src/test/compile-fail/name-clash-nullary.rs @@ -13,6 +13,6 @@ use std::option::*; fn main() { let None: isize = 42; //~ ERROR let bindings cannot shadow unit variants log(debug, None); - //~^ ERROR unresolved name `debug` - //~| ERROR unresolved name `log` + //~^ ERROR unresolved function `log` + //~| ERROR unresolved value `debug` } diff --git a/src/test/compile-fail/namespace-mix.rs b/src/test/compile-fail/namespace-mix.rs index cb7894b726f..c1c724fc431 100644 --- a/src/test/compile-fail/namespace-mix.rs +++ b/src/test/compile-fail/namespace-mix.rs @@ -41,13 +41,13 @@ mod m2 { fn f12() { check(m1::S{}); //~ ERROR c::Item - check(m1::S); //~ ERROR unresolved name + check(m1::S); //~ ERROR expected value, found type alias `m1::S` check(m2::S{}); //~ ERROR c::S check(m2::S); //~ ERROR c::Item } fn xf12() { check(xm1::S{}); //~ ERROR c::Item - check(xm1::S); //~ ERROR unresolved name + check(xm1::S); //~ ERROR expected value, found type alias `xm1::S` check(xm2::S{}); //~ ERROR c::S check(xm2::S); //~ ERROR c::Item } @@ -107,13 +107,13 @@ mod m8 { fn f78() { check(m7::V{}); //~ ERROR c::Item - check(m7::V); //~ ERROR name of a struct or struct variant + check(m7::V); //~ ERROR expected value, found struct variant `m7::V` check(m8::V{}); //~ ERROR c::E check(m8::V); //~ ERROR c::Item } fn xf78() { check(xm7::V{}); //~ ERROR c::Item - check(xm7::V); //~ ERROR name of a struct or struct variant + check(xm7::V); //~ ERROR expected value, found struct variant `xm7::V` check(xm8::V{}); //~ ERROR c::E check(xm8::V); //~ ERROR c::Item } diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs index 4fcb31d3686..d92323e290b 100644 --- a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs @@ -18,8 +18,8 @@ mod m { pub fn main() { use namespaced_enums::Foo::*; - foo(); //~ ERROR unresolved name `foo` - m::foo(); //~ ERROR unresolved name `m::foo` - bar(); //~ ERROR unresolved name `bar` - m::bar(); //~ ERROR unresolved name `m::bar` + foo(); //~ ERROR unresolved function `foo` + m::foo(); //~ ERROR unresolved function `m::foo` + bar(); //~ ERROR unresolved function `bar` + m::bar(); //~ ERROR unresolved function `m::bar` } diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs index 4437482fb67..b7c7397ee98 100644 --- a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs @@ -28,8 +28,8 @@ mod m { pub fn main() { use m2::Foo::*; - foo(); //~ ERROR unresolved name `foo` - m::foo(); //~ ERROR unresolved name `m::foo` - bar(); //~ ERROR unresolved name `bar` - m::bar(); //~ ERROR unresolved name `m::bar` + foo(); //~ ERROR unresolved function `foo` + m::foo(); //~ ERROR unresolved function `m::foo` + bar(); //~ ERROR unresolved function `bar` + m::bar(); //~ ERROR unresolved function `m::bar` } diff --git a/src/test/compile-fail/nested-cfg-attrs.rs b/src/test/compile-fail/nested-cfg-attrs.rs index 6010b1e695e..f3e20f4f614 100644 --- a/src/test/compile-fail/nested-cfg-attrs.rs +++ b/src/test/compile-fail/nested-cfg-attrs.rs @@ -11,4 +11,4 @@ #[cfg_attr(all(), cfg_attr(all(), cfg(foo)))] fn f() {} -fn main() { f() } //~ ERROR unresolved name `f` +fn main() { f() } //~ ERROR unresolved function `f` diff --git a/src/test/compile-fail/no-implicit-prelude-nested.rs b/src/test/compile-fail/no-implicit-prelude-nested.rs index af1046bcd5d..49e2e9f34fa 100644 --- a/src/test/compile-fail/no-implicit-prelude-nested.rs +++ b/src/test/compile-fail/no-implicit-prelude-nested.rs @@ -18,26 +18,26 @@ mod foo { mod baz { struct Test; - impl Add for Test {} //~ ERROR: not in scope - impl Clone for Test {} //~ ERROR: not in scope - impl Iterator for Test {} //~ ERROR: not in scope - impl ToString for Test {} //~ ERROR: not in scope - impl Writer for Test {} //~ ERROR: not in scope + impl Add for Test {} //~ ERROR unresolved trait `Add` + impl Clone for Test {} //~ ERROR unresolved trait `Clone` + impl Iterator for Test {} //~ ERROR unresolved trait `Iterator` + impl ToString for Test {} //~ ERROR unresolved trait `ToString` + impl Writer for Test {} //~ ERROR unresolved trait `Writer` fn foo() { - drop(2) //~ ERROR: unresolved name + drop(2) //~ ERROR unresolved function `drop` } } struct Test; - impl Add for Test {} //~ ERROR: not in scope - impl Clone for Test {} //~ ERROR: not in scope - impl Iterator for Test {} //~ ERROR: not in scope - impl ToString for Test {} //~ ERROR: not in scope - impl Writer for Test {} //~ ERROR: not in scope + impl Add for Test {} //~ ERROR unresolved trait `Add` + impl Clone for Test {} //~ ERROR unresolved trait `Clone` + impl Iterator for Test {} //~ ERROR unresolved trait `Iterator` + impl ToString for Test {} //~ ERROR unresolved trait `ToString` + impl Writer for Test {} //~ ERROR unresolved trait `Writer` fn foo() { - drop(2) //~ ERROR: unresolved name + drop(2) //~ ERROR unresolved function `drop` } } @@ -45,14 +45,14 @@ fn qux() { #[no_implicit_prelude] mod qux_inner { struct Test; - impl Add for Test {} //~ ERROR: not in scope - impl Clone for Test {} //~ ERROR: not in scope - impl Iterator for Test {} //~ ERROR: not in scope - impl ToString for Test {} //~ ERROR: not in scope - impl Writer for Test {} //~ ERROR: not in scope + impl Add for Test {} //~ ERROR unresolved trait `Add` + impl Clone for Test {} //~ ERROR unresolved trait `Clone` + impl Iterator for Test {} //~ ERROR unresolved trait `Iterator` + impl ToString for Test {} //~ ERROR unresolved trait `ToString` + impl Writer for Test {} //~ ERROR unresolved trait `Writer` fn foo() { - drop(2) //~ ERROR: unresolved name + drop(2) //~ ERROR unresolved function `drop` } } } diff --git a/src/test/compile-fail/no-implicit-prelude.rs b/src/test/compile-fail/no-implicit-prelude.rs index 4693fd14e7d..b830a64fa81 100644 --- a/src/test/compile-fail/no-implicit-prelude.rs +++ b/src/test/compile-fail/no-implicit-prelude.rs @@ -17,12 +17,12 @@ // fail with the same error message). struct Test; -impl Add for Test {} //~ ERROR: not in scope -impl Clone for Test {} //~ ERROR: not in scope -impl Iterator for Test {} //~ ERROR: not in scope -impl ToString for Test {} //~ ERROR: not in scope -impl Writer for Test {} //~ ERROR: not in scope +impl Add for Test {} //~ ERROR unresolved trait `Add` +impl Clone for Test {} //~ ERROR unresolved trait `Clone` +impl Iterator for Test {} //~ ERROR unresolved trait `Iterator` +impl ToString for Test {} //~ ERROR unresolved trait `ToString` +impl Writer for Test {} //~ ERROR unresolved trait `Writer` fn main() { - drop(2) //~ ERROR: unresolved name + drop(2) //~ ERROR unresolved function `drop` } diff --git a/src/test/compile-fail/no-link.rs b/src/test/compile-fail/no-link.rs index c4737a37399..7e4e55543cd 100644 --- a/src/test/compile-fail/no-link.rs +++ b/src/test/compile-fail/no-link.rs @@ -15,5 +15,5 @@ extern crate empty_struct; //~^ WARN custom derive crates and `#[no_link]` crates have no effect without `#[macro_use]` fn main() { - empty_struct::XEmpty1; //~ ERROR unresolved name + empty_struct::XEmpty1; //~ ERROR unresolved value `empty_struct::XEmpty1` } diff --git a/src/test/compile-fail/parser-recovery-1.rs b/src/test/compile-fail/parser-recovery-1.rs index 85b62461238..373b33c3e49 100644 --- a/src/test/compile-fail/parser-recovery-1.rs +++ b/src/test/compile-fail/parser-recovery-1.rs @@ -14,11 +14,11 @@ trait Foo { fn bar() { - let x = foo(); //~ ERROR unresolved name `foo` + let x = foo(); //~ ERROR unresolved function `foo` } fn main() { let x = y.; //~ ERROR unexpected token - //~^ ERROR unresolved name `y` + //~^ ERROR unresolved value `y` } //~ ERROR this file contains an un-closed delimiter diff --git a/src/test/compile-fail/parser-recovery-2.rs b/src/test/compile-fail/parser-recovery-2.rs index 109da6251e3..c2bbbda4011 100644 --- a/src/test/compile-fail/parser-recovery-2.rs +++ b/src/test/compile-fail/parser-recovery-2.rs @@ -14,11 +14,11 @@ trait Foo { fn bar() { - let x = foo(); //~ ERROR unresolved name `foo` + let x = foo(); //~ ERROR unresolved function `foo` ) //~ ERROR incorrect close delimiter: `)` } fn main() { let x = y.; //~ ERROR unexpected token - //~^ ERROR unresolved name `y` + //~^ ERROR unresolved value `y` } diff --git a/src/test/compile-fail/pattern-macro-hygiene.rs b/src/test/compile-fail/pattern-macro-hygiene.rs index 1c79c9a2293..24f29666172 100644 --- a/src/test/compile-fail/pattern-macro-hygiene.rs +++ b/src/test/compile-fail/pattern-macro-hygiene.rs @@ -12,5 +12,5 @@ macro_rules! foo { () => ( x ) } fn main() { let foo!() = 2; - x + 1; //~ ERROR unresolved name `x` + x + 1; //~ ERROR unresolved value `x` } diff --git a/src/test/compile-fail/privacy-ns1.rs b/src/test/compile-fail/privacy-ns1.rs index dcab3a46b0a..9c1e8250dbc 100644 --- a/src/test/compile-fail/privacy-ns1.rs +++ b/src/test/compile-fail/privacy-ns1.rs @@ -27,7 +27,7 @@ pub mod foo1 { fn test_glob1() { use foo1::*; - Bar(); //~ ERROR unresolved name `Bar` + Bar(); //~ ERROR expected function, found trait `Bar` } // private type, public value @@ -42,7 +42,7 @@ pub mod foo2 { fn test_glob2() { use foo2::*; - let _x: Box<Bar>; //~ ERROR type name `Bar` is undefined or not in scope + let _x: Box<Bar>; //~ ERROR expected type, found function `Bar` } // neither public @@ -57,8 +57,8 @@ pub mod foo3 { fn test_glob3() { use foo3::*; - Bar(); //~ ERROR unresolved name `Bar` - let _x: Box<Bar>; //~ ERROR type name `Bar` is undefined or not in scope + Bar(); //~ ERROR unresolved function `Bar` + let _x: Box<Bar>; //~ ERROR unresolved type `Bar` } fn main() { diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs index 7accf0ca820..ec9396b5e7b 100644 --- a/src/test/compile-fail/privacy-ns2.rs +++ b/src/test/compile-fail/privacy-ns2.rs @@ -27,13 +27,13 @@ pub mod foo1 { fn test_single1() { use foo1::Bar; - Bar(); //~ ERROR unresolved name `Bar` + Bar(); //~ ERROR expected function, found trait `Bar` } fn test_list1() { use foo1::{Bar,Baz}; - Bar(); //~ ERROR unresolved name `Bar` + Bar(); //~ ERROR expected function, found trait `Bar` } // private type, public value @@ -48,13 +48,13 @@ pub mod foo2 { fn test_single2() { use foo2::Bar; - let _x : Box<Bar>; //~ ERROR type name `Bar` is undefined + let _x : Box<Bar>; //~ ERROR expected type, found function `Bar` } fn test_list2() { use foo2::{Bar,Baz}; - let _x: Box<Bar>; //~ ERROR type name `Bar` is undefined + let _x: Box<Bar>; //~ ERROR expected type, found function `Bar` } // neither public diff --git a/src/test/compile-fail/privacy/restricted/test.rs b/src/test/compile-fail/privacy/restricted/test.rs index 3e1bb766622..01e2c6cd7e8 100644 --- a/src/test/compile-fail/privacy/restricted/test.rs +++ b/src/test/compile-fail/privacy/restricted/test.rs @@ -57,6 +57,6 @@ fn main() { } mod pathological { - pub(bad::path) mod m1 {} //~ ERROR failed to resolve module path + pub(bad::path) mod m1 {} //~ ERROR failed to resolve. Maybe a missing `extern crate bad;`? pub(foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules } diff --git a/src/test/compile-fail/privacy/restricted/ty-params.rs b/src/test/compile-fail/privacy/restricted/ty-params.rs index ae60c4366ee..593713a6e05 100644 --- a/src/test/compile-fail/privacy/restricted/ty-params.rs +++ b/src/test/compile-fail/privacy/restricted/ty-params.rs @@ -16,11 +16,11 @@ macro_rules! m { struct S<T>(T); m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path -//~^ ERROR failed to resolve module path. Not a module `S` +//~^ ERROR expected module, found struct `S` mod foo { struct S(pub(foo<T>) ()); //~ ERROR type or lifetime parameters in visibility path - //~^ ERROR type name `T` is undefined or not in scope + //~^ ERROR unresolved type `T` } fn main() {} diff --git a/src/test/compile-fail/recursive-reexports.rs b/src/test/compile-fail/recursive-reexports.rs index aa444d45eeb..48ec16a7610 100644 --- a/src/test/compile-fail/recursive-reexports.rs +++ b/src/test/compile-fail/recursive-reexports.rs @@ -12,6 +12,6 @@ extern crate recursive_reexports; -fn f() -> recursive_reexports::S {} //~ ERROR type name `recursive_reexports::S` is undefined +fn f() -> recursive_reexports::S {} //~ ERROR unresolved type `recursive_reexports::S` fn main() {} diff --git a/src/test/compile-fail/resolve-bad-import-prefix.rs b/src/test/compile-fail/resolve-bad-import-prefix.rs new file mode 100644 index 00000000000..6b4a5122ad0 --- /dev/null +++ b/src/test/compile-fail/resolve-bad-import-prefix.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod m {} +enum E {} +struct S; +trait Tr {} + +use {}; // OK +use ::{}; // OK +use m::{}; // OK +use E::{}; // OK +use S::{}; //~ ERROR expected module or enum, found struct `S` +use Tr::{}; //~ ERROR expected module or enum, found trait `Tr` +use Nonexistent::{}; //~ ERROR unresolved module or enum `Nonexistent` + +fn main () {} diff --git a/src/test/compile-fail/resolve-bad-visibility.rs b/src/test/compile-fail/resolve-bad-visibility.rs new file mode 100644 index 00000000000..088a4e6cd76 --- /dev/null +++ b/src/test/compile-fail/resolve-bad-visibility.rs @@ -0,0 +1,27 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(pub_restricted)] + +enum E {} +trait Tr {} + +pub(E) struct S; //~ ERROR expected module, found enum `E` +pub(Tr) struct Z; //~ ERROR expected module, found trait `Tr` +pub(std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules +pub(nonexistent) struct G; //~ ERROR unresolved module `nonexistent` +pub(too_soon) struct H; //~ ERROR unresolved module `too_soon` + +// Visibilities are resolved eagerly without waiting for modules becoming fully populated. +// Visibilities can only use ancestor modules legally which are always available in time, +// so the worst thing that can happen due to eager resolution is a suboptimal error message. +mod too_soon {} + +fn main () {} diff --git a/src/test/compile-fail/resolve-primitive-fallback.rs b/src/test/compile-fail/resolve-primitive-fallback.rs index 3c585680eab..de463cd9e6a 100644 --- a/src/test/compile-fail/resolve-primitive-fallback.rs +++ b/src/test/compile-fail/resolve-primitive-fallback.rs @@ -11,10 +11,10 @@ fn main() { // Make sure primitive type fallback doesn't work in value namespace std::mem::size_of(u16); - //~^ ERROR unresolved name `u16` + //~^ ERROR expected value, found builtin type `u16` //~| ERROR this function takes 0 parameters but 1 parameter was supplied // Make sure primitive type fallback doesn't work with global paths let _: ::u8; - //~^ ERROR type name `::u8` is undefined or not in scope + //~^ ERROR unresolved type `u8` } diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs index dae3a79832b..affafbfadcf 100644 --- a/src/test/compile-fail/resolve-unknown-trait.rs +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -10,10 +10,10 @@ trait NewTrait : SomeNonExistentTrait {} -//~^ ERROR trait `SomeNonExistentTrait` is not in scope +//~^ ERROR unresolved trait `SomeNonExistentTrait` impl SomeNonExistentTrait for isize {} -//~^ ERROR trait `SomeNonExistentTrait` is not in scope +//~^ ERROR unresolved trait `SomeNonExistentTrait` fn f<T:SomeNonExistentTrait>() {} -//~^ ERROR trait `SomeNonExistentTrait` is not in scope +//~^ ERROR unresolved trait `SomeNonExistentTrait` diff --git a/src/test/compile-fail/rmeta.rs b/src/test/compile-fail/rmeta.rs index e81e0541096..455574bbb9d 100644 --- a/src/test/compile-fail/rmeta.rs +++ b/src/test/compile-fail/rmeta.rs @@ -15,5 +15,5 @@ #![crate_type="metadata"] fn main() { - let _ = Foo; //~ ERROR unresolved name `Foo` + let _ = Foo; //~ ERROR unresolved value `Foo` } diff --git a/src/test/compile-fail/struct-fields-shorthand-unresolved.rs b/src/test/compile-fail/struct-fields-shorthand-unresolved.rs index 50a43f4a276..d1555373015 100644 --- a/src/test/compile-fail/struct-fields-shorthand-unresolved.rs +++ b/src/test/compile-fail/struct-fields-shorthand-unresolved.rs @@ -19,6 +19,6 @@ fn main() { let x = 0; let foo = Foo { x, - y //~ ERROR unresolved name `y` + y //~ ERROR unresolved value `y` }; } diff --git a/src/test/compile-fail/syntax-extension-minor.rs b/src/test/compile-fail/syntax-extension-minor.rs index f06e3544e57..0beb4f084c8 100644 --- a/src/test/compile-fail/syntax-extension-minor.rs +++ b/src/test/compile-fail/syntax-extension-minor.rs @@ -18,7 +18,7 @@ pub fn main() { // this now fails (correctly, I claim) because hygiene prevents // the assembled identifier from being a reference to the binding. assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string()); - //~^ ERROR: unresolved name `asdf_fdsa` + //~^ ERROR unresolved value `asdf_fdsa` assert_eq!(stringify!(use_mention_distinction), "use_mention_distinction"); } diff --git a/src/test/compile-fail/test-cfg.rs b/src/test/compile-fail/test-cfg.rs index 0709d909512..28c69e8df22 100644 --- a/src/test/compile-fail/test-cfg.rs +++ b/src/test/compile-fail/test-cfg.rs @@ -14,5 +14,5 @@ fn foo() {} fn main() { - foo(); //~ ERROR unresolved name `foo` + foo(); //~ ERROR unresolved function `foo` } diff --git a/src/test/compile-fail/ufcs-partially-resolved.rs b/src/test/compile-fail/ufcs-partially-resolved.rs new file mode 100644 index 00000000000..5337272343b --- /dev/null +++ b/src/test/compile-fail/ufcs-partially-resolved.rs @@ -0,0 +1,66 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(associated_type_defaults)] + +trait Tr { + type Y = u16; + fn Y() {} +} +impl Tr for u8 {} + +trait Dr { + type X = u16; + fn Z() {} +} +impl Dr for u8 {} + +enum E { Y } +type A = u32; + +fn main() { + let _: <u8 as Tr>::N; //~ ERROR unresolved associated type `Tr::N` + let _: <u8 as E>::N; //~ ERROR unresolved associated type `E::N` + let _: <u8 as A>::N; //~ ERROR unresolved associated type `A::N` + <u8 as Tr>::N; //~ ERROR unresolved method or associated constant `Tr::N` + <u8 as E>::N; //~ ERROR unresolved method or associated constant `E::N` + <u8 as A>::N; //~ ERROR unresolved method or associated constant `A::N` + let _: <u8 as Tr>::Y; // OK + let _: <u8 as E>::Y; //~ ERROR expected associated type, found variant `E::Y` + <u8 as Tr>::Y; // OK + <u8 as E>::Y; //~ ERROR expected method or associated constant, found unit variant `E::Y` + + let _: <u8 as Tr>::N::NN; //~ ERROR unresolved associated type `Tr::N` + let _: <u8 as E>::N::NN; //~ ERROR unresolved associated type `E::N` + let _: <u8 as A>::N::NN; //~ ERROR unresolved associated type `A::N` + <u8 as Tr>::N::NN; //~ ERROR unresolved associated type `Tr::N` + <u8 as E>::N::NN; //~ ERROR unresolved associated type `E::N` + <u8 as A>::N::NN; //~ ERROR unresolved associated type `A::N` + let _: <u8 as Tr>::Y::NN; //~ ERROR ambiguous associated type + let _: <u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y` + <u8 as Tr>::Y::NN; //~ ERROR no associated item named `NN` found for type `<u8 as Tr>::Y` + <u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y` + + let _: <u8 as Tr::N>::NN; //~ ERROR unresolved associated type `Tr::N::NN` + let _: <u8 as E::N>::NN; //~ ERROR unresolved associated type `E::N::NN` + let _: <u8 as A::N>::NN; //~ ERROR unresolved associated type `A::N::NN` + <u8 as Tr::N>::NN; //~ ERROR unresolved method or associated constant `Tr::N::NN` + <u8 as E::N>::NN; //~ ERROR unresolved method or associated constant `E::N::NN` + <u8 as A::N>::NN; //~ ERROR unresolved method or associated constant `A::N::NN` + let _: <u8 as Tr::Y>::NN; //~ ERROR unresolved associated type `Tr::Y::NN` + let _: <u8 as E::Y>::NN; //~ ERROR unresolved associated type `E::Y::NN` + <u8 as Tr::Y>::NN; //~ ERROR unresolved method or associated constant `Tr::Y::NN` + <u8 as E::Y>::NN; //~ ERROR unresolved method or associated constant `E::Y::NN` + + let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found method `Dr::Z` + <u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X` + let _: <u8 as Dr>::Z::N; //~ ERROR expected associated type, found method `Dr::Z` + <u8 as Dr>::X::N; //~ ERROR no associated item named `N` found for type `<u8 as Dr>::X` +} diff --git a/src/test/compile-fail/variant-used-as-type.rs b/src/test/compile-fail/variant-used-as-type.rs index 73defa6eef9..c889b7d28f8 100644 --- a/src/test/compile-fail/variant-used-as-type.rs +++ b/src/test/compile-fail/variant-used-as-type.rs @@ -15,7 +15,7 @@ enum Ty { A, B(Ty::A), - //~^ ERROR: found value `Ty::A` used as a type + //~^ ERROR expected type, found variant `Ty::A` } @@ -25,6 +25,6 @@ enum E { } impl E::A {} -//~^ ERROR: found value `E::A` used as a type +//~^ ERROR expected type, found variant `E::A` fn main() {} diff --git a/src/test/compile-fail/xcrate-unit-struct.rs b/src/test/compile-fail/xcrate-unit-struct.rs index 214a2a371ba..04af7133000 100644 --- a/src/test/compile-fail/xcrate-unit-struct.rs +++ b/src/test/compile-fail/xcrate-unit-struct.rs @@ -17,6 +17,6 @@ extern crate xcrate_unit_struct; fn main() { let _ = xcrate_unit_struct::StructWithFields; - //~^ ERROR: `xcrate_unit_struct::StructWithFields` is the name of a struct or struct variant + //~^ ERROR expected value, found struct `xcrate_unit_struct::StructWithFields` let _ = xcrate_unit_struct::Struct; } diff --git a/src/test/ui/codemap_tests/tab.stderr b/src/test/ui/codemap_tests/tab.stderr index f865f0a5f23..73d548009dd 100644 --- a/src/test/ui/codemap_tests/tab.stderr +++ b/src/test/ui/codemap_tests/tab.stderr @@ -1,8 +1,8 @@ -error[E0425]: unresolved name `bar` +error[E0425]: unresolved value `bar` --> $DIR/tab.rs:14:2 | 14 | \tbar; - | \t^^^ unresolved name + | \t^^^ no resolution found error: aborting due to previous error diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index d05e6eb2bbe..9db43dde1ac 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -1,10 +1,8 @@ -error[E0404]: `Bar` is not a trait +error[E0404]: expected trait, found type alias `Bar` --> $DIR/two_files.rs:15:6 | 15 | impl Bar for Baz { } - | ^^^ expected trait, found type alias - | - = note: type aliases cannot be used for traits + | ^^^ type aliases cannot be used for traits error: cannot continue compilation due to previous error diff --git a/src/test/ui/macros/macro-backtrace-nested.stderr b/src/test/ui/macros/macro-backtrace-nested.stderr index 1c7fac894f9..27514093621 100644 --- a/src/test/ui/macros/macro-backtrace-nested.stderr +++ b/src/test/ui/macros/macro-backtrace-nested.stderr @@ -1,17 +1,17 @@ -error[E0425]: unresolved name `fake` +error[E0425]: unresolved value `fake` --> $DIR/macro-backtrace-nested.rs:15:12 | 15 | () => (fake) - | ^^^^ unresolved name + | ^^^^ no resolution found ... 27 | 1 + call_nested_expr!(); | ------------------- in this macro invocation -error[E0425]: unresolved name `fake` +error[E0425]: unresolved value `fake` --> $DIR/macro-backtrace-nested.rs:15:12 | 15 | () => (fake) - | ^^^^ unresolved name + | ^^^^ no resolution found ... 28 | call_nested_expr_sum!(); | ------------------------ in this macro invocation diff --git a/src/test/compile-fail/auxiliary/issue-21221-3.rs b/src/test/ui/resolve/auxiliary/issue-21221-3.rs index fae0fe16a26..fae0fe16a26 100644 --- a/src/test/compile-fail/auxiliary/issue-21221-3.rs +++ b/src/test/ui/resolve/auxiliary/issue-21221-3.rs diff --git a/src/test/compile-fail/auxiliary/issue-21221-4.rs b/src/test/ui/resolve/auxiliary/issue-21221-4.rs index fffe060ee24..fffe060ee24 100644 --- a/src/test/compile-fail/auxiliary/issue-21221-4.rs +++ b/src/test/ui/resolve/auxiliary/issue-21221-4.rs diff --git a/src/test/compile-fail/auxiliary/issue_19452_aux.rs b/src/test/ui/resolve/auxiliary/issue_19452_aux.rs index 205566e4b1f..205566e4b1f 100644 --- a/src/test/compile-fail/auxiliary/issue_19452_aux.rs +++ b/src/test/ui/resolve/auxiliary/issue_19452_aux.rs diff --git a/src/test/compile-fail/auxiliary/issue_3907.rs b/src/test/ui/resolve/auxiliary/issue_3907.rs index 6472c08c222..6472c08c222 100644 --- a/src/test/compile-fail/auxiliary/issue_3907.rs +++ b/src/test/ui/resolve/auxiliary/issue_3907.rs diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/ui/resolve/auxiliary/namespaced_enums.rs index 465bddd060d..3bf39b788db 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs +++ b/src/test/ui/resolve/auxiliary/namespaced_enums.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR trait `Nonexist` is not in scope +pub enum Foo { + A, + B(isize), + C { a: isize }, +} -type Typedef = isize; - -fn g<F:Typedef(isize) -> isize>(x: F) {} //~ ERROR `Typedef` is not a trait - -fn main() {} +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} diff --git a/src/test/compile-fail/enums-are-namespaced-xc.rs b/src/test/ui/resolve/enums-are-namespaced-xc.rs index 02939565f69..4f55f33d7f8 100644 --- a/src/test/compile-fail/enums-are-namespaced-xc.rs +++ b/src/test/ui/resolve/enums-are-namespaced-xc.rs @@ -12,8 +12,13 @@ extern crate namespaced_enums; fn main() { - let _ = namespaced_enums::A; //~ ERROR unresolved name - let _ = namespaced_enums::B(10); //~ ERROR unresolved name + let _ = namespaced_enums::A; + //~^ ERROR unresolved value `namespaced_enums::A` + //~| HELP you can import it into scope: `use namespaced_enums::Foo::A;` + let _ = namespaced_enums::B(10); + //~^ ERROR unresolved function `namespaced_enums::B` + //~| HELP you can import it into scope: `use namespaced_enums::Foo::B;` let _ = namespaced_enums::C { a: 10 }; //~^ ERROR unresolved struct, variant or union type `namespaced_enums::C` + //~| HELP you can import it into scope: `use namespaced_enums::Foo::C;` } diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr new file mode 100644 index 00000000000..fda8023b7f6 --- /dev/null +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -0,0 +1,29 @@ +error[E0425]: unresolved value `namespaced_enums::A` + --> $DIR/enums-are-namespaced-xc.rs:15:13 + | +15 | let _ = namespaced_enums::A; + | ^^^^^^^^^^^^^^^^^^^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use namespaced_enums::Foo::A;` + +error[E0425]: unresolved function `namespaced_enums::B` + --> $DIR/enums-are-namespaced-xc.rs:18:13 + | +18 | let _ = namespaced_enums::B(10); + | ^^^^^^^^^^^^^^^^^^^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use namespaced_enums::Foo::B;` + +error[E0422]: unresolved struct, variant or union type `namespaced_enums::C` + --> $DIR/enums-are-namespaced-xc.rs:21:13 + | +21 | let _ = namespaced_enums::C { a: 10 }; + | ^^^^^^^^^^^^^^^^^^^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use namespaced_enums::Foo::C;` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/resolve/issue-14254.rs b/src/test/ui/resolve/issue-14254.rs new file mode 100644 index 00000000000..b1fc6c47720 --- /dev/null +++ b/src/test/ui/resolve/issue-14254.rs @@ -0,0 +1,137 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + fn bar(&self); + fn baz(&self) { } + fn bah(_: Option<&Self>) { } +} + +struct BarTy { + x : isize, + y : f64, +} + +impl BarTy { + fn a() {} + fn b(&self) {} +} + +impl Foo for *const BarTy { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + a; + //~^ ERROR unresolved value `a` + //~| NOTE no resolution found + } +} + +impl<'a> Foo for &'a BarTy { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + x; + //~^ ERROR unresolved value `x` + //~| NOTE did you mean `self.x`? + y; + //~^ ERROR unresolved value `y` + //~| NOTE did you mean `self.y`? + a; + //~^ ERROR unresolved value `a` + //~| NOTE no resolution found + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + b; + //~^ ERROR unresolved value `b` + //~| NOTE no resolution found + } +} + +impl<'a> Foo for &'a mut BarTy { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + x; + //~^ ERROR unresolved value `x` + //~| NOTE did you mean `self.x`? + y; + //~^ ERROR unresolved value `y` + //~| NOTE did you mean `self.y`? + a; + //~^ ERROR unresolved value `a` + //~| NOTE no resolution found + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + b; + //~^ ERROR unresolved value `b` + //~| NOTE no resolution found + } +} + +impl Foo for Box<BarTy> { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + } +} + +impl Foo for *const isize { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + } +} + +impl<'a> Foo for &'a isize { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + } +} + +impl<'a> Foo for &'a mut isize { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + } +} + +impl Foo for Box<isize> { + fn bar(&self) { + baz(); + //~^ ERROR unresolved function `baz` + //~| NOTE did you mean `self.baz(...)`? + bah; + //~^ ERROR unresolved value `bah` + //~| NOTE did you mean `Self::bah`? + } +} diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr new file mode 100644 index 00000000000..2780c1c406f --- /dev/null +++ b/src/test/ui/resolve/issue-14254.stderr @@ -0,0 +1,148 @@ +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:29:9 + | +29 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `a` + --> $DIR/issue-14254.rs:32:9 + | +32 | a; + | ^ no resolution found + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:40:9 + | +40 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `x` + --> $DIR/issue-14254.rs:43:9 + | +43 | x; + | ^ did you mean `self.x`? + +error[E0425]: unresolved value `y` + --> $DIR/issue-14254.rs:46:9 + | +46 | y; + | ^ did you mean `self.y`? + +error[E0425]: unresolved value `a` + --> $DIR/issue-14254.rs:49:9 + | +49 | a; + | ^ no resolution found + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:52:9 + | +52 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved value `b` + --> $DIR/issue-14254.rs:55:9 + | +55 | b; + | ^ no resolution found + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:63:9 + | +63 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `x` + --> $DIR/issue-14254.rs:66:9 + | +66 | x; + | ^ did you mean `self.x`? + +error[E0425]: unresolved value `y` + --> $DIR/issue-14254.rs:69:9 + | +69 | y; + | ^ did you mean `self.y`? + +error[E0425]: unresolved value `a` + --> $DIR/issue-14254.rs:72:9 + | +72 | a; + | ^ no resolution found + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:75:9 + | +75 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved value `b` + --> $DIR/issue-14254.rs:78:9 + | +78 | b; + | ^ no resolution found + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:86:9 + | +86 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:89:9 + | +89 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:97:9 + | +97 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:100:9 + | +100 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:108:9 + | +108 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:111:9 + | +111 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:119:9 + | +119 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:122:9 + | +122 | bah; + | ^^^ did you mean `Self::bah`? + +error[E0425]: unresolved function `baz` + --> $DIR/issue-14254.rs:130:9 + | +130 | baz(); + | ^^^ did you mean `self.baz(...)`? + +error[E0425]: unresolved value `bah` + --> $DIR/issue-14254.rs:133:9 + | +133 | bah; + | ^^^ did you mean `Self::bah`? + +error: main function not found + +error: aborting due to 25 previous errors + diff --git a/src/test/compile-fail/issue-16058.rs b/src/test/ui/resolve/issue-16058.rs index 92c1e4b5f50..1f777e53632 100644 --- a/src/test/compile-fail/issue-16058.rs +++ b/src/test/ui/resolve/issue-16058.rs @@ -16,7 +16,12 @@ pub struct GslResult { impl GslResult { pub fn new() -> GslResult { - Result { //~ ERROR: expected struct, variant or union type, found enum `Result` + Result { +//~^ ERROR expected struct, variant or union type, found enum `Result` +//~| HELP possible better candidates are found in other modules, you can import them into scope +//~| HELP std::fmt::Result +//~| HELP std::io::Result +//~| HELP std::thread::Result val: 0f64, err: 0f64 } diff --git a/src/test/ui/resolve/issue-16058.stderr b/src/test/ui/resolve/issue-16058.stderr new file mode 100644 index 00000000000..6b00cfb8693 --- /dev/null +++ b/src/test/ui/resolve/issue-16058.stderr @@ -0,0 +1,13 @@ +error[E0574]: expected struct, variant or union type, found enum `Result` + --> $DIR/issue-16058.rs:19:9 + | +19 | Result { + | ^^^^^^ not a struct, variant or union type + | + = help: possible better candidates are found in other modules, you can import them into scope: + = help: `use std::fmt::Result;` + = help: `use std::io::Result;` + = help: `use std::thread::Result;` + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-17518.rs b/src/test/ui/resolve/issue-17518.rs index 2113e38c45c..3ac9b379d18 100644 --- a/src/test/compile-fail/issue-17518.rs +++ b/src/test/ui/resolve/issue-17518.rs @@ -14,4 +14,5 @@ enum SomeEnum { fn main() { E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E` + //~^ HELP you can import it into scope: `use SomeEnum::E;` } diff --git a/src/test/ui/resolve/issue-17518.stderr b/src/test/ui/resolve/issue-17518.stderr new file mode 100644 index 00000000000..9de43728b2f --- /dev/null +++ b/src/test/ui/resolve/issue-17518.stderr @@ -0,0 +1,11 @@ +error[E0422]: unresolved struct, variant or union type `E` + --> $DIR/issue-17518.rs:16:5 + | +16 | E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E` + | ^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use SomeEnum::E;` + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-18252.rs b/src/test/ui/resolve/issue-18252.rs index 8e3faca02b7..02c6643a920 100644 --- a/src/test/compile-fail/issue-18252.rs +++ b/src/test/ui/resolve/issue-18252.rs @@ -14,6 +14,5 @@ enum Foo { fn main() { let f = Foo::Variant(42); - //~^ ERROR uses it like a function - //~| struct called like a function + //~^ ERROR expected function, found struct variant `Foo::Variant` } diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr new file mode 100644 index 00000000000..edc7196d846 --- /dev/null +++ b/src/test/ui/resolve/issue-18252.stderr @@ -0,0 +1,8 @@ +error[E0423]: expected function, found struct variant `Foo::Variant` + --> $DIR/issue-18252.rs:16:13 + | +16 | let f = Foo::Variant(42); + | ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`? + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-19452.rs b/src/test/ui/resolve/issue-19452.rs index 34872b7c8c5..080fb064c9f 100644 --- a/src/test/compile-fail/issue-19452.rs +++ b/src/test/ui/resolve/issue-19452.rs @@ -17,10 +17,8 @@ enum Homura { fn main() { let homura = Homura::Madoka; - //~^ ERROR uses it like a function - //~| struct called like a function + //~^ ERROR expected value, found struct variant `Homura::Madoka` let homura = issue_19452_aux::Homura::Madoka; - //~^ ERROR uses it like a function - //~| struct called like a function + //~^ ERROR expected value, found struct variant `issue_19452_aux::Homura::Madoka` } diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr new file mode 100644 index 00000000000..7b14d49af51 --- /dev/null +++ b/src/test/ui/resolve/issue-19452.stderr @@ -0,0 +1,14 @@ +error[E0423]: expected value, found struct variant `Homura::Madoka` + --> $DIR/issue-19452.rs:19:18 + | +19 | let homura = Homura::Madoka; + | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? + +error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` + --> $DIR/issue-19452.rs:22:18 + | +22 | let homura = issue_19452_aux::Homura::Madoka; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/issue-21221-1.rs b/src/test/ui/resolve/issue-21221-1.rs index 2bc9ec3289a..b1266a5af35 100644 --- a/src/test/compile-fail/issue-21221-1.rs +++ b/src/test/ui/resolve/issue-21221-1.rs @@ -51,11 +51,11 @@ struct Foo; // help: `std::ops::Mul` impl Mul for Foo { -//~^ ERROR trait `Mul` is not in scope +//~^ ERROR unresolved trait `Mul` +//~| HELP possible candidates are found in other modules, you can import them into scope //~| HELP `mul1::Mul` //~| HELP `mul2::Mul` //~| HELP `std::ops::Mul` -//~| HELP you can import several candidates into scope (`use ...;`): } // BEFORE, we got: @@ -70,24 +70,23 @@ impl Mul for Foo { // help: `mul4::Mul` // help: and 2 other candidates fn getMul() -> Mul { -//~^ ERROR type name `Mul` is undefined or not in scope +//~^ ERROR unresolved type `Mul` +//~| HELP possible candidates are found in other modules, you can import them into scope //~| HELP `mul1::Mul` //~| HELP `mul2::Mul` //~| HELP `mul3::Mul` //~| HELP `mul4::Mul` //~| HELP and 2 other candidates -//~| HELP you can import several candidates into scope (`use ...;`): } // Let's also test what happens if the trait doesn't exist: impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { -//~^ ERROR trait `ThisTraitReallyDoesntExistInAnyModuleReally` is not in scope -//~| HELP no candidates by the name of `ThisTraitReallyDoesntExistInAnyModuleReally` found +//~^ ERROR unresolved trait `ThisTraitReallyDoesntExistInAnyModuleReally` } // Let's also test what happens if there's just one alternative: impl Div for Foo { -//~^ ERROR trait `Div` is not in scope +//~^ ERROR unresolved trait `Div` //~| HELP `use std::ops::Div;` } diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr new file mode 100644 index 00000000000..17b70d2182e --- /dev/null +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -0,0 +1,41 @@ +error[E0405]: unresolved trait `Mul` + --> $DIR/issue-21221-1.rs:53:6 + | +53 | impl Mul for Foo { + | ^^^ no resolution found + | + = help: possible candidates are found in other modules, you can import them into scope: + = help: `use mul1::Mul;` + = help: `use mul2::Mul;` + = help: `use std::ops::Mul;` + +error[E0412]: unresolved type `Mul` + --> $DIR/issue-21221-1.rs:72:16 + | +72 | fn getMul() -> Mul { + | ^^^ no resolution found + | + = help: possible candidates are found in other modules, you can import them into scope: + = help: `use mul1::Mul;` + = help: `use mul2::Mul;` + = help: `use mul3::Mul;` + = help: `use mul4::Mul;` + = help: and 2 other candidates + +error[E0405]: unresolved trait `ThisTraitReallyDoesntExistInAnyModuleReally` + --> $DIR/issue-21221-1.rs:83:6 + | +83 | impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no resolution found + +error[E0405]: unresolved trait `Div` + --> $DIR/issue-21221-1.rs:88:6 + | +88 | impl Div for Foo { + | ^^^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use std::ops::Div;` + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-21221-2.rs b/src/test/ui/resolve/issue-21221-2.rs index 861acf62d0b..15e859329c4 100644 --- a/src/test/compile-fail/issue-21221-2.rs +++ b/src/test/ui/resolve/issue-21221-2.rs @@ -26,5 +26,5 @@ pub mod baz { struct Foo; impl T for Foo { } -//~^ ERROR trait `T` is not in scope -//~| HELP you can import it into scope: `use foo::bar::T;`. +//~^ ERROR unresolved trait `T` +//~| HELP you can import it into scope: `use foo::bar::T;` diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr new file mode 100644 index 00000000000..342fe12f5e5 --- /dev/null +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -0,0 +1,13 @@ +error[E0405]: unresolved trait `T` + --> $DIR/issue-21221-2.rs:28:6 + | +28 | impl T for Foo { } + | ^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use foo::bar::T;` + +error: main function not found + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-21221-3.rs b/src/test/ui/resolve/issue-21221-3.rs index 05786e69cef..5d62cb85914 100644 --- a/src/test/compile-fail/issue-21221-3.rs +++ b/src/test/ui/resolve/issue-21221-3.rs @@ -23,8 +23,8 @@ struct Foo; // `issue_21221_3::outer::public_module::OuterTrait` // are hidden from the view. impl OuterTrait for Foo {} -//~^ ERROR trait `OuterTrait` is not in scope -//~| HELP you can import it into scope: `use issue_21221_3::outer::OuterTrait;`. +//~^ ERROR unresolved trait `OuterTrait` +//~| HELP you can import it into scope: `use issue_21221_3::outer::OuterTrait;` fn main() { println!("Hello, world!"); } diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr new file mode 100644 index 00000000000..25f57f3e3d1 --- /dev/null +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -0,0 +1,11 @@ +error[E0405]: unresolved trait `OuterTrait` + --> $DIR/issue-21221-3.rs:25:6 + | +25 | impl OuterTrait for Foo {} + | ^^^^^^^^^^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use issue_21221_3::outer::OuterTrait;` + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-21221-4.rs b/src/test/ui/resolve/issue-21221-4.rs index bcbee16cdcf..ff6698f8717 100644 --- a/src/test/compile-fail/issue-21221-4.rs +++ b/src/test/ui/resolve/issue-21221-4.rs @@ -18,8 +18,8 @@ extern crate issue_21221_4; struct Foo; impl T for Foo {} -//~^ ERROR trait `T` is not in scope -//~| HELP you can import it into scope: `use issue_21221_4::T;`. +//~^ ERROR unresolved trait `T` +//~| HELP you can import it into scope: `use issue_21221_4::T;` fn main() { println!("Hello, world!"); diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr new file mode 100644 index 00000000000..7ddbeebb8df --- /dev/null +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -0,0 +1,11 @@ +error[E0405]: unresolved trait `T` + --> $DIR/issue-21221-4.rs:20:6 + | +20 | impl T for Foo {} + | ^ no resolution found + | + = help: possible candidate is found in another module, you can import it into scope: + = help: `use issue_21221_4::T;` + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index 4acb1f70d34..19069f49167 100644 --- a/src/test/compile-fail/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -12,7 +12,11 @@ pub trait ToNbt<T> { fn new(val: T) -> Self; } -impl ToNbt<Self> {} //~ ERROR use of `Self` outside of an impl or trait -//~^ ERROR the trait `ToNbt` cannot be made into an object +impl ToNbt<Self> {} +//~^ ERROR unresolved type `Self` +//~| NOTE `Self` is only available in traits and impls +//~| ERROR the trait `ToNbt` cannot be made into an object +//~| NOTE the trait `ToNbt` cannot be made into an object +//~| NOTE method `new` has no receiver fn main() {} diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr new file mode 100644 index 00000000000..cd0d7d3ce16 --- /dev/null +++ b/src/test/ui/resolve/issue-23305.stderr @@ -0,0 +1,16 @@ +error[E0411]: unresolved type `Self` + --> $DIR/issue-23305.rs:15:12 + | +15 | impl ToNbt<Self> {} + | ^^^^ `Self` is only available in traits and impls + +error[E0038]: the trait `ToNbt` cannot be made into an object + --> $DIR/issue-23305.rs:15:6 + | +15 | impl ToNbt<Self> {} + | ^^^^^^^^^^^ the trait `ToNbt` cannot be made into an object + | + = note: method `new` has no receiver + +error: aborting due to previous error + diff --git a/src/test/ui/resolve/issue-2356.rs b/src/test/ui/resolve/issue-2356.rs new file mode 100644 index 00000000000..6deb598b631 --- /dev/null +++ b/src/test/ui/resolve/issue-2356.rs @@ -0,0 +1,125 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Groom { + fn shave(other: usize); +} + +pub struct cat { + whiskers: isize, +} + +pub enum MaybeDog { + Dog, + NoDog +} + +impl MaybeDog { + fn bark() { + // If this provides a suggestion, it's a bug as MaybeDog doesn't impl Groom + shave(); + //~^ ERROR unresolved function `shave` + //~| NOTE no resolution found + } +} + +impl Clone for cat { + fn clone(&self) -> Self { + clone(); + //~^ ERROR unresolved function `clone` + //~| NOTE did you mean `self.clone(...)`? + loop {} + } +} +impl Default for cat { + fn default() -> Self { + default(); + //~^ ERROR unresolved function `default` + //~| NOTE did you mean `Self::default`? + loop {} + } +} + +impl Groom for cat { + fn shave(other: usize) { + whiskers -= other; + //~^ ERROR unresolved value `whiskers` + //~| ERROR unresolved value `whiskers` + //~| NOTE did you mean `self.whiskers`? + //~| NOTE `self` value is only available in methods with `self` parameter + shave(4); + //~^ ERROR unresolved function `shave` + //~| NOTE did you mean `Self::shave`? + purr(); + //~^ ERROR unresolved function `purr` + //~| NOTE no resolution found + } +} + +impl cat { + fn static_method() {} + + fn purr_louder() { + static_method(); + //~^ ERROR unresolved function `static_method` + //~| NOTE no resolution found + purr(); + //~^ ERROR unresolved function `purr` + //~| NOTE no resolution found + purr(); + //~^ ERROR unresolved function `purr` + //~| NOTE no resolution found + purr(); + //~^ ERROR unresolved function `purr` + //~| NOTE no resolution found + } +} + +impl cat { + fn meow() { + if self.whiskers > 3 { + //~^ ERROR expected value, found module `self` + //~| NOTE `self` value is only available in methods with `self` parameter + println!("MEOW"); + } + } + + fn purr(&self) { + grow_older(); + //~^ ERROR unresolved function `grow_older` + //~| NOTE no resolution found + shave(); + //~^ ERROR unresolved function `shave` + //~| NOTE no resolution found + } + + fn burn_whiskers(&mut self) { + whiskers = 0; + //~^ ERROR unresolved value `whiskers` + //~| NOTE did you mean `self.whiskers`? + } + + pub fn grow_older(other:usize) { + whiskers = 4; + //~^ ERROR unresolved value `whiskers` + //~| ERROR unresolved value `whiskers` + //~| NOTE did you mean `self.whiskers`? + //~| NOTE `self` value is only available in methods with `self` parameter + purr_louder(); + //~^ ERROR unresolved function `purr_louder` + //~| NOTE no resolution found + } +} + +fn main() { + self += 1; + //~^ ERROR expected value, found module `self` + //~| NOTE `self` value is only available in methods with `self` parameter +} diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr new file mode 100644 index 00000000000..32c1a3694d7 --- /dev/null +++ b/src/test/ui/resolve/issue-2356.stderr @@ -0,0 +1,110 @@ +error[E0425]: unresolved function `shave` + --> $DIR/issue-2356.rs:27:5 + | +27 | shave(); + | ^^^^^ no resolution found + +error[E0425]: unresolved function `clone` + --> $DIR/issue-2356.rs:35:5 + | +35 | clone(); + | ^^^^^ did you mean `self.clone(...)`? + +error[E0425]: unresolved function `default` + --> $DIR/issue-2356.rs:43:5 + | +43 | default(); + | ^^^^^^^ did you mean `Self::default`? + +error[E0425]: unresolved value `whiskers` + --> $DIR/issue-2356.rs:52:5 + | +52 | whiskers -= other; + | ^^^^^^^^ + | | + | did you mean `self.whiskers`? + | `self` value is only available in methods with `self` parameter + +error[E0425]: unresolved function `shave` + --> $DIR/issue-2356.rs:57:5 + | +57 | shave(4); + | ^^^^^ did you mean `Self::shave`? + +error[E0425]: unresolved function `purr` + --> $DIR/issue-2356.rs:60:5 + | +60 | purr(); + | ^^^^ no resolution found + +error[E0425]: unresolved function `static_method` + --> $DIR/issue-2356.rs:70:9 + | +70 | static_method(); + | ^^^^^^^^^^^^^ no resolution found + +error[E0425]: unresolved function `purr` + --> $DIR/issue-2356.rs:73:9 + | +73 | purr(); + | ^^^^ no resolution found + +error[E0425]: unresolved function `purr` + --> $DIR/issue-2356.rs:76:9 + | +76 | purr(); + | ^^^^ no resolution found + +error[E0425]: unresolved function `purr` + --> $DIR/issue-2356.rs:79:9 + | +79 | purr(); + | ^^^^ no resolution found + +error[E0424]: expected value, found module `self` + --> $DIR/issue-2356.rs:87:8 + | +87 | if self.whiskers > 3 { + | ^^^^ `self` value is only available in methods with `self` parameter + +error[E0425]: unresolved function `grow_older` + --> $DIR/issue-2356.rs:95:5 + | +95 | grow_older(); + | ^^^^^^^^^^ no resolution found + +error[E0425]: unresolved function `shave` + --> $DIR/issue-2356.rs:98:5 + | +98 | shave(); + | ^^^^^ no resolution found + +error[E0425]: unresolved value `whiskers` + --> $DIR/issue-2356.rs:104:5 + | +104 | whiskers = 0; + | ^^^^^^^^ did you mean `self.whiskers`? + +error[E0425]: unresolved value `whiskers` + --> $DIR/issue-2356.rs:110:5 + | +110 | whiskers = 4; + | ^^^^^^^^ + | | + | did you mean `self.whiskers`? + | `self` value is only available in methods with `self` parameter + +error[E0425]: unresolved function `purr_louder` + --> $DIR/issue-2356.rs:115:5 + | +115 | purr_louder(); + | ^^^^^^^^^^^ no resolution found + +error[E0424]: expected value, found module `self` + --> $DIR/issue-2356.rs:122:5 + | +122 | self += 1; + | ^^^^ `self` value is only available in methods with `self` parameter + +error: aborting due to 17 previous errors + diff --git a/src/test/compile-fail/issue-24968.rs b/src/test/ui/resolve/issue-24968.rs index f51b77b0ee5..0d562cab6b8 100644 --- a/src/test/compile-fail/issue-24968.rs +++ b/src/test/ui/resolve/issue-24968.rs @@ -9,7 +9,8 @@ // except according to those terms. fn foo(_: Self) { - //~^ ERROR use of `Self` outside of an impl or trait +//~^ ERROR unresolved type `Self` +//~| NOTE `Self` is only available in traits and impls } fn main() {} diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr new file mode 100644 index 00000000000..3050bc4eb62 --- /dev/null +++ b/src/test/ui/resolve/issue-24968.stderr @@ -0,0 +1,8 @@ +error[E0411]: unresolved type `Self` + --> $DIR/issue-24968.rs:11:11 + | +11 | fn foo(_: Self) { + | ^^^^ `Self` is only available in traits and impls + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-33876.rs b/src/test/ui/resolve/issue-33876.rs index 87747d2851f..a97cc5e4101 100644 --- a/src/test/compile-fail/issue-33876.rs +++ b/src/test/ui/resolve/issue-33876.rs @@ -17,7 +17,6 @@ trait Bar {} impl Bar for Foo {} fn main() { - let any: &Any = &Bar; //~ ERROR E0425 - //~| HELP trait `Bar` + let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar` if any.is::<u32>() { println!("u32"); } } diff --git a/src/test/ui/resolve/issue-33876.stderr b/src/test/ui/resolve/issue-33876.stderr new file mode 100644 index 00000000000..5dbecc4f0c5 --- /dev/null +++ b/src/test/ui/resolve/issue-33876.stderr @@ -0,0 +1,8 @@ +error[E0423]: expected value, found trait `Bar` + --> $DIR/issue-33876.rs:20:22 + | +20 | let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar` + | ^^^ not a value + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-3907-2.rs b/src/test/ui/resolve/issue-3907-2.rs index 130647966f2..130647966f2 100644 --- a/src/test/compile-fail/issue-3907-2.rs +++ b/src/test/ui/resolve/issue-3907-2.rs diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr new file mode 100644 index 00000000000..ef02250e21c --- /dev/null +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -0,0 +1,10 @@ +error[E0038]: the trait `issue_3907::Foo` cannot be made into an object + --> $DIR/issue-3907-2.rs:20:1 + | +20 | fn bar(_x: Foo) {} + | ^^^^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object + | + = note: method `bar` has no receiver + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-3907.rs b/src/test/ui/resolve/issue-3907.rs index 86906ed9af2..0e54e68df0d 100644 --- a/src/test/compile-fail/issue-3907.rs +++ b/src/test/ui/resolve/issue-3907.rs @@ -17,9 +17,7 @@ struct S { name: isize } -impl Foo for S { //~ ERROR: `Foo` is not a trait - //~| NOTE: expected trait, found type alias - //~| NOTE: type aliases cannot be used for traits +impl Foo for S { //~ ERROR expected trait, found type alias `Foo` fn bar() { } } diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr new file mode 100644 index 00000000000..0a402680aa8 --- /dev/null +++ b/src/test/ui/resolve/issue-3907.stderr @@ -0,0 +1,11 @@ +error[E0404]: expected trait, found type alias `Foo` + --> $DIR/issue-3907.rs:20:6 + | +20 | impl Foo for S { //~ ERROR expected trait, found type alias `Foo` + | ^^^ type aliases cannot be used for traits + | + = help: possible better candidate is found in another module, you can import it into scope: + = help: `use issue_3907::Foo;` + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/ui/resolve/issue-5035-2.rs index 83ff95cc2ea..83ff95cc2ea 100644 --- a/src/test/compile-fail/issue-5035-2.rs +++ b/src/test/ui/resolve/issue-5035-2.rs diff --git a/src/test/ui/resolve/issue-5035-2.stderr b/src/test/ui/resolve/issue-5035-2.stderr new file mode 100644 index 00000000000..72b1578e0d0 --- /dev/null +++ b/src/test/ui/resolve/issue-5035-2.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `I + 'static: std::marker::Sized` is not satisfied + --> $DIR/issue-5035-2.rs:14:8 + | +14 | fn foo(_x: K) {} //~ ERROR: `I + 'static: std::marker::Sized` is not satisfied + | ^^ the trait `std::marker::Sized` is not implemented for `I + 'static` + | + = note: `I + 'static` does not have a constant size known at compile-time + = note: all local variables must have a statically known size + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-5035.rs b/src/test/ui/resolve/issue-5035.rs index 8ebcba47134..6263e6f6db4 100644 --- a/src/test/compile-fail/issue-5035.rs +++ b/src/test/ui/resolve/issue-5035.rs @@ -10,9 +10,8 @@ trait I {} type K = I; -impl K for isize {} //~ ERROR: `K` is not a trait - //~| NOTE: expected trait, found type alias - //~| NOTE: aliases cannot be used for traits +impl K for isize {} //~ ERROR expected trait, found type alias `K` + //~| NOTE type aliases cannot be used for traits use ImportError; //~ ERROR unresolved import `ImportError` [E0432] //~^ no `ImportError` in the root diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr new file mode 100644 index 00000000000..6cb9a289379 --- /dev/null +++ b/src/test/ui/resolve/issue-5035.stderr @@ -0,0 +1,14 @@ +error[E0432]: unresolved import `ImportError` + --> $DIR/issue-5035.rs:16:5 + | +16 | use ImportError; //~ ERROR unresolved import `ImportError` [E0432] + | ^^^^^^^^^^^ no `ImportError` in the root + +error[E0404]: expected trait, found type alias `K` + --> $DIR/issue-5035.rs:13:6 + | +13 | impl K for isize {} //~ ERROR expected trait, found type alias `K` + | ^ type aliases cannot be used for traits + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/issue-6702.rs b/src/test/ui/resolve/issue-6702.rs index 66ed817ffa8..b391ddf3469 100644 --- a/src/test/compile-fail/issue-6702.rs +++ b/src/test/ui/resolve/issue-6702.rs @@ -14,6 +14,6 @@ struct Monster { fn main() { - let _m = Monster(); //~ ERROR `Monster` is the name of a struct or - //~^ HELP did you mean to write: `Monster { /* fields */ }`? + let _m = Monster(); //~ ERROR expected function, found struct `Monster` + //~^ NOTE did you mean `Monster { /* fields */ }`? } diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr new file mode 100644 index 00000000000..b50295752f2 --- /dev/null +++ b/src/test/ui/resolve/issue-6702.stderr @@ -0,0 +1,8 @@ +error[E0423]: expected function, found struct `Monster` + --> $DIR/issue-6702.rs:17:14 + | +17 | let _m = Monster(); //~ ERROR expected function, found struct `Monster` + | ^^^^^^^ did you mean `Monster { /* fields */ }`? + +error: aborting due to previous error + diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.rs b/src/test/ui/resolve/resolve-assoc-suggestions.rs new file mode 100644 index 00000000000..53e26ddafec --- /dev/null +++ b/src/test/ui/resolve/resolve-assoc-suggestions.rs @@ -0,0 +1,58 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure associated items are recommended only in appropriate contexts. + +struct S { + field: u8, +} + +trait Tr { + fn method(&self); + type Type; +} + +impl Tr for S { + type Type = u8; + + fn method(&self) { + let _: field; + //~^ ERROR unresolved type `field` + //~| NOTE no resolution found + let field(..); + //~^ ERROR unresolved tuple struct/variant `field` + //~| NOTE no resolution found + field; + //~^ ERROR unresolved value `field` + //~| NOTE did you mean `self.field`? + + let _: Type; + //~^ ERROR unresolved type `Type` + //~| NOTE did you mean `Self::Type`? + let Type(..); + //~^ ERROR unresolved tuple struct/variant `Type` + //~| NOTE no resolution found + Type; + //~^ ERROR unresolved value `Type` + //~| NOTE no resolution found + + let _: method; + //~^ ERROR unresolved type `method` + //~| NOTE no resolution found + let method(..); + //~^ ERROR unresolved tuple struct/variant `method` + //~| NOTE no resolution found + method; + //~^ ERROR unresolved value `method` + //~| NOTE did you mean `self.method(...)`? + } +} + +fn main() {} diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.stderr b/src/test/ui/resolve/resolve-assoc-suggestions.stderr new file mode 100644 index 00000000000..98ead713947 --- /dev/null +++ b/src/test/ui/resolve/resolve-assoc-suggestions.stderr @@ -0,0 +1,56 @@ +error[E0412]: unresolved type `field` + --> $DIR/resolve-assoc-suggestions.rs:26:16 + | +26 | let _: field; + | ^^^^^ no resolution found + +error[E0531]: unresolved tuple struct/variant `field` + --> $DIR/resolve-assoc-suggestions.rs:29:13 + | +29 | let field(..); + | ^^^^^ no resolution found + +error[E0425]: unresolved value `field` + --> $DIR/resolve-assoc-suggestions.rs:32:9 + | +32 | field; + | ^^^^^ did you mean `self.field`? + +error[E0412]: unresolved type `Type` + --> $DIR/resolve-assoc-suggestions.rs:36:16 + | +36 | let _: Type; + | ^^^^ did you mean `Self::Type`? + +error[E0531]: unresolved tuple struct/variant `Type` + --> $DIR/resolve-assoc-suggestions.rs:39:13 + | +39 | let Type(..); + | ^^^^ no resolution found + +error[E0425]: unresolved value `Type` + --> $DIR/resolve-assoc-suggestions.rs:42:9 + | +42 | Type; + | ^^^^ no resolution found + +error[E0412]: unresolved type `method` + --> $DIR/resolve-assoc-suggestions.rs:46:16 + | +46 | let _: method; + | ^^^^^^ no resolution found + +error[E0531]: unresolved tuple struct/variant `method` + --> $DIR/resolve-assoc-suggestions.rs:49:13 + | +49 | let method(..); + | ^^^^^^ no resolution found + +error[E0425]: unresolved value `method` + --> $DIR/resolve-assoc-suggestions.rs:52:9 + | +52 | method; + | ^^^^^^ did you mean `self.method(...)`? + +error: aborting due to 9 previous errors + diff --git a/src/test/compile-fail/resolve-hint-macro.rs b/src/test/ui/resolve/resolve-hint-macro.rs index edaab012757..72fd9a79376 100644 --- a/src/test/compile-fail/resolve-hint-macro.rs +++ b/src/test/ui/resolve/resolve-hint-macro.rs @@ -10,6 +10,6 @@ fn main() { assert(true); - //~^ ERROR unresolved name `assert` - //~| NOTE did you mean the macro `assert!`? + //~^ ERROR expected function, found macro `assert` + //~| NOTE did you mean `assert!(...)`? } diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr new file mode 100644 index 00000000000..ffb3f848430 --- /dev/null +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -0,0 +1,8 @@ +error[E0423]: expected function, found macro `assert` + --> $DIR/resolve-hint-macro.rs:12:5 + | +12 | assert(true); + | ^^^^^^ did you mean `assert!(...)`? + +error: aborting due to previous error + diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.rs b/src/test/ui/resolve/resolve-speculative-adjustment.rs new file mode 100644 index 00000000000..95289e23f9e --- /dev/null +++ b/src/test/ui/resolve/resolve-speculative-adjustment.rs @@ -0,0 +1,44 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure speculative path resolution works properly when resolution +// adjustment happens and no extra errors is reported. + +struct S { + field: u8, +} + +trait Tr { + fn method(&self); +} + +impl Tr for S { + fn method(&self) { + fn g() { + // Speculative resolution of `Self` and `self` silently fails, + // "did you mean" messages are not printed. + field; + //~^ ERROR unresolved value `field` + //~| NOTE no resolution found + method(); + //~^ ERROR unresolved function `method` + //~| NOTE no resolution found + } + + field; + //~^ ERROR unresolved value `field` + //~| NOTE did you mean `self.field`? + method(); + //~^ ERROR unresolved function `method` + //~| NOTE did you mean `self.method(...)`? + } +} + +fn main() {} diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.stderr b/src/test/ui/resolve/resolve-speculative-adjustment.stderr new file mode 100644 index 00000000000..173b6905541 --- /dev/null +++ b/src/test/ui/resolve/resolve-speculative-adjustment.stderr @@ -0,0 +1,26 @@ +error[E0425]: unresolved value `field` + --> $DIR/resolve-speculative-adjustment.rs:27:13 + | +27 | field; + | ^^^^^ no resolution found + +error[E0425]: unresolved function `method` + --> $DIR/resolve-speculative-adjustment.rs:30:13 + | +30 | method(); + | ^^^^^^ no resolution found + +error[E0425]: unresolved value `field` + --> $DIR/resolve-speculative-adjustment.rs:35:9 + | +35 | field; + | ^^^^^ did you mean `self.field`? + +error[E0425]: unresolved function `method` + --> $DIR/resolve-speculative-adjustment.rs:38:9 + | +38 | method(); + | ^^^^^^ did you mean `self.method(...)`? + +error: aborting due to 4 previous errors + diff --git a/src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs index 4a816ea7572..789bdfb414d 100644 --- a/src/test/compile-fail/suggest-path-instead-of-mod-dot-item.rs +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs @@ -25,52 +25,52 @@ pub mod a { fn h1() -> i32 { a.I - //~^ ERROR E0425 - //~| HELP to reference an item from the `a` module, use `a::I` + //~^ ERROR expected value, found module `a` + //~| NOTE did you mean `a::I`? } fn h2() -> i32 { a.g() - //~^ ERROR E0425 - //~| HELP to call a function from the `a` module, use `a::g(..)` + //~^ ERROR expected value, found module `a` + //~| NOTE did you mean `a::g(...)`? } fn h3() -> i32 { a.b.J - //~^ ERROR E0425 - //~| HELP to reference an item from the `a` module, use `a::b` + //~^ ERROR expected value, found module `a` + //~| NOTE did you mean `a::b`? } fn h4() -> i32 { a::b.J - //~^ ERROR E0425 - //~| HELP to reference an item from the `a::b` module, use `a::b::J` + //~^ ERROR expected value, found module `a::b` + //~| NOTE did you mean `a::b::J`? } fn h5() { a.b.f(); - //~^ ERROR E0425 - //~| HELP to reference an item from the `a` module, use `a::b` + //~^ ERROR expected value, found module `a` + //~| NOTE did you mean `a::b`? let v = Vec::new(); v.push(a::b); - //~^ ERROR E0425 - //~| HELP module `a::b` cannot be used as an expression + //~^ ERROR expected value, found module `a::b` + //~| NOTE not a value } fn h6() -> i32 { a::b.f() - //~^ ERROR E0425 - //~| HELP to call a function from the `a::b` module, use `a::b::f(..)` + //~^ ERROR expected value, found module `a::b` + //~| NOTE did you mean `a::b::f(...)`? } fn h7() { a::b - //~^ ERROR E0425 - //~| HELP module `a::b` cannot be used as an expression + //~^ ERROR expected value, found module `a::b` + //~| NOTE not a value } fn h8() -> i32 { a::b() - //~^ ERROR E0425 - //~| HELP module `a::b` cannot be used as an expression + //~^ ERROR expected function, found module `a::b` + //~| NOTE not a function } diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr new file mode 100644 index 00000000000..8ace738ad6d --- /dev/null +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -0,0 +1,58 @@ +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5 + | +27 | a.I + | ^ did you mean `a::I`? + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:33:5 + | +33 | a.g() + | ^ did you mean `a::g(...)`? + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:39:5 + | +39 | a.b.J + | ^ did you mean `a::b`? + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5 + | +45 | a::b.J + | ^^^^ did you mean `a::b::J`? + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:51:5 + | +51 | a.b.f(); + | ^ did you mean `a::b`? + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:12 + | +55 | v.push(a::b); + | ^^^^ not a value + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:61:5 + | +61 | a::b.f() + | ^^^^ did you mean `a::b::f(...)`? + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:67:5 + | +67 | a::b + | ^^^^ not a value + +error[E0423]: expected function, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:73:5 + | +73 | a::b() + | ^^^^ not a function + +error: main function not found + +error: aborting due to 10 previous errors + diff --git a/src/test/compile-fail/token-error-correct-2.rs b/src/test/ui/resolve/token-error-correct-2.rs index 151c1d432ed..6fa1260d180 100644 --- a/src/test/compile-fail/token-error-correct-2.rs +++ b/src/test/ui/resolve/token-error-correct-2.rs @@ -11,8 +11,9 @@ // Test that we do some basic error correcton in the tokeniser (and don't ICE). fn main() { - if foo { //~ NOTE: unclosed delimiter - //~^ ERROR: unresolved name `foo` - //~| NOTE unresolved name + if foo { + //~^ NOTE: unclosed delimiter + //~| ERROR: unresolved value `foo` + //~| NOTE: no resolution found ) //~ ERROR: incorrect close delimiter: `)` } diff --git a/src/test/ui/resolve/token-error-correct-2.stderr b/src/test/ui/resolve/token-error-correct-2.stderr new file mode 100644 index 00000000000..7c422398e21 --- /dev/null +++ b/src/test/ui/resolve/token-error-correct-2.stderr @@ -0,0 +1,20 @@ +error: incorrect close delimiter: `)` + --> $DIR/token-error-correct-2.rs:18:5 + | +18 | ) //~ ERROR: incorrect close delimiter: `)` + | ^ + | +note: unclosed delimiter + --> $DIR/token-error-correct-2.rs:14:12 + | +14 | if foo { + | ^ + +error[E0425]: unresolved value `foo` + --> $DIR/token-error-correct-2.rs:14:8 + | +14 | if foo { + | ^^^ no resolution found + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/token-error-correct-3.rs b/src/test/ui/resolve/token-error-correct-3.rs index 5f21bf18d7b..f72b7adf593 100644 --- a/src/test/compile-fail/token-error-correct-3.rs +++ b/src/test/ui/resolve/token-error-correct-3.rs @@ -18,8 +18,8 @@ pub mod raw { pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> { - if !is_directory(path.as_ref()) { //~ ERROR: unresolved name `is_directory` - //~| NOTE unresolved name + if !is_directory(path.as_ref()) { //~ ERROR: unresolved function `is_directory` + //~^ NOTE: no resolution found callback(path.as_ref(); //~ NOTE: unclosed delimiter //~^ ERROR: expected one of fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr new file mode 100644 index 00000000000..0b15c23909c --- /dev/null +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -0,0 +1,45 @@ +error: incorrect close delimiter: `}` + --> $DIR/token-error-correct-3.rs:29:9 + | +29 | } else { //~ ERROR: incorrect close delimiter: `}` + | ^ + | +note: unclosed delimiter + --> $DIR/token-error-correct-3.rs:23:21 + | +23 | callback(path.as_ref(); //~ NOTE: unclosed delimiter + | ^ + +error: expected one of `,`, `.`, `?`, or an operator, found `;` + --> $DIR/token-error-correct-3.rs:23:35 + | +23 | callback(path.as_ref(); //~ NOTE: unclosed delimiter + | ^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` + --> $DIR/token-error-correct-3.rs:29:9 + | +29 | } else { //~ ERROR: incorrect close delimiter: `}` + | ^ + +error[E0425]: unresolved function `is_directory` + --> $DIR/token-error-correct-3.rs:21:13 + | +21 | if !is_directory(path.as_ref()) { //~ ERROR: unresolved function `is_directory` + | ^^^^^^^^^^^^ no resolution found + +error[E0308]: mismatched types + --> $DIR/token-error-correct-3.rs:25:13 + | +25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result` + | + = note: expected type `()` + = note: found type `std::result::Result<bool, std::io::Error>` + = help: here are some functions which might fulfill your needs: + - .unwrap() + - .unwrap_err() + - .unwrap_or_default() + +error: aborting due to previous error + diff --git a/src/test/compile-fail/token-error-correct.rs b/src/test/ui/resolve/token-error-correct.rs index 3ba9edda07f..5fd35e51336 100644 --- a/src/test/compile-fail/token-error-correct.rs +++ b/src/test/ui/resolve/token-error-correct.rs @@ -11,14 +11,16 @@ // Test that we do some basic error correcton in the tokeniser. fn main() { - foo(bar(; //~ NOTE: unclosed delimiter + foo(bar(; //~^ NOTE: unclosed delimiter - //~^^ ERROR: expected expression, found `;` - //~^^^ ERROR: unresolved name `bar` - //~^^^^ ERROR: unresolved name `foo` - //~^^^^^ ERROR: expected one of `)`, `,`, `.`, `<`, `?` - //~| NOTE unresolved name - //~| NOTE unresolved name -} //~ ERROR: incorrect close delimiter: `}` + //~| NOTE: unclosed delimiter + //~| ERROR: expected expression, found `;` + //~| ERROR: unresolved function `foo` + //~| NOTE: no resolution found + //~| ERROR: unresolved function `bar` + //~| NOTE: no resolution found + //~| ERROR: expected one of `)`, `,`, `.`, `<`, `?` +} //~^ ERROR: incorrect close delimiter: `}` -//~^^ ERROR: expected expression, found `)` +//~| ERROR: incorrect close delimiter: `}` +//~| ERROR: expected expression, found `)` diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr new file mode 100644 index 00000000000..38cd95a4867 --- /dev/null +++ b/src/test/ui/resolve/token-error-correct.stderr @@ -0,0 +1,56 @@ +error: incorrect close delimiter: `}` + --> $DIR/token-error-correct.rs:23:1 + | +23 | } + | ^ + | +note: unclosed delimiter + --> $DIR/token-error-correct.rs:14:12 + | +14 | foo(bar(; + | ^ + +error: incorrect close delimiter: `}` + --> $DIR/token-error-correct.rs:23:1 + | +23 | } + | ^ + | +note: unclosed delimiter + --> $DIR/token-error-correct.rs:14:8 + | +14 | foo(bar(; + | ^ + +error: expected expression, found `;` + --> $DIR/token-error-correct.rs:14:13 + | +14 | foo(bar(; + | ^ + +error: expected one of `)`, `,`, `.`, `<`, `?`, `break`, `continue`, `false`, `for`, `if`, `loop`, `match`, `move`, `return`, `true`, `unsafe`, `while`, or an operator, found `;` + --> $DIR/token-error-correct.rs:14:13 + | +14 | foo(bar(; + | ^ + +error: expected expression, found `)` + --> $DIR/token-error-correct.rs:23:1 + | +23 | } + | ^ + +error[E0425]: unresolved function `foo` + --> $DIR/token-error-correct.rs:14:5 + | +14 | foo(bar(; + | ^^^ no resolution found + +error[E0425]: unresolved function `bar` + --> $DIR/token-error-correct.rs:14:9 + | +14 | foo(bar(; + | ^^^ no resolution found + +error: aborting due to 7 previous errors + diff --git a/src/test/compile-fail/E0248.rs b/src/test/ui/resolve/tuple-struct-alias.rs index 25568a323e1..c9c05202fea 100644 --- a/src/test/compile-fail/E0248.rs +++ b/src/test/ui/resolve/tuple-struct-alias.rs @@ -8,11 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum Foo { - Bar(u32), +struct S(u8, u16); +type A = S; + +impl S { + fn f() { + let s = Self(0, 1); + match s { + Self(..) => {} + } + } } -fn do_something(x: Foo::Bar) { } //~ ERROR E0248 - //~| NOTE value used as a type fn main() { + let s = A(0, 1); + match s { + A(..) => {} + } } diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr new file mode 100644 index 00000000000..485c8ebbaeb --- /dev/null +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -0,0 +1,26 @@ +error[E0423]: expected function, found self type `Self` + --> $DIR/tuple-struct-alias.rs:16:17 + | +16 | let s = Self(0, 1); + | ^^^^ did you mean `Self { /* fields */ }`? + +error[E0532]: expected tuple struct/variant, found self type `Self` + --> $DIR/tuple-struct-alias.rs:18:13 + | +18 | Self(..) => {} + | ^^^^ did you mean `Self { /* fields */ }`? + +error[E0423]: expected function, found type alias `A` + --> $DIR/tuple-struct-alias.rs:24:13 + | +24 | let s = A(0, 1); + | ^ did you mean `A { /* fields */ }`? + +error[E0532]: expected tuple struct/variant, found type alias `A` + --> $DIR/tuple-struct-alias.rs:26:9 + | +26 | A(..) => {} + | ^ did you mean `A { /* fields */ }`? + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs new file mode 100644 index 00000000000..57f6ddd2d3c --- /dev/null +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs @@ -0,0 +1,21 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn f<F:Nonexist(isize) -> isize>(x: F) {} +//~^ ERROR unresolved trait `Nonexist` +//~| NOTE no resolution found + +type Typedef = isize; + +fn g<F:Typedef(isize) -> isize>(x: F) {} +//~^ ERROR expected trait, found type alias `Typedef` +//~| NOTE type aliases cannot be used for traits + +fn main() {} diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr new file mode 100644 index 00000000000..ba90321ca2b --- /dev/null +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -0,0 +1,14 @@ +error[E0405]: unresolved trait `Nonexist` + --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:11:8 + | +11 | fn f<F:Nonexist(isize) -> isize>(x: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ no resolution found + +error[E0404]: expected trait, found type alias `Typedef` + --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:17:8 + | +17 | fn g<F:Typedef(isize) -> isize>(x: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used for traits + +error: cannot continue compilation due to previous error + diff --git a/src/test/compile-fail/unresolved_static_type_field.rs b/src/test/ui/resolve/unresolved_static_type_field.rs index 80f6108f02d..19beabd8823 100644 --- a/src/test/compile-fail/unresolved_static_type_field.rs +++ b/src/test/ui/resolve/unresolved_static_type_field.rs @@ -16,8 +16,11 @@ struct Foo { impl Foo { fn bar() { - f(cx); //~ ERROR E0425 - //~| HELP this is an associated function + f(cx); + //~^ ERROR unresolved value `cx` + //~| ERROR unresolved value `cx` + //~| NOTE did you mean `self.cx`? + //~| NOTE `self` value is only available in methods with `self` parameter } } diff --git a/src/test/ui/resolve/unresolved_static_type_field.stderr b/src/test/ui/resolve/unresolved_static_type_field.stderr new file mode 100644 index 00000000000..1d0ee191175 --- /dev/null +++ b/src/test/ui/resolve/unresolved_static_type_field.stderr @@ -0,0 +1,11 @@ +error[E0425]: unresolved value `cx` + --> $DIR/unresolved_static_type_field.rs:19:11 + | +19 | f(cx); + | ^^ + | | + | did you mean `self.cx`? + | `self` value is only available in methods with `self` parameter + +error: aborting due to previous error + diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr index 815893e0c82..717f5ee200c 100644 --- a/src/test/ui/span/impl-wrong-item-for-trait.stderr +++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr @@ -1,3 +1,9 @@ +error[E0437]: type `bar` is not a member of trait `Foo` + --> $DIR/impl-wrong-item-for-trait.rs:47:5 + | +47 | type bar = u64; + | ^^^^^^^^^^^^^^^ not a member of trait `Foo` + error[E0323]: item `bar` is an associated const, which doesn't match its trait `Foo` --> $DIR/impl-wrong-item-for-trait.rs:25:5 | diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 2370b3d6c61..764f34cabde 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -1,10 +1,11 @@ -error[E0404]: `Add` is not a trait +error[E0404]: expected trait, found type parameter `Add` --> $DIR/issue-35987.rs:15:21 | 15 | impl<T: Clone, Add> Add for Foo<T> { - | --- ^^^ expected trait, found type parameter - | | - | type parameter defined here + | ^^^ not a trait + | + = help: possible better candidate is found in another module, you can import it into scope: + = help: `use std::ops::Add;` error: main function not found diff --git a/src/test/ui/span/typo-suggestion.stderr b/src/test/ui/span/typo-suggestion.stderr index 5446175aa25..117c38e1db9 100644 --- a/src/test/ui/span/typo-suggestion.stderr +++ b/src/test/ui/span/typo-suggestion.stderr @@ -1,10 +1,10 @@ -error[E0425]: unresolved name `bar` +error[E0425]: unresolved value `bar` --> $DIR/typo-suggestion.rs:15:26 | 15 | println!("Hello {}", bar); - | ^^^ unresolved name + | ^^^ no resolution found -error[E0425]: unresolved name `fob` +error[E0425]: unresolved value `fob` --> $DIR/typo-suggestion.rs:18:26 | 18 | println!("Hello {}", fob); |
