提交 6d7b35bd 编写于 作者: V Vadim Petrochenkov

Address review comments + fix rebase

上级 e783a0a5
......@@ -1105,17 +1105,10 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
(*op)(self, cmt.clone(), pat);
// This function can be used during region checking when not all paths are fully
// resolved. Partially resolved paths in patterns can only legally refer to
// associated constants which don't require categorization.
let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
if path_res.depth != 0 || path_res.base_def == Def::Err {
return Err(());
}
Some(path_res.full_def())
} else {
None
};
let opt_def = self.tcx().expect_def_or_none(pat.id);
if opt_def == Some(Def::Err) {
return Err(());
}
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
// alone) because struct patterns can refer to struct types or
......
......@@ -162,7 +162,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
}
PatKind::Binding(bm, ref ident, ref sub) => {
let id = self.cx.tcx.def_map.borrow()[&pat.id].full_def().var_id();
let id = self.cx.tcx.expect_def(pat.id).var_id();
let var_ty = self.cx.tcx.node_id_to_type(pat.id);
let region = match var_ty.sty {
ty::TyRef(&r, _) => Some(r),
......
......@@ -584,7 +584,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
hir::ExprStruct(..) => {
if v.tcx.expect_def(e.id).def_id() == v.tcx.lang_items.unsafe_cell_type().unwrap() {
// unsafe_cell_type doesn't necessarily exist with no_core
if Some(v.tcx.expect_def(e.id).def_id()) == v.tcx.lang_items.unsafe_cell_type() {
v.add_qualif(ConstQualif::MUTABLE_MEM);
}
}
......
......@@ -677,100 +677,6 @@ fn foo<T>(x: T) {} // ok!
```
"##,
E0413: r##"
A declaration shadows an enum variant or unit-like struct in scope. Example of
erroneous code:
```compile_fail
struct Foo;
let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or
// unit-like struct in scope
```
To fix this error, rename the variable such that it doesn't shadow any enum
variable or structure in scope. Example:
```
struct Foo;
let foo = 12i32; // ok!
```
Or:
```
struct FooStruct;
let Foo = 12i32; // ok!
```
The goal here is to avoid a conflict of names.
"##,
E0414: r##"
A variable binding in an irrefutable pattern is shadowing the name of a
constant. Example of erroneous code:
```compile_fail
const FOO: u8 = 7;
let FOO = 5; // error: variable bindings cannot shadow constants
// or
fn bar(FOO: u8) { // error: variable bindings cannot shadow constants
}
// or
for FOO in bar {
}
```
Introducing a new variable in Rust is done through a pattern. Thus you can have
`let` bindings like `let (a, b) = ...`. However, patterns also allow constants
in them, e.g. if you want to match over a constant:
```ignore
const FOO: u8 = 1;
match (x,y) {
(3, 4) => { .. }, // it is (3,4)
(FOO, 1) => { .. }, // it is (1,1)
(foo, 1) => { .. }, // it is (anything, 1)
// call the value in the first slot "foo"
_ => { .. } // it is anything
}
```
Here, the second arm matches the value of `x` against the constant `FOO`,
whereas the third arm will accept any value of `x` and call it `foo`.
This works for `match`, however in cases where an irrefutable pattern is
required, constants can't be used. An irrefutable pattern is one which always
matches, whose purpose is only to bind variable names to values. These are
required by let, for, and function argument patterns.
Refutable patterns in such a situation do not make sense, for example:
```ignore
let Some(x) = foo; // what if foo is None, instead?
let (1, x) = foo; // what if foo.0 is not 1?
let (SOME_CONST, x) = foo; // what if foo.0 is not SOME_CONST?
let SOME_CONST = foo; // what if foo is not SOME_CONST?
```
Thus, an irrefutable variable binding can't contain a constant.
To fix this error, just give the marked variable a different name.
"##,
E0415: r##"
More than one function parameter have the same name. Example of erroneous code:
......@@ -814,34 +720,6 @@ fn foo(f: i32, g: i32) {} // ok!
```
"##,
E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code:
```compile_fail
static FOO : i32 = 0;
match 0 {
FOO => {} // error: static variables cannot be referenced in a
// pattern, use a `const` instead
_ => {}
}
```
The compiler needs to know the value of the pattern at compile time;
compile-time patterns can defined via const or enum items. Please verify
that the identifier is spelled correctly, and if so, use a const instead
of static to define it. Example:
```
const FOO : i32 = 0;
match 0 {
FOO => {} // ok!
_ => {}
}
```
"##,
E0422: r##"
You are trying to use an identifier that is either undefined or not a struct.
For instance:
......@@ -1221,11 +1099,23 @@ 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
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 ...
// E0410, merged into 408
// E0413, merged into 530
// E0414, merged into 530
// E0417, merged into 532
// E0418, merged into 532
// E0419, merged into 531
// E0420, merged into 532
// E0421, merged into 531
E0530, // X bindings cannot shadow Ys
E0531, // unresolved pattern path kind `name`
E0532, // expected pattern path kind, found another pattern path kind
// E0427, merged into 530
}
......@@ -155,11 +155,11 @@ enum ResolutionError<'a> {
CannotCaptureDynamicEnvironmentInFnItem,
/// error E0435: attempt to use a non-constant value in a constant
AttemptToUseNonConstantValueInConstant,
/// error E0418: X bindings cannot shadow Ys
/// error E0530: X bindings cannot shadow Ys
BindingShadowsSomethingUnacceptable(&'a str, &'a str, Name),
/// error E0419: unresolved pattern path kind `name`
/// error E0531: unresolved pattern path kind `name`
PatPathUnresolved(&'a str, &'a Path),
/// error E0420: expected pattern path kind, found another pattern path kind
/// error E0532: expected pattern path kind, found another pattern path kind
PatPathUnexpected(&'a str, &'a str, &'a Path),
}
......@@ -426,11 +426,10 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => {
let mut err = struct_span_err!(resolver.session,
span,
E0418,
E0530,
"{}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) {
if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
let participle = if binding.is_import() { "imported" } else { "defined" };
err.span_label(binding.span, &format!("a {} `{}` is {} here",
shadows_what, name, participle));
......@@ -440,7 +439,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
ResolutionError::PatPathUnresolved(expected_what, path) => {
struct_span_err!(resolver.session,
span,
E0419,
E0531,
"unresolved {} `{}`",
expected_what,
path.segments.last().unwrap().identifier)
......@@ -448,7 +447,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
ResolutionError::PatPathUnexpected(expected_what, found_what, path) => {
struct_span_err!(resolver.session,
span,
E0420,
E0532,
"expected {}, found {} `{}`",
expected_what,
found_what,
......@@ -2201,15 +2200,15 @@ fn fresh_binding(&mut self,
pat_id: NodeId,
outer_pat_id: NodeId,
pat_src: PatternSource,
bindings_list: &mut HashMap<Name, NodeId>)
bindings: &mut HashMap<Name, NodeId>)
-> 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
// doesn't already exist in the bindings map. (We
// must not add it if it's in the bindings map
// 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() {
let def = match bindings.get(&renamed).cloned() {
Some(id) if id == outer_pat_id => {
// `Variant(a, a)`, error
resolve_error(
......@@ -2231,8 +2230,9 @@ fn fresh_binding(&mut self,
Def::Err
}
Some(..) if pat_src == PatternSource::Match => {
// `Varian1(a) | Varian2(a)`, ok
Def::Local(self.definitions.local_def_id(pat_id), pat_id)
// `Variant1(a) | Variant2(a)`, ok
// Reuse definition from the first `a`.
self.value_ribs.last_mut().unwrap().bindings[&renamed]
}
Some(..) => {
span_bug!(ident.span, "two bindings with the same name from \
......@@ -2244,7 +2244,7 @@ fn fresh_binding(&mut self,
// define `Invalid` bindings as `Def::Local`, just don't add them to the lists.
let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
if ident.node.name != keywords::Invalid.name() {
bindings_list.insert(renamed, outer_pat_id);
bindings.insert(renamed, outer_pat_id);
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
}
def
......@@ -2255,12 +2255,12 @@ fn fresh_binding(&mut self,
}
fn resolve_pattern_path<ExpectedFn>(&mut self,
pat_id: NodeId,
qself: Option<&QSelf>,
path: &Path,
namespace: Namespace,
expected_fn: ExpectedFn,
expected_what: &'static str)
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,
......@@ -2307,8 +2307,8 @@ fn resolve_pattern(&mut self,
pat_src: PatternSource,
// Maps idents to the node ID for the
// outermost pattern that binds them.
bindings_list: &mut HashMap<Name, NodeId>) {
// Visit all direct subpatterns of this pattern with the same PatternBindingMode.
bindings: &mut HashMap<Name, NodeId>) {
// Visit all direct subpatterns of this pattern.
let outer_pat_id = pat.id;
pat.walk(&mut |pat| {
match pat.node {
......@@ -2340,7 +2340,7 @@ fn resolve_pattern(&mut self,
// These entities are explicitly allowed
// to be shadowed by fresh bindings.
self.fresh_binding(ident, pat.id, outer_pat_id,
pat_src, bindings_list)
pat_src, bindings)
}
def => {
span_bug!(ident.span, "unexpected definition for an \
......@@ -2349,7 +2349,7 @@ fn resolve_pattern(&mut self,
}
} else {
// Fall back to a fresh binding.
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings_list)
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
};
self.record_def(pat.id, resolution);
......
......@@ -151,7 +151,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
// is good enough.
self.demand_suptype(pat.span, expected, const_ty);
}
PatKind::Binding(bm, ref path, ref sub) => {
PatKind::Binding(bm, _, ref sub) => {
let typ = self.local_ty(pat.span, pat.id);
match bm {
hir::BindByRef(mutbl) => {
......@@ -180,7 +180,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
// if there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be
match tcx.def_map.borrow()[&pat.id].full_def() {
match tcx.expect_def(pat.id) {
Def::Err => {}
Def::Local(_, var_id) => {
if var_id != pat.id {
......
......@@ -86,8 +86,8 @@
use middle::cstore::LOCAL_CRATE;
use hir::def::{self, Def};
use hir::def_id::DefId;
use hir::pat_util;
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
use hir::pat_util::{self};
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
use rustc::traits::{self, ProjectionMode};
use rustc::ty::{GenericPredicates, TypeScheme};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册