Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6d7b35bd
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6d7b35bd
编写于
6月 03, 2016
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address review comments + fix rebase
上级
e783a0a5
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
51 addition
and
167 deletion
+51
-167
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+4
-11
src/librustc_mir/hair/cx/pattern.rs
src/librustc_mir/hair/cx/pattern.rs
+1
-1
src/librustc_passes/consts.rs
src/librustc_passes/consts.rs
+2
-1
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/diagnostics.rs
+16
-126
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+25
-25
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+2
-2
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+1
-1
未找到文件。
src/librustc/middle/mem_categorization.rs
浏览文件 @
6d7b35bd
...
...
@@ -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
...
...
src/librustc_mir/hair/cx/pattern.rs
浏览文件 @
6d7b35bd
...
...
@@ -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
),
...
...
src/librustc_passes/consts.rs
浏览文件 @
6d7b35bd
...
...
@@ -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
);
}
}
...
...
src/librustc_resolve/diagnostics.rs
浏览文件 @
6d7b35bd
...
...
@@ -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
}
src/librustc_resolve/lib.rs
浏览文件 @
6d7b35bd
...
...
@@ -155,11 +155,11 @@ enum ResolutionError<'a> {
CannotCaptureDynamicEnvironmentInFnItem
,
/// error E0435: attempt to use a non-constant value in a constant
AttemptToUseNonConstantValueInConstant
,
/// error E0
418
: X bindings cannot shadow Ys
/// error E0
530
: X bindings cannot shadow Ys
BindingShadowsSomethingUnacceptable
(
&
'a
str
,
&
'a
str
,
Name
),
/// error E0
419
: unresolved pattern path kind `name`
/// error E0
531
: unresolved pattern path kind `name`
PatPathUnresolved
(
&
'a
str
,
&
'a
Path
),
/// error E0
420
: expected pattern path kind, found another pattern path kind
/// error E0
532
: 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
,
E0
418
,
E0
530
,
"{}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
,
E0
419
,
E0
531
,
"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
,
E0
420
,
E0
532
,
"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
);
...
...
src/librustc_typeck/check/_match.rs
浏览文件 @
6d7b35bd
...
...
@@ -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
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
6d7b35bd
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录