From d8062a9317a3113a9d0447895a2d12899072a6c8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 12 Nov 2015 00:46:57 +0530 Subject: [PATCH 1/2] Add more comprehensive diagnostics for irrefutable pattern error with constants Fixes #7526 --- src/librustc_resolve/lib.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e9a0efe76cb42..aa5824b96a120 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -153,7 +153,7 @@ pub enum ResolutionError<'a> { /// error E0413: declaration shadows an enum variant or unit-like struct in scope DeclarationShadowsEnumVariantOrUnitLikeStruct(Name), /// error E0414: only irrefutable patterns allowed here - OnlyIrrefutablePatternsAllowedHere, + OnlyIrrefutablePatternsAllowedHere(DefId, Name), /// 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 @@ -283,8 +283,16 @@ fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syn scope", name); }, - ResolutionError::OnlyIrrefutablePatternsAllowedHere => { + ResolutionError::OnlyIrrefutablePatternsAllowedHere(did, name) => { span_err!(resolver.session, span, E0414, "only irrefutable patterns allowed here"); + resolver.session.span_note(span, "there already is a constant in scope sharing the same name as this pattern"); + if let Some(sp) = resolver.ast_map.span_if_local(did) { + resolver.session.span_note(sp, "constant defined here"); + } + if let Some(directive) = resolver.current_module.import_resolutions.borrow().get(&name) { + let item = resolver.ast_map.expect_item(directive.value_id); + resolver.session.span_note(item.span, "constant imported here"); + } }, ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { span_err!(resolver.session, span, E0415, @@ -632,7 +640,7 @@ enum NameSearchType { #[derive(Copy, Clone)] enum BareIdentifierPatternResolution { FoundStructOrEnumVariant(Def, LastPrivate), - FoundConst(Def, LastPrivate), + FoundConst(Def, LastPrivate, Name), BareIdentifierPatternUnresolved } @@ -2685,7 +2693,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { renamed) ); } - FoundConst(def, lp) if const_ok => { + FoundConst(def, lp, _) if const_ok => { debug!("(resolving pattern) resolving `{}` to \ constant", renamed); @@ -2700,11 +2708,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { depth: 0 }); } - FoundConst(..) => { + FoundConst(def, _, name) => { resolve_error( self, pattern.span, - ResolutionError::OnlyIrrefutablePatternsAllowedHere + ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(), name) ); } BareIdentifierPatternUnresolved => { @@ -2929,7 +2937,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return FoundStructOrEnumVariant(def, LastMod(AllPublic)); } def @ DefConst(..) | def @ DefAssociatedConst(..) => { - return FoundConst(def, LastMod(AllPublic)); + return FoundConst(def, LastMod(AllPublic), name); } DefStatic(..) => { resolve_error(self, From 9be0ba5cc0e27e32e4d55332118f9891e97e5423 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 12 Nov 2015 00:48:02 +0530 Subject: [PATCH 2/2] Add test for constant pattern diagnostics --- .../compile-fail/const-pattern-irrefutable.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/compile-fail/const-pattern-irrefutable.rs diff --git a/src/test/compile-fail/const-pattern-irrefutable.rs b/src/test/compile-fail/const-pattern-irrefutable.rs new file mode 100644 index 0000000000000..2d345d9142b0b --- /dev/null +++ b/src/test/compile-fail/const-pattern-irrefutable.rs @@ -0,0 +1,28 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod foo { + const b: u8 = 2; //~ NOTE constant defined here + const d: u8 = 2; //~ NOTE constant defined here +} + +use foo::b as c; //~ NOTE constant imported here +use foo::d; //~ NOTE constant imported here + +const a: u8 = 2; //~ NOTE constant defined here + +fn main() { + let a = 4; //~ ERROR only irrefutable + //~^ NOTE there already is a constant in scope + let c = 4; //~ ERROR only irrefutable + //~^ NOTE there already is a constant in scope + let d = 4; //~ ERROR only irrefutable + //~^ NOTE there already is a constant in scope +}