From 91b9dabdebb95b689d335b98a8890923d9af7f7e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 3 Jun 2016 23:15:00 +0300 Subject: [PATCH] resolve: Rewrite resolve_pattern --- src/librustc/hir/def.rs | 12 +- src/librustc_resolve/diagnostics.rs | 37 +- src/librustc_resolve/lib.rs | 681 +++++++----------- .../associated-const-private-impl.rs | 2 +- .../compile-fail/blind-item-block-middle.rs | 2 +- .../compile-fail/const-pattern-irrefutable.rs | 12 +- .../compile-fail/empty-struct-braces-pat-2.rs | 4 +- src/test/compile-fail/enum-in-scope.rs | 2 +- .../compile-fail/enums-pats-not-idents.rs | 5 +- src/test/compile-fail/issue-10200.rs | 2 +- src/test/compile-fail/issue-12863.rs | 2 +- src/test/compile-fail/issue-16149.rs | 2 +- src/test/compile-fail/issue-17405.rs | 3 +- .../compile-fail/issue-17718-const-privacy.rs | 4 +- src/test/compile-fail/issue-17718-patterns.rs | 4 +- src/test/compile-fail/issue-17933.rs | 2 +- src/test/compile-fail/issue-23716.rs | 12 +- src/test/compile-fail/issue-26459.rs | 3 +- src/test/compile-fail/issue-27033.rs | 4 +- src/test/compile-fail/issue-27815.rs | 6 +- src/test/compile-fail/issue-28992-empty.rs | 2 +- src/test/compile-fail/issue-5927.rs | 2 +- .../method-resolvable-path-in-pattern.rs | 2 +- src/test/compile-fail/name-clash-nullary.rs | 5 +- .../pat-shadow-in-nested-binding.rs | 2 +- .../compile-fail/qualified-path-params.rs | 2 +- src/test/compile-fail/static-mut-not-pat.rs | 4 +- .../compile-fail/trait-impl-for-module.rs | 2 +- 28 files changed, 339 insertions(+), 483 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index a056ba588b807..3b2d5ba449381 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -88,6 +88,14 @@ impl PathResolution { depth: depth, } } + + pub fn kind_name(&self) -> &'static str { + if self.depth != 0 { + "associated item" + } else { + self.base_def.kind_name() + } + } } // Definition mapping @@ -161,8 +169,8 @@ impl Def { Def::Struct(..) => "struct", Def::Trait(..) => "trait", Def::Method(..) => "method", - Def::Const(..) => "const", - Def::AssociatedConst(..) => "associated const", + Def::Const(..) => "constant", + Def::AssociatedConst(..) => "associated constant", Def::TyParam(..) => "type parameter", Def::PrimTy(..) => "builtin type", Def::Local(..) => "local variable", diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 97b57f231b907..d3e2dd2a917e5 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -842,32 +842,6 @@ match 0 { ``` "##, -E0419: r##" -An unknown enum variant, struct or const was used. Example of erroneous code: - -```compile_fail -match 0 { - Something::Foo => {} // error: unresolved enum variant, struct - // or const `Foo` -} -``` - -Please verify you didn't misspell it and the enum variant, struct or const has -been declared and imported into scope. Example: - -``` -enum Something { - Foo, - NotFoo, -} - -match Something::NotFoo { - Something::Foo => {} // ok! - _ => {} -} -``` -"##, - E0422: r##" You are trying to use an identifier that is either undefined or not a struct. For instance: @@ -1247,16 +1221,11 @@ impl Foo for i32 {} } register_diagnostics! { -// E0153, unused error code -// E0157, unused error code E0254, // import conflicts with imported crate in this module -// E0257, -// E0258, E0402, // cannot use an outer type parameter in this context E0406, // undeclared associated type -// E0410, merged into 408 - E0418, // is not an enum variant, struct or const - E0420, // is not an associated const - E0421, // unresolved associated const + E0418, // X bindings cannot shadow Ys + E0419, // unresolved pattern path kind `name` + E0420, // expected pattern path kind, found another pattern path kind E0427, // cannot use `ref` binding mode with ... } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0fab12c230c0f..86868fc085bf7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -31,7 +31,6 @@ extern crate arena; #[macro_use] extern crate rustc; -use self::PatternBindingMode::*; use self::Namespace::*; use self::ResolveResult::*; use self::FallbackSuggestion::*; @@ -40,7 +39,6 @@ use self::RibKind::*; use self::UseLexicalScopeFlag::*; use self::ModulePrefixResult::*; use self::AssocItemResolveResult::*; -use self::BareIdentifierPatternResolution::*; use self::ParentLink::*; use rustc::hir::map::Definitions; @@ -66,8 +64,8 @@ use syntax::visit::{self, FnKind, Visitor}; use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind}; use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics}; use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind}; -use syntax::ast::{Local, Pat, PatKind, Path}; -use syntax::ast::{PathSegment, PathParameters, TraitItemKind, TraitRef, Ty, TyKind}; +use syntax::ast::{Local, Mutability, Pat, PatKind, Path}; +use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind}; use std::collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; @@ -123,24 +121,10 @@ enum ResolutionError<'a> { SelfUsedOutsideImplOrTrait, /// error E0412: use of undeclared UseOfUndeclared(&'a str, &'a str, SuggestedCandidates), - /// error E0413: cannot be named the same as an enum variant or unit-like struct in scope - DeclarationShadowsEnumVariantOrUnitLikeStruct(Name), - /// error E0414: only irrefutable patterns allowed here - ConstantForIrrefutableBinding(Name, &'a NameBinding<'a>), /// 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 E0417: static variables cannot be referenced in a pattern - StaticVariableReference(&'a NameBinding<'a>), - /// error E0418: is not an enum variant, struct or const - NotAnEnumVariantStructOrConst(&'a str), - /// error E0419: unresolved enum variant, struct or const - UnresolvedEnumVariantStructOrConst(&'a str), - /// error E0420: is not an associated const - NotAnAssociatedConst(&'a str), - /// error E0421: unresolved associated const - UnresolvedAssociatedConst(&'a str), /// error E0422: does not name a struct DoesNotNameAStruct(&'a str), /// error E0423: is a struct variant name, but this expression uses it like a function name @@ -158,8 +142,6 @@ enum ResolutionError<'a> { }, /// error E0426: use of undeclared label UndeclaredLabel(&'a str), - /// error E0427: cannot use `ref` binding mode with ... - CannotUseRefBindingModeWith(&'a str), /// error E0429: `self` imports are only allowed within a { } list SelfImportsOnlyAllowedWithin, /// error E0430: `self` import can only appear once in the list @@ -174,6 +156,12 @@ enum ResolutionError<'a> { CannotCaptureDynamicEnvironmentInFnItem, /// error E0435: attempt to use a non-constant value in a constant AttemptToUseNonConstantValueInConstant, + /// error E0418: X bindings cannot shadow Ys + BindingShadowsSomethingUnacceptable(&'a str, &'a str, Name), + /// error E0419: unresolved pattern path kind `name` + PatPathUnresolved(&'a str, &'a Path), + /// error E0420: expected pattern path kind, found another pattern path kind + PatPathUnexpected(&'a str, &'a str, &'a Path), } /// Context of where `ResolutionError::UnresolvedName` arose. @@ -306,28 +294,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, err.span_label(span, &format!("undefined or not in scope")); err } - ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => { - let mut err = struct_span_err!(resolver.session, - span, - E0413, - "`{}` cannot be named the same as an enum variant \ - or unit-like struct in scope", - name); - err.span_label(span, - &format!("has same name as enum variant or unit-like struct")); - err - } - ResolutionError::ConstantForIrrefutableBinding(name, binding) => { - let mut err = struct_span_err!(resolver.session, - span, - E0414, - "let variables cannot be named the same as const variables"); - err.span_label(span, - &format!("cannot be named the same as a const variable")); - let participle = if binding.is_import() { "imported" } else { "defined" }; - err.span_label(binding.span, &format!("a constant `{}` is {} here", name, participle)); - err - } ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { let mut err = struct_span_err!(resolver.session, span, @@ -346,47 +312,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::StaticVariableReference(binding) => { - let mut err = struct_span_err!(resolver.session, - span, - E0417, - "static variables cannot be referenced in a \ - pattern, use a `const` instead"); - err.span_label(span, &format!("static variable used in pattern")); - if binding.span != codemap::DUMMY_SP { - let participle = if binding.is_import() { "imported" } else { "defined" }; - err.span_label(binding.span, &format!("static variable {} here", participle)); - } - err - } - ResolutionError::NotAnEnumVariantStructOrConst(name) => { - struct_span_err!(resolver.session, - span, - E0418, - "`{}` is not an enum variant, struct or const", - name) - } - ResolutionError::UnresolvedEnumVariantStructOrConst(name) => { - struct_span_err!(resolver.session, - span, - E0419, - "unresolved enum variant, struct or const `{}`", - name) - } - ResolutionError::NotAnAssociatedConst(name) => { - struct_span_err!(resolver.session, - span, - E0420, - "`{}` is not an associated const", - name) - } - ResolutionError::UnresolvedAssociatedConst(name) => { - struct_span_err!(resolver.session, - span, - E0421, - "unresolved associated const `{}`", - name) - } ResolutionError::DoesNotNameAStruct(name) => { struct_span_err!(resolver.session, span, @@ -455,13 +380,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, "use of undeclared label `{}`", name) } - ResolutionError::CannotUseRefBindingModeWith(descr) => { - struct_span_err!(resolver.session, - span, - E0427, - "cannot use `ref` binding mode with {}", - descr) - } ResolutionError::SelfImportsOnlyAllowedWithin => { struct_span_err!(resolver.session, span, @@ -506,6 +424,37 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, E0435, "attempt to use a non-constant value in a constant") } + ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => { + let mut err = struct_span_err!(resolver.session, + span, + E0418, + "{}s cannot shadow {}s", what_binding, shadows_what); + err.span_label(span, &format!("cannot be named the same as a {}", shadows_what)); + if let Some(binding) = resolver.current_module + .resolve_name_in_lexical_scope(name, ValueNS) { + let participle = if binding.is_import() { "imported" } else { "defined" }; + err.span_label(binding.span, &format!("a {} `{}` is {} here", + shadows_what, name, participle)); + } + err + } + ResolutionError::PatPathUnresolved(expected_what, path) => { + struct_span_err!(resolver.session, + span, + E0419, + "unresolved {} `{}`", + expected_what, + path.segments.last().unwrap().identifier) + } + ResolutionError::PatPathUnexpected(expected_what, found_what, path) => { + struct_span_err!(resolver.session, + span, + E0420, + "expected {}, found {} `{}`", + expected_what, + found_what, + path.segments.last().unwrap().identifier) + } } } @@ -518,11 +467,33 @@ struct BindingInfo { // Map from the name in a pattern to its binding mode. type BindingMap = HashMap; -#[derive(Copy, Clone, PartialEq)] -enum PatternBindingMode { - RefutableMode, - LocalIrrefutableMode, - ArgumentIrrefutableMode, +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum PatternSource { + Match, + IfLet, + WhileLet, + Let, + For, + FnParam, +} + +impl PatternSource { + fn is_refutable(self) -> bool { + match self { + PatternSource::Match | PatternSource::IfLet | PatternSource::WhileLet => true, + PatternSource::Let | PatternSource::For | PatternSource::FnParam => false, + } + } + fn descr(self) -> &'static str { + match self { + PatternSource::Match => "match binding", + PatternSource::IfLet => "if let binding", + PatternSource::WhileLet => "while let binding", + PatternSource::Let => "let binding", + PatternSource::For => "for binding", + PatternSource::FnParam => "function parameter", + } + } } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -709,13 +680,6 @@ enum AssocItemResolveResult { ResolveAttempt(Option), } -#[derive(Copy, Clone)] -enum BareIdentifierPatternResolution<'a> { - FoundStructOrEnumVariant(Def), - FoundConst(&'a NameBinding<'a>, Name), - BareIdentifierPatternUnresolved, -} - /// One local scope. #[derive(Debug)] struct Rib<'a> { @@ -1814,7 +1778,7 @@ impl<'a> Resolver<'a> { // Add each argument to the rib. let mut bindings_list = HashMap::new(); for argument in &declaration.inputs { - self.resolve_pattern(&argument.pat, ArgumentIrrefutableMode, &mut bindings_list); + self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); self.visit_ty(&argument.ty); @@ -2055,7 +2019,7 @@ impl<'a> Resolver<'a> { walk_list!(self, visit_expr, &local.init); // Resolve the pattern. - self.resolve_pattern(&local.pat, LocalIrrefutableMode, &mut HashMap::new()); + self.resolve_pattern(&local.pat, PatternSource::Let, &mut HashMap::new()); } // build a map from pattern identifiers to binding-info's. @@ -2124,7 +2088,7 @@ impl<'a> Resolver<'a> { let mut bindings_list = HashMap::new(); for pattern in &arm.pats { - self.resolve_pattern(&pattern, RefutableMode, &mut bindings_list); + self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list); } // This has to happen *after* we determine which @@ -2183,10 +2147,18 @@ impl<'a> Resolver<'a> { // This is a path in the type namespace. Walk through scopes // looking for it. if let Some(def) = 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); + match def.base_def { + Def::Mod(..) => { + 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()); @@ -2246,312 +2218,230 @@ impl<'a> Resolver<'a> { visit::walk_ty(self, ty); } - fn resolve_pattern(&mut self, - pattern: &Pat, - mode: PatternBindingMode, - // Maps idents to the node ID for the (outermost) - // pattern that binds them - bindings_list: &mut HashMap) { - let pat_id = pattern.id; - pattern.walk(&mut |pattern| { - match pattern.node { - PatKind::Ident(binding_mode, ref path1, ref at_rhs) => { - // The meaning of PatKind::Ident with no type parameters - // depends on whether an enum variant or unit-like struct - // with that name is in scope. The probing lookup has to - // be careful not to emit spurious errors. Only matching - // patterns (match) can match nullary variants or - // unit-like structs. For binding patterns (let - // and the LHS of @-patterns), matching such a value is - // simply disallowed (since it's rarely what you want). - let const_ok = mode == RefutableMode && at_rhs.is_none(); - - let ident = path1.node; - let renamed = mtwt::resolve(ident); - - match self.resolve_bare_identifier_pattern(ident, pattern.span) { - FoundStructOrEnumVariant(def) if const_ok => { - debug!("(resolving pattern) resolving `{}` to struct or enum variant", - renamed); - - self.enforce_default_binding_mode(pattern, - binding_mode, - "an enum variant"); - self.record_def(pattern.id, - PathResolution { - base_def: def, - depth: 0, - }); - } - FoundStructOrEnumVariant(..) => { - resolve_error( - self, - pattern.span, - ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct( - renamed) - ); - self.record_def(pattern.id, err_path_resolution()); - } - FoundConst(binding, _) if const_ok => { - debug!("(resolving pattern) resolving `{}` to constant", renamed); - - self.enforce_default_binding_mode(pattern, binding_mode, "a constant"); - self.record_def(pattern.id, - PathResolution { - base_def: binding.def().unwrap(), - depth: 0, - }); - } - FoundConst(binding, name) => { - resolve_error( - self, - pattern.span, - ResolutionError::ConstantForIrrefutableBinding(name, binding) - ); - self.record_def(pattern.id, err_path_resolution()); - } - BareIdentifierPatternUnresolved => { - debug!("(resolving pattern) binding `{}`", renamed); - - let def_id = self.definitions.local_def_id(pattern.id); - let def = Def::Local(def_id, pattern.id); - - // Record the definition so that later passes - // will be able to distinguish variants from - // locals in patterns. - - self.record_def(pattern.id, - PathResolution { - base_def: def, - depth: 0, - }); - - // Add the binding to the local ribs, if it - // doesn't already exist in the bindings list. (We - // must not add it if it's in the bindings list - // because that breaks the assumptions later - // passes make about or-patterns.) - if !bindings_list.contains_key(&renamed) { - let this = &mut *self; - let last_rib = this.value_ribs.last_mut().unwrap(); - last_rib.bindings.insert(renamed, def); - bindings_list.insert(renamed, pat_id); - } else if mode == ArgumentIrrefutableMode && - bindings_list.contains_key(&renamed) { - // Forbid duplicate bindings in the same - // parameter list. - resolve_error( - self, - pattern.span, - ResolutionError::IdentifierBoundMoreThanOnceInParameterList( - &ident.name.as_str()) - ); - } else if bindings_list.get(&renamed) == Some(&pat_id) { - // Then this is a duplicate variable in the - // same disjunction, which is an error. - resolve_error( - self, - pattern.span, - ResolutionError::IdentifierBoundMoreThanOnceInSamePattern( - &ident.name.as_str()) - ); - } - // Else, not bound in the same pattern: do - // nothing. - } - } - } + fn fresh_binding(&mut self, + ident: &ast::SpannedIdent, + pat_id: NodeId, + outer_pat_id: NodeId, + pat_src: PatternSource, + bindings_list: &mut HashMap) + -> PathResolution { + // Add the binding to the local ribs, if it + // doesn't already exist in the bindings list. (We + // must not add it if it's in the bindings list + // because that breaks the assumptions later + // passes make about or-patterns.) + let renamed = mtwt::resolve(ident.node); + let def = match bindings_list.get(&renamed).cloned() { + Some(id) if id == outer_pat_id => { + // `Variant(a, a)`, error + resolve_error( + self, + ident.span, + ResolutionError::IdentifierBoundMoreThanOnceInSamePattern( + &ident.node.name.as_str()) + ); + Def::Err + } + Some(..) if pat_src == PatternSource::FnParam => { + // `fn f(a: u8, a: u8)`, error + resolve_error( + self, + ident.span, + ResolutionError::IdentifierBoundMoreThanOnceInParameterList( + &ident.node.name.as_str()) + ); + Def::Err + } + Some(..) if pat_src == PatternSource::Match => { + // `Varian1(a) | Varian2(a)`, ok + Def::Local(self.definitions.local_def_id(pat_id), pat_id) + } + Some(..) => { + span_bug!(ident.span, "two bindings with the same name from \ + unexpected pattern source {:?}", pat_src); + } + None => { + // A completely fresh binding, add to the lists + bindings_list.insert(renamed, outer_pat_id); + let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id); + self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def); + def + } + }; - PatKind::TupleStruct(ref path, _, _) | PatKind::Path(ref path) => { - // This must be an enum variant, struct or const. - let resolution = match self.resolve_possibly_assoc_item(pat_id, - None, - path, - ValueNS) { - // The below shouldn't happen because all - // qualified paths should be in PatKind::QPath. - TypecheckRequired => - span_bug!(path.span, - "resolve_possibly_assoc_item claimed that a path \ - in PatKind::Path or PatKind::TupleStruct \ - requires typecheck to resolve, but qualified \ - paths should be PatKind::QPath"), - ResolveAttempt(resolution) => resolution, - }; - if let Some(path_res) = resolution { - match path_res.base_def { - Def::Struct(..) if path_res.depth == 0 => { - self.record_def(pattern.id, path_res); - } - Def::Variant(..) | Def::Const(..) => { - self.record_def(pattern.id, path_res); - } - Def::Static(..) => { - let segments = &path.segments; - let binding = if path.global { - self.resolve_crate_relative_path(path.span, segments, ValueNS) - } else { - self.resolve_module_relative_path(path.span, segments, ValueNS) - }.unwrap(); + PathResolution { base_def: def, depth: 0 } + } - let error = ResolutionError::StaticVariableReference(binding); - resolve_error(self, path.span, error); - self.record_def(pattern.id, err_path_resolution()); - } - _ => { - // If anything ends up here entirely resolved, - // it's an error. If anything ends up here - // partially resolved, that's OK, because it may - // be a `T::CONST` that typeck will resolve. - if path_res.depth == 0 { - resolve_error( - self, - path.span, - ResolutionError::NotAnEnumVariantStructOrConst( - &path.segments - .last() - .unwrap() - .identifier - .name - .as_str()) - ); - self.record_def(pattern.id, err_path_resolution()); - } else { - let const_name = path.segments - .last() - .unwrap() - .identifier - .name; - let traits = self.get_traits_containing_item(const_name); - self.trait_map.insert(pattern.id, traits); - self.record_def(pattern.id, path_res); - } - } - } - } else { - if let Err(false) = self.resolve_path(pat_id, &path, 0, ValueNS) { - // No error has been reported, so we need to do this ourselves. + fn resolve_pattern_path(&mut self, + pat_id: NodeId, + qself: Option<&QSelf>, + path: &Path, + namespace: Namespace, + expected_fn: ExpectedFn, + expected_what: &'static str) + where ExpectedFn: FnOnce(Def) -> bool + { + let resolution = match self.resolve_possibly_assoc_item(pat_id, qself, path, namespace) { + ResolveAttempt(resolution) => { + if let Some(resolution) = resolution { + if resolution.depth == 0 { + if expected_fn(resolution.base_def) { + resolution + } else { resolve_error( self, path.span, - ResolutionError::UnresolvedEnumVariantStructOrConst( - &path.segments.last().unwrap().identifier.name.as_str()) + ResolutionError::PatPathUnexpected(expected_what, + resolution.kind_name(), path) ); + err_path_resolution() + } + } else { + // Not fully resolved associated item `T::A::B::C` or + // `::A::B::C`. If `C` 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); } - self.record_def(pattern.id, err_path_resolution()); + resolution } - visit::walk_path(self, path); + } else { + if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) { + resolve_error( + self, + path.span, + ResolutionError::PatPathUnresolved(expected_what, path) + ); + } + err_path_resolution() + } + } + TypecheckRequired => { + // `::A::B::C`, resolves exclusively during typechecking. + // If `C` 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); } + return; + } + }; - PatKind::QPath(ref qself, ref path) => { - // Associated constants only. - let resolution = match self.resolve_possibly_assoc_item(pat_id, - Some(qself), - path, - ValueNS) { - TypecheckRequired => { - // All `::CONST` should end up here, and will - // require use of the trait map to resolve - // during typechecking. - let const_name = path.segments - .last() - .unwrap() - .identifier - .name; - let traits = self.get_traits_containing_item(const_name); - self.trait_map.insert(pattern.id, traits); - visit::walk_pat(self, pattern); - return true; - } - ResolveAttempt(resolution) => resolution, - }; - if let Some(path_res) = resolution { - match path_res.base_def { - // All `::CONST` should end up here, and - // have the trait already selected. - Def::AssociatedConst(..) => { - self.record_def(pattern.id, path_res); + self.record_def(pat_id, resolution); + } + + fn resolve_pattern(&mut self, + pat: &Pat, + pat_src: PatternSource, + // Maps idents to the node ID for the + // outermost pattern that binds them. + bindings_list: &mut HashMap) { + // Visit all direct subpatterns of this pattern with the same PatternBindingMode. + let outer_pat_id = pat.id; + pat.walk(&mut |pat| { + match pat.node { + PatKind::Ident(bmode, ref ident, ref opt_pat) => { + // First try to resolve the identifier as some existing + // entity, then fall back to a fresh binding. + let resolution = if let Ok(resolution) = self.resolve_path(pat.id, + &Path::from_ident(ident.span, ident.node), 0, ValueNS) { + let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || + bmode != BindingMode::ByValue(Mutability::Immutable); + match resolution.base_def { + // Def::Err => { + // // Just pass it through, the error is already + // // reported if it was necessary. + // resolution + // } + Def::Struct(..) | Def::Variant(..) | + Def::Const(..) | Def::AssociatedConst(..) if !always_binding => { + // A constant, unit variant, etc pattern. + resolution } - _ => { + Def::Struct(..) | Def::Variant(..) | + Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => { + // A fresh binding that shadows something unacceptable. resolve_error( self, - path.span, - ResolutionError::NotAnAssociatedConst( - &path.segments.last().unwrap().identifier.name.as_str() - ) + ident.span, + ResolutionError::BindingShadowsSomethingUnacceptable( + pat_src.descr(), resolution.kind_name(), ident.node.name) ); - self.record_def(pattern.id, err_path_resolution()); + err_path_resolution() + } + Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Err => { + // These entities are explicitly allowed + // to be shadowed by fresh bindings. + self.fresh_binding(ident, pat.id, outer_pat_id, + pat_src, bindings_list) + } + def => { + span_bug!(ident.span, "unexpected definition for an \ + identifier in pattern {:?}", def); } } } else { - resolve_error(self, - path.span, - ResolutionError::UnresolvedAssociatedConst(&path.segments - .last() - .unwrap() - .identifier - .name - .as_str())); - self.record_def(pattern.id, err_path_resolution()); - } - visit::walk_pat(self, pattern); + // Fall back to a fresh binding. + self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings_list) + }; + + self.record_def(pat.id, resolution); } - PatKind::Struct(ref path, _, _) => { - match self.resolve_path(pat_id, path, 0, TypeNS) { - Ok(definition) => { - self.record_def(pattern.id, definition); + PatKind::TupleStruct(ref path, _, _) => { + self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| { + match def { + Def::Struct(..) | Def::Variant(..) | Def::Err => true, + _ => false, } - Err(true) => self.record_def(pattern.id, err_path_resolution()), - Err(false) => { - resolve_error( - self, - path.span, - ResolutionError::DoesNotNameAStruct( - &path_names_to_string(path, 0)) - ); - self.record_def(pattern.id, err_path_resolution()); + }, "variant or struct"); + } + + PatKind::Path(ref path) => { + self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| { + match def { + Def::Struct(..) | Def::Variant(..) | + Def::Const(..) | Def::AssociatedConst(..) | Def::Err => true, + _ => false, } - } - visit::walk_path(self, path); + }, "variant, struct or constant"); } - PatKind::Lit(_) | PatKind::Range(..) => { - visit::walk_pat(self, pattern); + PatKind::QPath(ref qself, ref path) => { + self.resolve_pattern_path(pat.id, Some(qself), path, ValueNS, |def| { + match def { + Def::AssociatedConst(..) | Def::Err => true, + _ => false, + } + }, "associated constant"); } - _ => { - // Nothing to do. + PatKind::Struct(ref path, _, _) => { + self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| { + match def { + Def::Struct(..) | Def::Variant(..) | + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::Err => true, + _ => false, + } + }, "variant, struct or type alias"); } + + _ => {} } true }); - } - - fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span) - -> BareIdentifierPatternResolution<'a> { - let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) { - Some(LexicalScopeBinding::Item(binding)) => binding, - _ => return BareIdentifierPatternUnresolved, - }; - let def = binding.def().unwrap(); - match def { - Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def), - Def::Const(..) | Def::AssociatedConst(..) => FoundConst(binding, ident.name), - Def::Static(..) => { - let error = ResolutionError::StaticVariableReference(binding); - resolve_error(self, span, error); - BareIdentifierPatternUnresolved - } - _ => BareIdentifierPatternUnresolved, - } + visit::walk_pat(self, pat); } /// Handles paths that may refer to associated items fn resolve_possibly_assoc_item(&mut self, id: NodeId, - maybe_qself: Option<&ast::QSelf>, + maybe_qself: Option<&QSelf>, path: &Path, namespace: Namespace) -> AssocItemResolveResult { @@ -2579,13 +2469,14 @@ impl<'a> Resolver<'a> { break; } self.with_no_errors(|this| { - resolution = this.resolve_path(id, path, depth, TypeNS).ok(); + let partial_resolution = this.resolve_path(id, path, depth, TypeNS).ok(); + if let Some(Def::Mod(..)) = partial_resolution.map(|r| r.base_def) { + // Modules cannot have associated items + } else { + resolution = partial_resolution; + } }); } - if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) { - // A module is not a valid type or value. - resolution = None; - } ResolveAttempt(resolution) } @@ -3171,7 +3062,7 @@ impl<'a> Resolver<'a> { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new()); + self.resolve_pattern(pattern, PatternSource::IfLet, &mut HashMap::new()); self.visit_block(if_block); self.value_ribs.pop(); @@ -3181,7 +3072,7 @@ impl<'a> Resolver<'a> { ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new()); + self.resolve_pattern(pattern, PatternSource::WhileLet, &mut HashMap::new()); self.resolve_labeled_block(label.map(|l| l.node), expr.id, block); @@ -3191,7 +3082,7 @@ impl<'a> Resolver<'a> { ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, LocalIrrefutableMode, &mut HashMap::new()); + self.resolve_pattern(pattern, PatternSource::For, &mut HashMap::new()); self.resolve_labeled_block(label.map(|l| l.node), expr.id, block); @@ -3411,20 +3302,6 @@ impl<'a> Resolver<'a> { } } - fn enforce_default_binding_mode(&mut self, - pat: &Pat, - pat_binding_mode: BindingMode, - descr: &str) { - match pat_binding_mode { - BindingMode::ByValue(_) => {} - BindingMode::ByRef(..) => { - resolve_error(self, - pat.span, - ResolutionError::CannotUseRefBindingModeWith(descr)); - } - } - } - fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { let (path, id) = match *vis { ast::Visibility::Public => return ty::Visibility::Public, diff --git a/src/test/compile-fail/associated-const-private-impl.rs b/src/test/compile-fail/associated-const-private-impl.rs index be949db0281d2..6ebe80b5701b9 100644 --- a/src/test/compile-fail/associated-const-private-impl.rs +++ b/src/test/compile-fail/associated-const-private-impl.rs @@ -23,5 +23,5 @@ mod bar1 { fn main() { assert_eq!(1, bar1::Foo::ID); - //~^ERROR associated const `ID` is private + //~^ERROR associated constant `ID` is private } diff --git a/src/test/compile-fail/blind-item-block-middle.rs b/src/test/compile-fail/blind-item-block-middle.rs index 287eab7a56338..f57727b773d63 100644 --- a/src/test/compile-fail/blind-item-block-middle.rs +++ b/src/test/compile-fail/blind-item-block-middle.rs @@ -12,6 +12,6 @@ mod foo { pub struct bar; } fn main() { let bar = 5; - //~^ ERROR cannot be named the same + //~^ ERROR let bindings cannot shadow structs use foo::bar; } diff --git a/src/test/compile-fail/const-pattern-irrefutable.rs b/src/test/compile-fail/const-pattern-irrefutable.rs index 392f391fb5120..75b6397f4ebd7 100644 --- a/src/test/compile-fail/const-pattern-irrefutable.rs +++ b/src/test/compile-fail/const-pattern-irrefutable.rs @@ -19,10 +19,10 @@ use foo::d; //~ NOTE is imported here const a: u8 = 2; //~ NOTE is defined here fn main() { - let a = 4; //~ ERROR let variables cannot - //~^ NOTE cannot be named the same as a const variable - let c = 4; //~ ERROR let variables cannot - //~^ NOTE cannot be named the same as a const variable - let d = 4; //~ ERROR let variables cannot - //~^ NOTE cannot be named the same as a const variable + let a = 4; //~ ERROR let bindings cannot shadow constants + //~^ NOTE cannot be named the same as a constant + let c = 4; //~ ERROR let bindings cannot shadow constants + //~^ NOTE cannot be named the same as a constant + let d = 4; //~ ERROR let bindings cannot shadow constants + //~^ NOTE cannot be named the same as a constant } 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 0bd96d8209596..0522a654a8528 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-2.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs @@ -29,9 +29,9 @@ fn main() { // XEmpty1() => () // ERROR unresolved enum variant, struct or const `XEmpty1` // } match e1 { - Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1` + Empty1(..) => () //~ ERROR unresolved variant or struct `Empty1` } match xe1 { - XEmpty1(..) => () //~ ERROR unresolved enum variant, struct or const `XEmpty1` + XEmpty1(..) => () //~ ERROR unresolved variant or struct `XEmpty1` } } diff --git a/src/test/compile-fail/enum-in-scope.rs b/src/test/compile-fail/enum-in-scope.rs index 6dffd1999d79b..e89b08a8a0651 100644 --- a/src/test/compile-fail/enum-in-scope.rs +++ b/src/test/compile-fail/enum-in-scope.rs @@ -11,5 +11,5 @@ struct hello(isize); fn main() { - let hello = 0; //~ERROR cannot be named the same + let hello = 0; //~ERROR let bindings cannot shadow structs } diff --git a/src/test/compile-fail/enums-pats-not-idents.rs b/src/test/compile-fail/enums-pats-not-idents.rs index faf672415bdfa..c847366a707a7 100644 --- a/src/test/compile-fail/enums-pats-not-idents.rs +++ b/src/test/compile-fail/enums-pats-not-idents.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//error-pattern:unresolved enum variant - fn main() { - // a bug in the parser is allowing this: - let a(1) = 13; + let a(1) = 13; //~ ERROR unresolved variant or struct `a` } diff --git a/src/test/compile-fail/issue-10200.rs b/src/test/compile-fail/issue-10200.rs index 03d4e9b81eb29..9eec8487a5087 100644 --- a/src/test/compile-fail/issue-10200.rs +++ b/src/test/compile-fail/issue-10200.rs @@ -13,7 +13,7 @@ fn foo(_: usize) -> Foo { Foo(false) } fn main() { match Foo(true) { - foo(x) //~ ERROR `foo` is not an enum variant, struct or const + foo(x) //~ ERROR expected variant or struct, found function `foo` => () } } diff --git a/src/test/compile-fail/issue-12863.rs b/src/test/compile-fail/issue-12863.rs index 07676679ef18f..7912410f69ea1 100644 --- a/src/test/compile-fail/issue-12863.rs +++ b/src/test/compile-fail/issue-12863.rs @@ -12,6 +12,6 @@ mod foo { pub fn bar() {} } fn main() { match () { - foo::bar => {} //~ ERROR `bar` is not an enum variant, struct or const + foo::bar => {} //~ ERROR expected variant, struct or constant, found function `bar` } } diff --git a/src/test/compile-fail/issue-16149.rs b/src/test/compile-fail/issue-16149.rs index 4954c95fcd1f2..60117bd88d46a 100644 --- a/src/test/compile-fail/issue-16149.rs +++ b/src/test/compile-fail/issue-16149.rs @@ -15,7 +15,7 @@ extern { fn main() { let boolValue = match 42 { externalValue => true, - //~^ ERROR static variables cannot be referenced in a pattern + //~^ ERROR match bindings cannot shadow statics _ => false }; } diff --git a/src/test/compile-fail/issue-17405.rs b/src/test/compile-fail/issue-17405.rs index de8a4f63476dc..db43c1cce9947 100644 --- a/src/test/compile-fail/issue-17405.rs +++ b/src/test/compile-fail/issue-17405.rs @@ -14,6 +14,7 @@ enum Foo { fn main() { match Foo::Bar(1) { - Foo { i } => () //~ ERROR `Foo` does not name a struct or a struct variant + Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo` + //~^ ERROR `Foo` does not name a struct or a struct variant } } diff --git a/src/test/compile-fail/issue-17718-const-privacy.rs b/src/test/compile-fail/issue-17718-const-privacy.rs index 021edbee566ba..523a387956a32 100644 --- a/src/test/compile-fail/issue-17718-const-privacy.rs +++ b/src/test/compile-fail/issue-17718-const-privacy.rs @@ -12,10 +12,10 @@ extern crate issue_17718_const_privacy as other; -use a::B; //~ ERROR: const `B` is private +use a::B; //~ ERROR: constant `B` is private use other::{ FOO, - BAR, //~ ERROR: const `BAR` is private + BAR, //~ ERROR: constant `BAR` is private FOO2, }; diff --git a/src/test/compile-fail/issue-17718-patterns.rs b/src/test/compile-fail/issue-17718-patterns.rs index 4e63f667d26fa..b9f5e98b6faa9 100644 --- a/src/test/compile-fail/issue-17718-patterns.rs +++ b/src/test/compile-fail/issue-17718-patterns.rs @@ -14,8 +14,8 @@ const A3: usize = 1; fn main() { match 1 { - A1 => {} //~ ERROR: static variables cannot be referenced in a pattern - A2 => {} //~ ERROR: static variables cannot be referenced in a pattern + A1 => {} //~ ERROR: match bindings cannot shadow statics + A2 => {} //~ ERROR: match bindings cannot shadow statics A3 => {} _ => {} } diff --git a/src/test/compile-fail/issue-17933.rs b/src/test/compile-fail/issue-17933.rs index 657b31fa83c7f..2313a3fe9c6d5 100644 --- a/src/test/compile-fail/issue-17933.rs +++ b/src/test/compile-fail/issue-17933.rs @@ -13,7 +13,7 @@ pub static X: usize = 1; fn main() { match 1 { self::X => { }, - //~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead + //~^ ERROR expected variant, struct or constant, found static `X` _ => { }, } } diff --git a/src/test/compile-fail/issue-23716.rs b/src/test/compile-fail/issue-23716.rs index b0d36610b7a51..5cf80dd172a3d 100644 --- a/src/test/compile-fail/issue-23716.rs +++ b/src/test/compile-fail/issue-23716.rs @@ -9,21 +9,21 @@ // except according to those terms. static foo: i32 = 0; -//~^ NOTE static variable defined here +//~^ NOTE a static `foo` is defined here fn bar(foo: i32) {} -//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead -//~| static variable used in pattern +//~^ ERROR function parameters cannot shadow statics +//~| cannot be named the same as a static mod submod { pub static answer: i32 = 42; } use self::submod::answer; -//~^ NOTE static variable imported here +//~^ NOTE a static `answer` is imported here fn question(answer: i32) {} -//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead -//~| static variable used in pattern +//~^ ERROR function parameters cannot shadow statics +//~| cannot be named the same as a static fn main() { } diff --git a/src/test/compile-fail/issue-26459.rs b/src/test/compile-fail/issue-26459.rs index 48eda91fbae50..6cadbef33e7f0 100644 --- a/src/test/compile-fail/issue-26459.rs +++ b/src/test/compile-fail/issue-26459.rs @@ -11,6 +11,7 @@ fn main() { match 'a' { char{ch} => true - //~^ ERROR `char` does not name a struct or a struct variant + //~^ ERROR expected variant, struct or type alias, found builtin type `char` + //~| ERROR `char` does not name a struct or a struct variant }; } diff --git a/src/test/compile-fail/issue-27033.rs b/src/test/compile-fail/issue-27033.rs index b0904dfeaa7a3..2a015adb498e1 100644 --- a/src/test/compile-fail/issue-27033.rs +++ b/src/test/compile-fail/issue-27033.rs @@ -10,11 +10,11 @@ fn main() { match Some(1) { - None @ _ => {} //~ ERROR cannot be named the same + None @ _ => {} //~ ERROR match bindings cannot shadow variants }; const C: u8 = 1; match 1 { - C @ 2 => { //~ ERROR cannot be named the same + C @ 2 => { //~ ERROR match bindings cannot shadow constant println!("{}", C); } _ => {} diff --git a/src/test/compile-fail/issue-27815.rs b/src/test/compile-fail/issue-27815.rs index b1ac2dfd1c414..d2f9abd2e316b 100644 --- a/src/test/compile-fail/issue-27815.rs +++ b/src/test/compile-fail/issue-27815.rs @@ -14,7 +14,9 @@ fn main() { let u = A { x: 1 }; //~ ERROR `A` does not name a structure let v = u32 { x: 1 }; //~ ERROR `u32` does not name a structure match () { - A { x: 1 } => {} //~ ERROR `A` does not name a struct - u32 { x: 1 } => {} //~ ERROR `u32` does not name a struct + A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A` + //~^ ERROR `A` does not name a struct or a struct variant + u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32 + //~^ ERROR `u32` does not name a struct or a struct variant } } diff --git a/src/test/compile-fail/issue-28992-empty.rs b/src/test/compile-fail/issue-28992-empty.rs index f7d53ba23daf5..e492d48fdaf0f 100644 --- a/src/test/compile-fail/issue-28992-empty.rs +++ b/src/test/compile-fail/issue-28992-empty.rs @@ -21,6 +21,6 @@ impl S { } fn main() { - if let C1(..) = 0 {} //~ ERROR `C1` does not name a tuple variant or a tuple struct + if let C1(..) = 0 {} //~ ERROR expected variant or struct, found constant `C1` if let S::C2(..) = 0 {} //~ ERROR `S::C2` does not name a tuple variant or a tuple struct } diff --git a/src/test/compile-fail/issue-5927.rs b/src/test/compile-fail/issue-5927.rs index e5f091d873df9..3a8ff12429ab3 100644 --- a/src/test/compile-fail/issue-5927.rs +++ b/src/test/compile-fail/issue-5927.rs @@ -11,7 +11,7 @@ fn main() { let z = match 3 { - x(1) => x(1) //~ ERROR unresolved enum variant + x(1) => x(1) //~ ERROR unresolved variant or struct `x` //~^ ERROR unresolved name `x` }; assert!(z == 3); diff --git a/src/test/compile-fail/method-resolvable-path-in-pattern.rs b/src/test/compile-fail/method-resolvable-path-in-pattern.rs index 0df824e7f535b..1cba64ccf2cde 100644 --- a/src/test/compile-fail/method-resolvable-path-in-pattern.rs +++ b/src/test/compile-fail/method-resolvable-path-in-pattern.rs @@ -19,6 +19,6 @@ impl MyTrait for Foo {} fn main() { match 0u32 { ::trait_bar => {} - //~^ ERROR `trait_bar` is not an associated const + //~^ ERROR expected associated constant, found method `trait_bar` } } diff --git a/src/test/compile-fail/name-clash-nullary.rs b/src/test/compile-fail/name-clash-nullary.rs index 662bb7bfe57f0..2e2d53c4d40b6 100644 --- a/src/test/compile-fail/name-clash-nullary.rs +++ b/src/test/compile-fail/name-clash-nullary.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:cannot be named the same use std::option::*; fn main() { - let None: isize = 42; + let None: isize = 42; //~ ERROR let bindings cannot shadow variants log(debug, None); + //~^ ERROR unresolved name `debug` + //~| ERROR unresolved name `log` } diff --git a/src/test/compile-fail/pat-shadow-in-nested-binding.rs b/src/test/compile-fail/pat-shadow-in-nested-binding.rs index 4a8513e10d755..f1683e51c648d 100644 --- a/src/test/compile-fail/pat-shadow-in-nested-binding.rs +++ b/src/test/compile-fail/pat-shadow-in-nested-binding.rs @@ -11,5 +11,5 @@ struct foo(usize); fn main() { - let (foo, _) = (2, 3); //~ ERROR `foo` cannot be named the same as + let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow structs } diff --git a/src/test/compile-fail/qualified-path-params.rs b/src/test/compile-fail/qualified-path-params.rs index 002080f4cb44c..86873022f0ff1 100644 --- a/src/test/compile-fail/qualified-path-params.rs +++ b/src/test/compile-fail/qualified-path-params.rs @@ -27,7 +27,7 @@ impl S { fn main() { match 10 { - ::A::f:: => {} //~ ERROR `f` is not an associated const + ::A::f:: => {} //~ ERROR associated items in match patterns must be constants 0 ... ::A::f:: => {} //~ ERROR only char and numeric types are allowed in range } } diff --git a/src/test/compile-fail/static-mut-not-pat.rs b/src/test/compile-fail/static-mut-not-pat.rs index 76fecea0c3a6a..351a47fdf3923 100644 --- a/src/test/compile-fail/static-mut-not-pat.rs +++ b/src/test/compile-fail/static-mut-not-pat.rs @@ -20,7 +20,7 @@ fn main() { // instead of spitting out a custom error about some identifier collisions // (we should allow shadowing) match 4 { - a => {} //~ ERROR static variables cannot be referenced in a pattern + a => {} //~ ERROR match bindings cannot shadow statics _ => {} } } @@ -44,7 +44,7 @@ fn mutable_statics() { match (Foo { bar: Some(Direction::North), baz: NewBool(true) }) { Foo { bar: None, baz: NewBool(true) } => (), STATIC_MUT_FOO => (), - //~^ ERROR static variables cannot be referenced in a pattern + //~^ ERROR match bindings cannot shadow statics Foo { bar: Some(Direction::South), .. } => (), Foo { bar: Some(EAST), .. } => (), Foo { bar: Some(Direction::North), baz: NewBool(true) } => (), diff --git a/src/test/compile-fail/trait-impl-for-module.rs b/src/test/compile-fail/trait-impl-for-module.rs index c04e197b6bd77..1fe8f6294da21 100644 --- a/src/test/compile-fail/trait-impl-for-module.rs +++ b/src/test/compile-fail/trait-impl-for-module.rs @@ -14,7 +14,7 @@ mod a { trait A { } -impl A for a { //~ ERROR type name `a` is undefined or not in scope +impl A for a { //~ ERROR expected type, found module } fn main() {