提交 db0be32f 编写于 作者: V Vadim Petrochenkov

resolve: Use same rules for disambiguating fresh bindings in `match` and `let`

上级 2278506f
...@@ -376,12 +376,6 @@ enum PatternSource { ...@@ -376,12 +376,6 @@ enum PatternSource {
} }
impl PatternSource { 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 { fn descr(self) -> &'static str {
match self { match self {
PatternSource::Match => "match binding", PatternSource::Match => "match binding",
...@@ -2378,20 +2372,24 @@ fn resolve_pattern(&mut self, ...@@ -2378,20 +2372,24 @@ fn resolve_pattern(&mut self,
false, pat.span) false, pat.span)
.and_then(LexicalScopeBinding::item); .and_then(LexicalScopeBinding::item);
let resolution = binding.map(NameBinding::def).and_then(|def| { let resolution = binding.map(NameBinding::def).and_then(|def| {
let ivmode = BindingMode::ByValue(Mutability::Immutable); let is_syntactic_ambiguity = opt_pat.is_none() &&
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || bmode == BindingMode::ByValue(Mutability::Immutable);
bmode != ivmode;
match def { match def {
Def::StructCtor(_, CtorKind::Const) | Def::StructCtor(_, CtorKind::Const) |
Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Const) |
Def::Const(..) if !always_binding => { Def::Const(..) if is_syntactic_ambiguity => {
// A unit struct/variant or constant pattern. // Disambiguate in favor of a unit struct/variant
// or constant pattern.
self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span); self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span);
Some(PathResolution::new(def)) Some(PathResolution::new(def))
} }
Def::StructCtor(..) | Def::VariantCtor(..) | Def::StructCtor(..) | Def::VariantCtor(..) |
Def::Const(..) | Def::Static(..) => { Def::Const(..) | Def::Static(..) => {
// A fresh binding that shadows something unacceptable. // This is unambiguously a fresh binding, either syntactically
// (e.g. `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
// to something unusable as a pattern (e.g. constructor function),
// but we still conservatively report an error, see
// issues/33118#issuecomment-233962221 for one reason why.
resolve_error( resolve_error(
self, self,
ident.span, ident.span,
...@@ -2400,7 +2398,7 @@ fn resolve_pattern(&mut self, ...@@ -2400,7 +2398,7 @@ fn resolve_pattern(&mut self,
); );
None None
} }
Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Err => { Def::Fn(..) | Def::Err => {
// These entities are explicitly allowed // These entities are explicitly allowed
// to be shadowed by fresh bindings. // to be shadowed by fresh bindings.
None None
......
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
fn main() { fn main() {
let bar = 5; let bar = 5;
//~^ ERROR let bindings cannot shadow unit structs //~^ ERROR mismatched types
use foo::bar; use foo::bar;
} }
...@@ -13,17 +13,17 @@ mod foo { ...@@ -13,17 +13,17 @@ mod foo {
pub const d: u8 = 2; pub const d: u8 = 2;
} }
use foo::b as c; //~ NOTE is imported here use foo::b as c;
use foo::d; //~ NOTE is imported here use foo::d;
const a: u8 = 2; //~ NOTE is defined here const a: u8 = 2;
fn main() { fn main() {
let a = 4; //~ ERROR let bindings cannot shadow constants let a = 4; //~ ERROR refutable pattern in local binding: `_` not covered
//~^ NOTE cannot be named the same as a constant //~^ NOTE pattern `_` not covered
let c = 4; //~ ERROR let bindings cannot shadow constants let c = 4; //~ ERROR refutable pattern in local binding: `_` not covered
//~^ NOTE cannot be named the same as a constant //~^ NOTE pattern `_` not covered
let d = 4; //~ ERROR let bindings cannot shadow constants let d = 4; //~ ERROR refutable pattern in local binding: `_` not covered
//~^ NOTE cannot be named the same as a constant //~^ NOTE pattern `_` not covered
fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115). fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
} }
...@@ -14,6 +14,6 @@ ...@@ -14,6 +14,6 @@
fn main() { fn main() {
|| { || {
let Test = 1; //~ ERROR let bindings cannot shadow unit structs let Test = 1; //~ ERROR mismatched types
}; };
} }
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
use std::option::*; use std::option::*;
fn main() { fn main() {
let None: isize = 42; //~ ERROR let bindings cannot shadow unit variants let None: isize = 42; //~ ERROR mismatched types
log(debug, None); log(debug, None);
//~^ ERROR cannot find function `log` in this scope //~^ ERROR cannot find function `log` in this scope
//~| ERROR cannot find value `debug` in this scope //~| ERROR cannot find value `debug` in this scope
......
// Copyright 2017 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.
struct UnitStruct;
struct TupleStruct();
struct BracedStruct{}
enum E {
UnitVariant,
TupleVariant(),
BracedVariant{},
}
use E::*;
const CONST: () = ();
static STATIC: () = ();
fn function() {}
fn main() {
let doesnt_matter = 0;
match UnitStruct {
UnitStruct => {} // OK, `UnitStruct` is a unit struct pattern
}
match doesnt_matter {
TupleStruct => {} //~ ERROR match bindings cannot shadow tuple structs
}
match doesnt_matter {
BracedStruct => {} // OK, `BracedStruct` is a fresh binding
}
match UnitVariant {
UnitVariant => {} // OK, `UnitVariant` is a unit variant pattern
}
match doesnt_matter {
TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants
}
match doesnt_matter {
BracedVariant => {} //~ ERROR match bindings cannot shadow struct variants
}
match CONST {
CONST => {} // OK, `CONST` is a const pattern
}
match doesnt_matter {
STATIC => {} //~ ERROR match bindings cannot shadow statics
}
match doesnt_matter {
function => {} // OK, `function` is a fresh binding
}
let UnitStruct = UnitStruct; // OK, `UnitStruct` is a unit struct pattern
let TupleStruct = doesnt_matter; //~ ERROR let bindings cannot shadow tuple structs
let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding
let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern
let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants
let BracedVariant = doesnt_matter; //~ ERROR let bindings cannot shadow struct variants
let CONST = CONST; // OK, `CONST` is a const pattern
let STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics
let function = doesnt_matter; // OK, `function` is a fresh binding
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册