Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5f3c1412
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,发现更多精彩内容 >>
提交
5f3c1412
编写于
8月 02, 2015
作者:
A
Ariel Ben-Yehuda
提交者:
Ariel Ben-Yehuda
8月 06, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
use VariantDef instead of struct_fields
上级
4816e606
变更
36
展开全部
隐藏空白更改
内联
并排
Showing
36 changed file
with
892 addition
and
1441 deletion
+892
-1441
src/librustc/diagnostics.rs
src/librustc/diagnostics.rs
+0
-59
src/librustc/middle/cast.rs
src/librustc/middle/cast.rs
+2
-3
src/librustc/middle/check_match.rs
src/librustc/middle/check_match.rs
+33
-59
src/librustc/middle/dead.rs
src/librustc/middle/dead.rs
+12
-31
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/expr_use_visitor.rs
+23
-27
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+1
-1
src/librustc/middle/stability.rs
src/librustc/middle/stability.rs
+10
-42
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+11
-30
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+62
-336
src/librustc_borrowck/borrowck/fragments.rs
src/librustc_borrowck/borrowck/fragments.rs
+14
-24
src/librustc_lint/builtin.rs
src/librustc_lint/builtin.rs
+21
-20
src/librustc_privacy/lib.rs
src/librustc_privacy/lib.rs
+51
-96
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/save/dump_csv.rs
+31
-49
src/librustc_trans/save/mod.rs
src/librustc_trans/save/mod.rs
+17
-33
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/_match.rs
+18
-21
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/adt.rs
+14
-16
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+25
-31
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+2
-4
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/common.rs
+87
-4
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/consts.rs
+32
-32
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/debuginfo/metadata.rs
+59
-55
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+57
-135
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/glue.rs
+2
-3
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/inline.rs
+24
-22
src/librustc_trans/trans/monomorphize.rs
src/librustc_trans/trans/monomorphize.rs
+13
-18
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+28
-28
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+5
-4
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/dropck.rs
+31
-50
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/method/suggest.rs
+2
-4
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+78
-120
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+2
-3
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+35
-18
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/diagnostics.rs
+59
-0
src/librustc_typeck/variance.rs
src/librustc_typeck/variance.rs
+5
-37
src/librustdoc/clean/inline.rs
src/librustdoc/clean/inline.rs
+4
-4
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+22
-22
未找到文件。
src/librustc/diagnostics.rs
浏览文件 @
5f3c1412
...
...
@@ -692,64 +692,6 @@ trait Super<A> {
you no longer need to derive from `Super<Self>`.
"####
,
E0079
:
r##"
Enum variants which contain no data can be given a custom integer
representation. This error indicates that the value provided is not an integer
literal and is therefore invalid.
For example, in the following code,
```
enum Foo {
Q = "32"
}
```
we try to set the representation to a string.
There's no general fix for this; if you can work with an integer then just set
it to one:
```
enum Foo {
Q = 32
}
```
however if you actually wanted a mapping between variants and non-integer
objects, it may be preferable to use a method with a match instead:
```
enum Foo { Q }
impl Foo {
fn get_str(&self) -> &'static str {
match *self {
Foo::Q => "32",
}
}
}
```
"##
,
E0080
:
r##"
This error indicates that the compiler was unable to sensibly evaluate an
integer expression provided as an enum discriminant. Attempting to divide by 0
or causing integer overflow are two ways to induce this error. For example:
```
enum Enum {
X = (1 << 500),
Y = (1 / 0)
}
```
Ensure that the expressions given can be evaluated as the desired integer type.
See the FFI section of the Reference for more information about using a custom
integer type:
https://doc.rust-lang.org/reference.html#ffi-attributes
"##
,
E0109
:
r##"
You tried to give a type parameter to a type which doesn't need it. Erroneous
code example:
...
...
@@ -1937,6 +1879,5 @@ fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
E0314
,
// closure outlives stack frame
E0315
,
// cannot invoke closure outside of its lifetime
E0316
,
// nested quantification of lifetimes
E0370
,
// discriminant overflow
E0400
// overloaded derefs are not allowed in constants
}
src/librustc/middle/cast.rs
浏览文件 @
5f3c1412
...
...
@@ -58,15 +58,14 @@ pub enum CastKind {
}
impl
<
'tcx
>
CastTy
<
'tcx
>
{
pub
fn
from_ty
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
t
:
Ty
<
'tcx
>
)
->
Option
<
CastTy
<
'tcx
>>
{
pub
fn
from_ty
(
t
:
Ty
<
'tcx
>
)
->
Option
<
CastTy
<
'tcx
>>
{
match
t
.sty
{
ty
::
TyBool
=>
Some
(
CastTy
::
Int
(
IntTy
::
Bool
)),
ty
::
TyChar
=>
Some
(
CastTy
::
Int
(
IntTy
::
Char
)),
ty
::
TyInt
(
_
)
=>
Some
(
CastTy
::
Int
(
IntTy
::
I
)),
ty
::
TyUint
(
u
)
=>
Some
(
CastTy
::
Int
(
IntTy
::
U
(
u
))),
ty
::
TyFloat
(
_
)
=>
Some
(
CastTy
::
Float
),
ty
::
TyEnum
(
..
)
if
t
.is_c_like_enum
(
tcx
)
=>
ty
::
TyEnum
(
d
,
_
)
if
d
.is_payloadfree
(
)
=>
Some
(
CastTy
::
Int
(
IntTy
::
CEnum
)),
ty
::
TyRawPtr
(
ref
mt
)
=>
Some
(
CastTy
::
Ptr
(
mt
)),
ty
::
TyRef
(
_
,
ref
mt
)
=>
Some
(
CastTy
::
RPtr
(
mt
)),
...
...
src/librustc/middle/check_match.rs
浏览文件 @
5f3c1412
...
...
@@ -237,9 +237,9 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
if
let
ty
::
TyEnum
(
edef
,
_
)
=
pat_ty
.sty
{
let
def
=
cx
.tcx.def_map
.borrow
()
.get
(
&
p
.id
)
.map
(|
d
|
d
.full_def
());
if
let
Some
(
DefLocal
(
_
))
=
def
{
if
cx
.tcx
.enum_variants
(
edef
.did
)
.iter
()
.any
(|
variant
|
if
edef
.variants
.iter
()
.any
(|
variant
|
variant
.name
==
ident
.node.name
&&
variant
.
args
.is_empty
()
&&
variant
.
kind
()
==
VariantKind
::
Unit
)
{
span_warn!
(
cx
.tcx.sess
,
p
.span
,
E0170
,
"pattern binding `{}` is named the same as one
\
...
...
@@ -508,16 +508,10 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
let
pat
=
match
left_ty
.sty
{
ty
::
TyTuple
(
_
)
=>
ast
::
PatTup
(
pats
.collect
()),
ty
::
TyEnum
(
cid
,
_
)
|
ty
::
TyStruct
(
cid
,
_
)
=>
{
let
(
vid
,
is_structure
)
=
match
ctor
{
&
Variant
(
vid
)
=>
(
vid
,
cx
.tcx
.enum_variant_with_id
(
cid
.did
,
vid
)
.arg_names
.is_some
()),
_
=>
(
cid
.did
,
!
cid
.struct_variant
()
.is_tuple_struct
())
};
if
is_structure
{
let
fields
=
cx
.tcx
.lookup_struct_fields
(
vid
);
let
field_pats
:
Vec
<
_
>
=
fields
.into_iter
()
ty
::
TyEnum
(
adt
,
_
)
|
ty
::
TyStruct
(
adt
,
_
)
=>
{
let
v
=
adt
.variant_of_ctor
(
ctor
);
if
let
VariantKind
::
Dict
=
v
.kind
()
{
let
field_pats
:
Vec
<
_
>
=
v
.fields
.iter
()
.zip
(
pats
)
.filter
(|
&
(
_
,
ref
pat
)|
pat
.node
!=
ast
::
PatWild
(
ast
::
PatWildSingle
))
.map
(|(
field
,
pat
)|
Spanned
{
...
...
@@ -529,9 +523,9 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
}
})
.collect
();
let
has_more_fields
=
field_pats
.len
()
<
pats_len
;
ast
::
PatStruct
(
def_to_path
(
cx
.tcx
,
vid
),
field_pats
,
has_more_fields
)
ast
::
PatStruct
(
def_to_path
(
cx
.tcx
,
v
.d
id
),
field_pats
,
has_more_fields
)
}
else
{
ast
::
PatEnum
(
def_to_path
(
cx
.tcx
,
vid
),
Some
(
pats
.collect
()))
ast
::
PatEnum
(
def_to_path
(
cx
.tcx
,
v
.d
id
),
Some
(
pats
.collect
()))
}
}
...
...
@@ -580,6 +574,15 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
})
}
impl
<
'tcx
>
ADTDef
<
'tcx
>
{
fn
variant_of_ctor
(
&
'tcx
self
,
ctor
:
&
Constructor
)
->
&
'tcx
VariantDef
<
'tcx
>
{
match
ctor
{
&
Variant
(
vid
)
=>
self
.variant_with_id
(
vid
),
_
=>
self
.struct_variant
()
}
}
}
fn
missing_constructor
(
cx
:
&
MatchCheckCtxt
,
&
Matrix
(
ref
rows
):
&
Matrix
,
left_ty
:
Ty
,
max_slice_length
:
usize
)
->
Option
<
Constructor
>
{
let
used_constructors
:
Vec
<
Constructor
>
=
rows
.iter
()
...
...
@@ -594,7 +597,7 @@ fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
/// values of type `left_ty`. For vectors, this would normally be an infinite set
/// but is instead bounded by the maximum fixed length of slice patterns in
/// the column of patterns being analyzed.
fn
all_constructors
(
cx
:
&
MatchCheckCtxt
,
left_ty
:
Ty
,
fn
all_constructors
(
_
cx
:
&
MatchCheckCtxt
,
left_ty
:
Ty
,
max_slice_length
:
usize
)
->
Vec
<
Constructor
>
{
match
left_ty
.sty
{
ty
::
TyBool
=>
...
...
@@ -603,17 +606,11 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty,
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
})
=>
match
ty
.sty
{
ty
::
TySlice
(
_
)
=>
range_inclusive
(
0
,
max_slice_length
)
.map
(|
length
|
Slice
(
length
))
.collect
(),
_
=>
vec!
(
Single
)
_
=>
vec!
[
Single
]
},
ty
::
TyEnum
(
edef
,
_
)
=>
cx
.tcx
.enum_variants
(
edef
.did
)
.iter
()
.map
(|
va
|
Variant
(
va
.id
))
.collect
(),
_
=>
vec!
(
Single
)
ty
::
TyEnum
(
def
,
_
)
=>
def
.variants
.iter
()
.map
(|
v
|
Variant
(
v
.did
))
.collect
(),
_
=>
vec!
[
Single
]
}
}
...
...
@@ -804,7 +801,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
///
/// For instance, a tuple pattern (_, 42, Some([])) has the arity of 3.
/// A struct pattern's arity is the number of fields it contains, etc.
pub
fn
constructor_arity
(
cx
:
&
MatchCheckCtxt
,
ctor
:
&
Constructor
,
ty
:
Ty
)
->
usize
{
pub
fn
constructor_arity
(
_
cx
:
&
MatchCheckCtxt
,
ctor
:
&
Constructor
,
ty
:
Ty
)
->
usize
{
match
ty
.sty
{
ty
::
TyTuple
(
ref
fs
)
=>
fs
.len
(),
ty
::
TyBox
(
_
)
=>
1
,
...
...
@@ -817,13 +814,9 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usi
ty
::
TyStr
=>
0
,
_
=>
1
},
ty
::
TyEnum
(
edef
,
_
)
=>
{
match
*
ctor
{
Variant
(
id
)
=>
cx
.tcx
.enum_variant_with_id
(
edef
.did
,
id
)
.args
.len
(),
_
=>
unreachable!
()
}
ty
::
TyEnum
(
adt
,
_
)
|
ty
::
TyStruct
(
adt
,
_
)
=>
{
adt
.variant_of_ctor
(
ctor
)
.fields
.len
()
}
ty
::
TyStruct
(
cdef
,
_
)
=>
cx
.tcx
.lookup_struct_fields
(
cdef
.did
)
.len
(),
ty
::
TyArray
(
_
,
n
)
=>
n
,
_
=>
0
}
...
...
@@ -902,39 +895,20 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
ast
::
PatStruct
(
_
,
ref
pattern_fields
,
_
)
=>
{
// Is this a struct or an enum variant?
let
def
=
cx
.tcx.def_map
.borrow
()
.get
(
&
pat_id
)
.unwrap
()
.full_def
();
let
class_id
=
match
def
{
DefConst
(
..
)
|
DefAssociatedConst
(
..
)
=>
cx
.tcx.sess
.span_bug
(
pat_span
,
"const pattern should've
\
been rewritten"
),
DefVariant
(
_
,
variant_id
,
_
)
=>
if
*
constructor
==
Variant
(
variant_id
)
{
Some
(
variant_id
)
}
else
{
None
},
_
=>
{
// Assume this is a struct.
match
cx
.tcx
.node_id_to_type
(
pat_id
)
.ty_to_def_id
()
{
None
=>
{
cx
.tcx.sess
.span_bug
(
pat_span
,
"struct pattern wasn't of a
\
type with a def ID?!"
)
}
Some
(
def_id
)
=>
Some
(
def_id
),
}
}
};
class_id
.map
(|
variant_id
|
{
let
struct_fields
=
cx
.tcx
.lookup_struct_fields
(
variant_id
);
let
args
=
struct_fields
.iter
()
.map
(|
sf
|
{
let
adt
=
cx
.tcx
.node_id_to_type
(
pat_id
)
.ty_adt_def
()
.unwrap
();
let
variant
=
adt
.variant_of_ctor
(
constructor
);
let
def_variant
=
adt
.variant_of_def
(
def
);
if
variant
.did
==
def_variant
.did
{
Some
(
variant
.fields
.iter
()
.map
(|
sf
|
{
match
pattern_fields
.iter
()
.find
(|
f
|
f
.node.ident.name
==
sf
.name
)
{
Some
(
ref
f
)
=>
&*
f
.node.pat
,
_
=>
DUMMY_WILD_PAT
}
})
.collect
();
args
})
})
.collect
())
}
else
{
None
}
}
ast
::
PatTup
(
ref
args
)
=>
...
...
src/librustc/middle/dead.rs
浏览文件 @
5f3c1412
...
...
@@ -100,51 +100,32 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
}
fn
handle_field_access
(
&
mut
self
,
lhs
:
&
ast
::
Expr
,
name
:
ast
::
Name
)
{
match
self
.tcx
.expr_ty_adjusted
(
lhs
)
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
def
.did
);
let
field_id
=
fields
.iter
()
.find
(|
field
|
field
.name
==
name
)
.unwrap
()
.id
;
self
.live_symbols
.insert
(
field_id
.node
);
},
_
=>
()
if
let
ty
::
TyStruct
(
def
,
_
)
=
self
.tcx
.expr_ty_adjusted
(
lhs
)
.sty
{
self
.live_symbols
.insert
(
def
.struct_variant
()
.field_named
(
name
)
.did.node
);
}
else
{
self
.tcx.sess
.span_bug
(
lhs
.span
,
"named field access on non-struct"
)
}
}
fn
handle_tup_field_access
(
&
mut
self
,
lhs
:
&
ast
::
Expr
,
idx
:
usize
)
{
match
self
.tcx
.expr_ty_adjusted
(
lhs
)
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
def
.did
);
let
field_id
=
fields
[
idx
]
.id
;
self
.live_symbols
.insert
(
field_id
.node
);
},
_
=>
()
if
let
ty
::
TyStruct
(
def
,
_
)
=
self
.tcx
.expr_ty_adjusted
(
lhs
)
.sty
{
self
.live_symbols
.insert
(
def
.struct_variant
()
.fields
[
idx
]
.did.node
);
}
}
fn
handle_field_pattern_match
(
&
mut
self
,
lhs
:
&
ast
::
Pat
,
pats
:
&
[
codemap
::
Spanned
<
ast
::
FieldPat
>
])
{
let
id
=
match
self
.tcx.def_map
.borrow
()
.get
(
&
lhs
.id
)
.unwrap
()
.full_def
()
{
def
::
DefVariant
(
_
,
id
,
_
)
=>
id
,
_
=>
{
match
self
.tcx
.node_id_to_type
(
lhs
.id
)
.ty_to_def_id
()
{
None
=>
{
self
.tcx.sess
.span_bug
(
lhs
.span
,
"struct pattern wasn't of a
\
type with a def ID?!"
)
}
Some
(
def_id
)
=>
def_id
,
}
}
let
def
=
self
.tcx.def_map
.borrow
()
.get
(
&
lhs
.id
)
.unwrap
()
.full_def
();
let
pat_ty
=
self
.tcx
.node_id_to_type
(
lhs
.id
);
let
variant
=
match
pat_ty
.sty
{
ty
::
TyStruct
(
adt
,
_
)
|
ty
::
TyEnum
(
adt
,
_
)
=>
adt
.variant_of_def
(
def
),
_
=>
self
.tcx.sess
.span_bug
(
lhs
.span
,
"non-ADT in struct pattern"
)
};
let
fields
=
self
.tcx
.lookup_struct_fields
(
id
);
for
pat
in
pats
{
if
let
ast
::
PatWild
(
ast
::
PatWildSingle
)
=
pat
.node.pat.node
{
continue
;
}
let
field_id
=
fields
.iter
()
.find
(|
field
|
field
.name
==
pat
.node.ident.name
)
.unwrap
()
.id
;
self
.live_symbols
.insert
(
field_id
.node
);
self
.live_symbols
.insert
(
variant
.field_named
(
pat
.node.ident.name
)
.did.node
);
}
}
...
...
src/librustc/middle/expr_use_visitor.rs
浏览文件 @
5f3c1412
...
...
@@ -694,40 +694,36 @@ fn walk_struct_expr(&mut self,
// Select just those fields of the `with`
// expression that will actually be used
let
with_fields
=
match
with_cmt
.ty.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
{
self
.tcx
()
.struct_fields
(
def
.did
,
substs
)
}
_
=>
{
// the base expression should always evaluate to a
// struct; however, when EUV is run during typeck, it
// may not. This will generate an error earlier in typeck,
// so we can just ignore it.
if
!
self
.tcx
()
.sess
.has_errors
()
{
self
.tcx
()
.sess
.span_bug
(
with_expr
.span
,
"with expression doesn't evaluate to a struct"
);
if
let
ty
::
TyStruct
(
def
,
substs
)
=
with_cmt
.ty.sty
{
// Consume those fields of the with expression that are needed.
for
with_field
in
&
def
.struct_variant
()
.fields
{
if
!
contains_field_named
(
with_field
,
fields
)
{
let
cmt_field
=
self
.mc
.cat_field
(
&*
with_expr
,
with_cmt
.clone
(),
with_field
.name
,
with_field
.ty
(
self
.tcx
(),
substs
)
);
self
.delegate_consume
(
with_expr
.id
,
with_expr
.span
,
cmt_field
);
}
vec!
()
}
};
// Consume those fields of the with expression that are needed.
for
with_field
in
&
with_fields
{
if
!
contains_field_named
(
with_field
,
fields
)
{
let
cmt_field
=
self
.mc
.cat_field
(
&*
with_expr
,
with_cmt
.clone
(),
with_field
.name
,
with_field
.mt.ty
);
self
.delegate_consume
(
with_expr
.id
,
with_expr
.span
,
cmt_field
);
}
else
{
// the base expression should always evaluate to a
// struct; however, when EUV is run during typeck, it
// may not. This will generate an error earlier in typeck,
// so we can just ignore it.
if
!
self
.tcx
()
.sess
.has_errors
()
{
self
.tcx
()
.sess
.span_bug
(
with_expr
.span
,
"with expression doesn't evaluate to a struct"
);
}
}
}
;
// walk the with expression so that complex expressions
// are properly handled.
self
.walk_expr
(
with_expr
);
fn
contains_field_named
(
field
:
&
ty
::
Field
,
fn
contains_field_named
(
field
:
&
ty
::
Field
Def
,
fields
:
&
Vec
<
ast
::
Field
>
)
->
bool
{
...
...
@@ -1105,7 +1101,7 @@ fn walk_pat(&mut self,
Some
(
def
::
DefVariant
(
enum_did
,
variant_did
,
_
is_struct
))
=>
{
let
downcast_cmt
=
if
tcx
.
enum_is_univariant
(
enum_did
)
{
if
tcx
.
lookup_adt_def
(
enum_did
)
.is_univariant
(
)
{
cmt_pat
}
else
{
let
cmt_pat_ty
=
cmt_pat
.ty
;
...
...
src/librustc/middle/mem_categorization.rs
浏览文件 @
5f3c1412
...
...
@@ -1216,7 +1216,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
let
cmt
=
match
opt_def
{
Some
(
def
::
DefVariant
(
enum_did
,
variant_did
,
_
))
// univariant enums do not need downcasts
if
!
self
.tcx
()
.
enum_is_univariant
(
enum_did
)
=>
{
if
!
self
.tcx
()
.
lookup_adt_def
(
enum_did
)
.is_univariant
(
)
=>
{
self
.cat_downcast
(
pat
,
cmt
.clone
(),
cmt
.ty
,
variant_did
)
}
_
=>
cmt
...
...
src/librustc/middle/stability.rs
浏览文件 @
5f3c1412
...
...
@@ -415,16 +415,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
ast
::
ExprField
(
ref
base_e
,
ref
field
)
=>
{
span
=
field
.span
;
match
tcx
.expr_ty_adjusted
(
base_e
)
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
tcx
.lookup_struct_fields
(
def
.did
)
.iter
()
.find
(|
f
|
f
.name
==
field
.node.name
)
.unwrap_or_else
(||
{
tcx
.sess
.span_bug
(
field
.span
,
"stability::check_expr: unknown named field access"
)
})
.id
}
ty
::
TyStruct
(
def
,
_
)
=>
def
.struct_variant
()
.field_named
(
field
.node.name
)
.did
,
_
=>
tcx
.sess
.span_bug
(
e
.span
,
"stability::check_expr: named field access on non-struct"
)
}
...
...
@@ -432,15 +423,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
ast
::
ExprTupField
(
ref
base_e
,
ref
field
)
=>
{
span
=
field
.span
;
match
tcx
.expr_ty_adjusted
(
base_e
)
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
tcx
.lookup_struct_fields
(
def
.did
)
.get
(
field
.node
)
.unwrap_or_else
(||
{
tcx
.sess
.span_bug
(
field
.span
,
"stability::check_expr: unknown unnamed field access"
)
})
.id
}
ty
::
TyStruct
(
def
,
_
)
=>
def
.struct_variant
()
.fields
[
field
.node
]
.did
,
ty
::
TyTuple
(
..
)
=>
return
,
_
=>
tcx
.sess
.span_bug
(
e
.span
,
"stability::check_expr: unnamed field access on
\
...
...
@@ -451,19 +434,12 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
let
type_
=
tcx
.expr_ty
(
e
);
match
type_
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
let
struct_fields
=
tcx
.lookup_struct_fields
(
def
.did
);
// check the stability of each field that appears
// in the construction expression.
for
field
in
expr_fields
{
let
did
=
struct_fields
.iter
()
.find
(|
f
|
f
.name
==
field
.ident.node.name
)
.unwrap_or_else
(||
{
tcx
.sess
.span_bug
(
field
.span
,
"stability::check_expr: unknown named
\
field access"
)
})
.id
;
let
did
=
def
.struct_variant
()
.field_named
(
field
.ident.node.name
)
.did
;
maybe_do_stability_check
(
tcx
,
did
,
field
.span
,
cb
);
}
...
...
@@ -505,34 +481,26 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
debug!
(
"check_pat(pat = {:?})"
,
pat
);
if
is_internal
(
tcx
,
pat
.span
)
{
return
;
}
let
def
=
match
tcx
.pat_ty_opt
(
pat
)
{
Some
(
&
ty
::
TyS
{
sty
:
ty
::
TyStruct
(
def
,
_
),
..
})
=>
def
,
let
v
=
match
tcx
.pat_ty_opt
(
pat
)
{
Some
(
&
ty
::
TyS
{
sty
:
ty
::
TyStruct
(
def
,
_
),
..
})
=>
def
.struct_variant
()
,
Some
(
_
)
|
None
=>
return
,
};
let
struct_fields
=
tcx
.lookup_struct_fields
(
def
.did
);
match
pat
.node
{
// Foo(a, b, c)
ast
::
PatEnum
(
_
,
Some
(
ref
pat_fields
))
=>
{
for
(
field
,
struct_field
)
in
pat_fields
.iter
()
.zip
(
&
struct_
fields
)
{
for
(
field
,
struct_field
)
in
pat_fields
.iter
()
.zip
(
&
v
.
fields
)
{
// a .. pattern is fine, but anything positional is
// not.
if
let
ast
::
PatWild
(
ast
::
PatWildMulti
)
=
field
.node
{
continue
}
maybe_do_stability_check
(
tcx
,
struct_field
.id
,
field
.span
,
cb
)
maybe_do_stability_check
(
tcx
,
struct_field
.
d
id
,
field
.span
,
cb
)
}
}
// Foo { a, b, c }
ast
::
PatStruct
(
_
,
ref
pat_fields
,
_
)
=>
{
for
field
in
pat_fields
{
let
did
=
struct_fields
.iter
()
.find
(|
f
|
f
.name
==
field
.node.ident.name
)
.unwrap_or_else
(||
{
tcx
.sess
.span_bug
(
field
.span
,
"stability::check_pat: unknown named field access"
)
})
.id
;
let
did
=
v
.field_named
(
field
.node.ident.name
)
.did
;
maybe_do_stability_check
(
tcx
,
did
,
field
.span
,
cb
);
}
}
...
...
src/librustc/middle/traits/select.rs
浏览文件 @
5f3c1412
...
...
@@ -1721,21 +1721,10 @@ fn builtin_bound(&mut self,
ok_if
(
substs
.upvar_tys
.clone
())
}
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
types
:
Vec
<
Ty
>
=
self
.tcx
()
.struct_fields
(
def
.did
,
substs
)
.iter
()
.map
(|
f
|
f
.mt.ty
)
.collect
();
nominal
(
bound
,
types
)
}
ty
::
TyEnum
(
def
,
substs
)
=>
{
let
types
:
Vec
<
Ty
>
=
self
.tcx
()
.substd_enum_variants
(
def
.did
,
substs
)
.iter
()
.flat_map
(|
variant
|
&
variant
.args
)
.cloned
()
.collect
();
ty
::
TyStruct
(
def
,
substs
)
|
ty
::
TyEnum
(
def
,
substs
)
=>
{
let
types
:
Vec
<
Ty
>
=
def
.all_fields
()
.map
(|
f
|
{
f
.ty
(
self
.tcx
(),
substs
)
})
.collect
();
nominal
(
bound
,
types
)
}
...
...
@@ -1865,18 +1854,9 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
substs
.types
.get_slice
(
TypeSpace
)
.to_vec
()
}
ty
::
TyStruct
(
def
,
substs
)
=>
{
self
.tcx
()
.struct_fields
(
def
.did
,
substs
)
.iter
()
.map
(|
f
|
f
.mt.ty
)
.collect
()
}
ty
::
TyEnum
(
def
,
substs
)
=>
{
self
.tcx
()
.substd_enum_variants
(
def
.did
,
substs
)
.iter
()
.flat_map
(|
variant
|
&
variant
.args
)
.map
(|
&
ty
|
ty
)
ty
::
TyStruct
(
def
,
substs
)
|
ty
::
TyEnum
(
def
,
substs
)
=>
{
def
.all_fields
()
.map
(|
f
|
f
.ty
(
self
.tcx
(),
substs
))
.collect
()
}
}
...
...
@@ -2522,9 +2502,10 @@ fn confirm_builtin_unsize_candidate(&mut self,
// Struct<T> -> Struct<U>.
(
&
ty
::
TyStruct
(
def
,
substs_a
),
&
ty
::
TyStruct
(
_
,
substs_b
))
=>
{
let
fields
=
tcx
.lookup_struct_fields
(
def
.did
)
.iter
()
.map
(|
f
|
{
tcx
.lookup_field_type_unsubstituted
(
def
.did
,
f
.id
)
})
.collect
::
<
Vec
<
_
>>
();
let
fields
=
def
.all_fields
()
.map
(|
f
|
f
.unsubst_ty
())
.collect
::
<
Vec
<
_
>>
();
// The last field of the structure has to exist and contain type parameters.
let
field
=
if
let
Some
(
&
field
)
=
fields
.last
()
{
...
...
src/librustc/middle/ty.rs
浏览文件 @
5f3c1412
此差异已折叠。
点击以展开。
src/librustc_borrowck/borrowck/fragments.rs
浏览文件 @
5f3c1412
...
...
@@ -438,11 +438,10 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
}
}
(
&
ty
::
TyStruct
(
def
,
ref
_
substs
),
None
)
=>
{
let
fields
=
tcx
.lookup_struct_fields
(
def
.did
);
(
&
ty
::
TyStruct
(
def
,
_
),
None
)
=>
{
match
*
origin_field_name
{
mc
::
NamedField
(
ast_name
)
=>
{
for
f
in
&
fields
{
for
f
in
&
def
.struct_variant
()
.
fields
{
if
f
.name
==
ast_name
{
continue
;
}
...
...
@@ -451,7 +450,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
}
}
mc
::
PositionalField
(
tuple_idx
)
=>
{
for
(
i
,
_
f
)
in
fields
.iter
()
.enumerate
()
{
for
(
i
,
_
f
)
in
def
.struct_variant
()
.
fields
.iter
()
.enumerate
()
{
if
i
==
tuple_idx
{
continue
}
...
...
@@ -462,35 +461,26 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
}
}
(
&
ty
::
TyEnum
(
enum_def
,
substs
),
ref
enum_variant_info
)
=>
{
let
variant_info
=
{
let
mut
variants
=
tcx
.substd_enum_variants
(
enum_def
.did
,
substs
);
match
*
enum_variant_info
{
Some
((
variant_def_id
,
ref
_
lp2
))
=>
variants
.iter
()
.find
(|
variant
|
variant
.id
==
variant_def_id
)
.expect
(
"enum_variant_with_id(): no variant exists with that ID"
)
.clone
(),
None
=>
{
assert_eq!
(
variants
.len
(),
1
);
variants
.pop
()
.unwrap
()
}
(
&
ty
::
TyEnum
(
def
,
_
),
ref
enum_variant_info
)
=>
{
let
variant
=
match
*
enum_variant_info
{
Some
((
vid
,
ref
_
lp2
))
=>
def
.variant_with_id
(
vid
),
None
=>
{
assert
!
(
def
.is_univariant
());
&
def
.variants
[
0
]
}
};
match
*
origin_field_name
{
mc
::
NamedField
(
ast_name
)
=>
{
let
variant_arg_names
=
variant_info
.arg_names
.as_ref
()
.unwrap
();
for
&
variant_arg_name
in
variant_arg_names
{
if
variant_arg_name
==
ast_name
{
for
field
in
&
variant
.fields
{
if
field
.name
==
ast_name
{
continue
;
}
let
field_name
=
mc
::
NamedField
(
variant_arg_
name
);
add_fragment_sibling_local
(
field_name
,
Some
(
variant
_info
.
id
));
let
field_name
=
mc
::
NamedField
(
field
.
name
);
add_fragment_sibling_local
(
field_name
,
Some
(
variant
.d
id
));
}
}
mc
::
PositionalField
(
tuple_idx
)
=>
{
let
variant_arg_types
=
&
variant_info
.args
;
for
(
i
,
_
variant_arg_ty
)
in
variant_arg_types
.iter
()
.enumerate
()
{
for
(
i
,
_
f
)
in
variant
.fields
.iter
()
.enumerate
()
{
if
tuple_idx
==
i
{
continue
;
}
...
...
src/librustc_lint/builtin.rs
浏览文件 @
5f3c1412
...
...
@@ -45,7 +45,6 @@
use
std
::
collections
::
hash_map
::
Entry
::{
Occupied
,
Vacant
};
use
std
::{
cmp
,
slice
};
use
std
::{
i8
,
i16
,
i32
,
i64
,
u8
,
u16
,
u32
,
u64
,
f32
,
f64
};
use
std
::
rc
::
Rc
;
use
syntax
::{
abi
,
ast
};
use
syntax
::
ast_util
::{
self
,
is_shift_binop
,
local_def
};
...
...
@@ -413,18 +412,23 @@ enum FfiResult {
/// to function pointers and references, but could be
/// expanded to cover NonZero raw pointers and newtypes.
/// FIXME: This duplicates code in trans.
fn
is_repr_nullable_ptr
<
'tcx
>
(
variants
:
&
Vec
<
Rc
<
ty
::
VariantInfo
<
'tcx
>>>
)
->
bool
{
if
variants
.len
()
==
2
{
let
mut
data_idx
=
0
;
if
variants
[
0
]
.args
.is_empty
()
{
fn
is_repr_nullable_ptr
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
def
:
&
ty
::
ADTDef
<
'tcx
>
,
substs
:
&
Substs
<
'tcx
>
)
->
bool
{
if
def
.variants
.len
()
==
2
{
let
data_idx
;
if
def
.variants
[
0
]
.fields
.is_empty
()
{
data_idx
=
1
;
}
else
if
!
variants
[
1
]
.args
.is_empty
()
{
}
else
if
def
.variants
[
1
]
.fields
.is_empty
()
{
data_idx
=
0
;
}
else
{
return
false
;
}
if
variants
[
data_idx
]
.arg
s
.len
()
==
1
{
match
variants
[
data_idx
]
.args
[
0
]
.sty
{
if
def
.variants
[
data_idx
]
.field
s
.len
()
==
1
{
match
def
.variants
[
data_idx
]
.fields
[
0
]
.ty
(
tcx
,
substs
)
.sty
{
ty
::
TyBareFn
(
None
,
_
)
=>
{
return
true
;
}
ty
::
TyRef
(
..
)
=>
{
return
true
;
}
_
=>
{
}
...
...
@@ -474,16 +478,14 @@ fn check_type_for_ffi(&self,
// We can't completely trust repr(C) markings; make sure the
// fields are actually safe.
let
fields
=
cx
.struct_fields
(
def
.did
,
substs
);
if
fields
.is_empty
()
{
if
def
.struct_variant
()
.fields
.is_empty
()
{
return
FfiUnsafe
(
"found zero-size struct in foreign module, consider
\
adding a member to this struct"
);
}
for
field
in
fields
{
let
field_ty
=
infer
::
normalize_associated_type
(
cx
,
&
field
.
mt.ty
);
for
field
in
&
def
.struct_variant
()
.
fields
{
let
field_ty
=
infer
::
normalize_associated_type
(
cx
,
&
field
.
ty
(
cx
,
substs
)
);
let
r
=
self
.check_type_for_ffi
(
cache
,
field_ty
);
match
r
{
FfiSafe
=>
{}
...
...
@@ -494,8 +496,7 @@ fn check_type_for_ffi(&self,
FfiSafe
}
ty
::
TyEnum
(
def
,
substs
)
=>
{
let
variants
=
cx
.substd_enum_variants
(
def
.did
,
substs
);
if
variants
.is_empty
()
{
if
def
.variants
.is_empty
()
{
// Empty enums are okay... although sort of useless.
return
FfiSafe
}
...
...
@@ -506,7 +507,7 @@ fn check_type_for_ffi(&self,
match
&**
repr_hints
{
[]
=>
{
// Special-case types like `Option<extern fn()>`.
if
!
is_repr_nullable_ptr
(
&
varian
ts
)
{
if
!
is_repr_nullable_ptr
(
cx
,
def
,
subs
ts
)
{
return
FfiUnsafe
(
"found enum without foreign-function-safe
\
representation annotation in foreign module,
\
...
...
@@ -537,9 +538,9 @@ fn check_type_for_ffi(&self,
}
// Check the contained variants.
for
variant
in
variants
{
for
arg
in
&
variant
.arg
s
{
let
arg
=
infer
::
normalize_associated_type
(
cx
,
arg
);
for
variant
in
&
def
.
variants
{
for
field
in
&
variant
.field
s
{
let
arg
=
infer
::
normalize_associated_type
(
cx
,
&
field
.ty
(
cx
,
substs
)
);
let
r
=
self
.check_type_for_ffi
(
cache
,
arg
);
match
r
{
FfiSafe
=>
{}
...
...
src/librustc_privacy/lib.rs
浏览文件 @
5f3c1412
...
...
@@ -34,7 +34,6 @@
use
std
::
mem
::
replace
;
use
rustc
::
ast_map
;
use
rustc
::
metadata
::
csearch
;
use
rustc
::
middle
::
def
;
use
rustc
::
middle
::
privacy
::
ImportUse
::
*
;
use
rustc
::
middle
::
privacy
::
LastPrivate
::
*
;
...
...
@@ -688,29 +687,26 @@ fn ensure_public(&self, span: Span, to_check: ast::DefId,
// Checks that a field is in scope.
fn
check_field
(
&
mut
self
,
span
:
Span
,
id
:
ast
::
DefId
,
def
:
&
'tcx
ty
::
ADTDef
<
'tcx
>
,
v
:
&
'tcx
ty
::
VariantDef
<
'tcx
>
,
name
:
FieldName
)
{
// TODO: refactor to variant API
let
fields
=
self
.tcx
.lookup_struct_fields
(
id
);
let
field
=
match
name
{
NamedField
(
f_name
)
=>
{
debug!
(
"privacy - check named field {} in struct {:?}"
,
f_name
,
id
);
fields
.iter
()
.find
(|
f
|
f
.name
==
f_name
)
.unwrap
(
)
debug!
(
"privacy - check named field {} in struct {:?}"
,
f_name
,
def
);
v
.field_named
(
f_name
)
}
UnnamedField
(
idx
)
=>
&
fields
[
idx
]
UnnamedField
(
idx
)
=>
&
v
.
fields
[
idx
]
};
if
field
.vis
==
ast
::
Public
||
(
is_local
(
field
.
id
)
&&
self
.private_accessible
(
field
.
id.node
))
{
(
is_local
(
field
.
did
)
&&
self
.private_accessible
(
field
.d
id.node
))
{
return
}
let
struct_type
=
self
.tcx
.lookup_item_type
(
id
)
.ty
;
let
struct_desc
=
match
struct_type
.sty
{
ty
::
TyStruct
(
_
,
_
)
=>
format!
(
"struct `{}`"
,
self
.tcx
.item_path_str
(
id
)),
let
struct_desc
=
match
def
.adt_kind
()
{
ty
::
ADTKind
::
Struct
=>
format!
(
"struct `{}`"
,
self
.tcx
.item_path_str
(
def
.did
)),
// struct variant fields have inherited visibility
ty
::
TyEnum
(
..
)
=>
return
,
_
=>
self
.tcx.sess
.span_bug
(
span
,
"can't find struct for field"
)
ty
::
ADTKind
::
Enum
=>
return
};
let
msg
=
match
name
{
NamedField
(
name
)
=>
format!
(
"field `{}` of {} is private"
,
...
...
@@ -885,12 +881,18 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
match
expr
.node
{
ast
::
ExprField
(
ref
base
,
ident
)
=>
{
if
let
ty
::
TyStruct
(
def
,
_
)
=
self
.tcx
.expr_ty_adjusted
(
&**
base
)
.sty
{
self
.check_field
(
expr
.span
,
def
.did
,
NamedField
(
ident
.node.name
));
self
.check_field
(
expr
.span
,
def
,
def
.struct_variant
(),
NamedField
(
ident
.node.name
));
}
}
ast
::
ExprTupField
(
ref
base
,
idx
)
=>
{
if
let
ty
::
TyStruct
(
def
,
_
)
=
self
.tcx
.expr_ty_adjusted
(
&**
base
)
.sty
{
self
.check_field
(
expr
.span
,
def
.did
,
UnnamedField
(
idx
.node
));
self
.check_field
(
expr
.span
,
def
,
def
.struct_variant
(),
UnnamedField
(
idx
.node
));
}
}
ast
::
ExprMethodCall
(
ident
,
_
,
_
)
=>
{
...
...
@@ -899,67 +901,36 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
debug!
(
"(privacy checking) checking impl method"
);
self
.check_method
(
expr
.span
,
method
.def_id
,
ident
.node.name
);
}
ast
::
ExprStruct
(
_
,
ref
fields
,
_
)
=>
{
match
self
.tcx
.expr_ty
(
expr
)
.sty
{
ty
::
TyStruct
(
ctor_def
,
_
)
=>
{
// RFC 736: ensure all unmentioned fields are visible.
// Rather than computing the set of unmentioned fields
// (i.e. `all_fields - fields`), just check them all.
let
all_fields
=
self
.tcx
.lookup_struct_fields
(
ctor_def
.did
);
for
field
in
all_fields
{
self
.check_field
(
expr
.span
,
ctor_def
.did
,
NamedField
(
field
.name
));
}
}
ty
::
TyEnum
(
_
,
_
)
=>
{
match
self
.tcx.def_map
.borrow
()
.get
(
&
expr
.id
)
.unwrap
()
.full_def
()
{
def
::
DefVariant
(
_
,
variant_id
,
_
)
=>
{
for
field
in
fields
{
self
.check_field
(
expr
.span
,
variant_id
,
NamedField
(
field
.ident.node.name
));
}
}
_
=>
self
.tcx.sess
.span_bug
(
expr
.span
,
"resolve didn't
\
map enum struct
\
constructor to a
\
variant def"
),
}
}
_
=>
self
.tcx.sess
.span_bug
(
expr
.span
,
"struct expr
\
didn't have
\
struct type?!"
),
ast
::
ExprStruct
(
..
)
=>
{
let
adt
=
self
.tcx
.expr_ty
(
expr
)
.ty_adt_def
()
.unwrap
();
let
variant
=
adt
.variant_of_def
(
self
.tcx
.resolve_expr
(
expr
));
// RFC 736: ensure all unmentioned fields are visible.
// Rather than computing the set of unmentioned fields
// (i.e. `all_fields - fields`), just check them all.
for
field
in
&
variant
.fields
{
self
.check_field
(
expr
.span
,
adt
,
variant
,
NamedField
(
field
.name
));
}
}
ast
::
ExprPath
(
..
)
=>
{
let
guard
=
|
did
:
ast
::
DefId
|
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
did
);
let
any_priv
=
fields
.iter
()
.any
(|
f
|
{
if
let
def
::
DefStruct
(
_
)
=
self
.tcx
.resolve_expr
(
expr
)
{
let
expr_ty
=
self
.tcx
.expr_ty
(
expr
);
let
def
=
match
expr_ty
.sty
{
ty
::
TyBareFn
(
_
,
&
ty
::
BareFnTy
{
sig
:
ty
::
Binder
(
ty
::
FnSig
{
output
:
ty
::
FnConverging
(
ty
),
..
}),
..
})
=>
ty
,
_
=>
expr_ty
}
.ty_adt_def
()
.unwrap
();
let
any_priv
=
def
.struct_variant
()
.fields
.iter
()
.any
(|
f
|
{
f
.vis
!=
ast
::
Public
&&
(
!
is_local
(
f
.id
)
||
!
self
.private_accessible
(
f
.
id.node
))
});
!
is_local
(
f
.
d
id
)
||
!
self
.private_accessible
(
f
.d
id.node
))
});
if
any_priv
{
self
.tcx.sess
.span_err
(
expr
.span
,
"cannot invoke tuple struct constructor
\
with private fields"
);
}
};
match
self
.tcx.def_map
.borrow
()
.get
(
&
expr
.id
)
.map
(|
d
|
d
.full_def
())
{
Some
(
def
::
DefStruct
(
did
))
=>
{
guard
(
if
is_local
(
did
)
{
local_def
(
self
.tcx.map
.get_parent
(
did
.node
))
}
else
{
// "tuple structs" with zero fields (such as
// `pub struct Foo;`) don't have a ctor_id, hence
// the unwrap_or to the same struct id.
let
maybe_did
=
csearch
::
get_tuple_struct_definition_if_ctor
(
&
self
.tcx.sess.cstore
,
did
);
maybe_did
.unwrap_or
(
did
)
})
"cannot invoke tuple struct constructor
\
with private fields"
);
}
_
=>
{}
}
}
_
=>
{}
...
...
@@ -977,31 +948,12 @@ fn visit_pat(&mut self, pattern: &ast::Pat) {
match
pattern
.node
{
ast
::
PatStruct
(
_
,
ref
fields
,
_
)
=>
{
match
self
.tcx
.pat_ty
(
pattern
)
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
for
field
in
fields
{
self
.check_field
(
pattern
.span
,
def
.did
,
NamedField
(
field
.node.ident.name
));
}
}
ty
::
TyEnum
(
_
,
_
)
=>
{
match
self
.tcx.def_map
.borrow
()
.get
(
&
pattern
.id
)
.map
(|
d
|
d
.full_def
())
{
Some
(
def
::
DefVariant
(
_
,
variant_id
,
_
))
=>
{
for
field
in
fields
{
self
.check_field
(
pattern
.span
,
variant_id
,
NamedField
(
field
.node.ident.name
));
}
}
_
=>
self
.tcx.sess
.span_bug
(
pattern
.span
,
"resolve didn't
\
map enum struct
\
pattern to a
\
variant def"
),
}
}
_
=>
self
.tcx.sess
.span_bug
(
pattern
.span
,
"struct pattern didn't have
\
struct type?!"
),
let
adt
=
self
.tcx
.pat_ty
(
pattern
)
.ty_adt_def
()
.unwrap
();
let
def
=
self
.tcx.def_map
.borrow
()
.get
(
&
pattern
.id
)
.unwrap
()
.full_def
();
let
variant
=
adt
.variant_of_def
(
def
);
for
field
in
fields
{
self
.check_field
(
pattern
.span
,
adt
,
variant
,
NamedField
(
field
.node.ident.name
));
}
}
...
...
@@ -1014,7 +966,10 @@ struct type?!"),
if
let
ast
::
PatWild
(
..
)
=
field
.node
{
continue
}
self
.check_field
(
field
.span
,
def
.did
,
UnnamedField
(
i
));
self
.check_field
(
field
.span
,
def
,
def
.struct_variant
(),
UnnamedField
(
i
));
}
}
ty
::
TyEnum
(
..
)
=>
{
...
...
src/librustc_trans/save/dump_csv.rs
浏览文件 @
5f3c1412
...
...
@@ -742,6 +742,7 @@ fn process_struct_lit(&mut self,
ex
:
&
ast
::
Expr
,
path
:
&
ast
::
Path
,
fields
:
&
Vec
<
ast
::
Field
>
,
variant
:
&
ty
::
VariantDef
,
base
:
&
Option
<
P
<
ast
::
Expr
>>
)
{
if
generated_code
(
path
.span
)
{
return
...
...
@@ -756,7 +757,6 @@ fn process_struct_lit(&mut self,
Some
(
struct_lit_data
.span
),
struct_lit_data
.ref_id
,
struct_lit_data
.scope
);
let
struct_def
=
struct_lit_data
.ref_id
;
let
scope
=
self
.save_ctxt
.enclosing_scope
(
ex
.id
);
for
field
in
fields
{
...
...
@@ -765,7 +765,7 @@ fn process_struct_lit(&mut self,
}
let
field_data
=
self
.save_ctxt
.get_field_ref_data
(
field
,
struct_def
,
variant
,
scope
);
self
.fmt
.ref_str
(
recorder
::
VarRef
,
field
.ident.span
,
...
...
@@ -804,43 +804,24 @@ fn process_pat(&mut self, p:&ast::Pat) {
match
p
.node
{
ast
::
PatStruct
(
ref
path
,
ref
fields
,
_
)
=>
{
visit
::
walk_path
(
self
,
path
);
let
adt
=
self
.tcx
.node_id_to_type
(
p
.id
)
.ty_adt_def
()
.unwrap
();
let
def
=
self
.tcx.def_map
.borrow
()[
&
p
.id
]
.full_def
();
let
variant
=
adt
.variant_of_def
(
def
);
let
def
=
self
.tcx.def_map
.borrow
()
.get
(
&
p
.id
)
.unwrap
()
.full_def
();
let
struct_def
=
match
def
{
def
::
DefConst
(
..
)
|
def
::
DefAssociatedConst
(
..
)
=>
None
,
def
::
DefVariant
(
_
,
variant_id
,
_
)
=>
Some
(
variant_id
),
_
=>
{
match
self
.tcx
.node_id_to_type
(
p
.id
)
.ty_to_def_id
()
{
None
=>
{
self
.sess
.span_bug
(
p
.span
,
&
format!
(
"Could not find struct_def for `{}`"
,
self
.span
.snippet
(
p
.span
)));
}
Some
(
def_id
)
=>
Some
(
def_id
),
}
for
&
Spanned
{
node
:
ref
field
,
span
}
in
fields
{
if
generated_code
(
span
)
{
continue
;
}
};
if
let
Some
(
struct_def
)
=
struct_def
{
let
struct_fields
=
self
.tcx
.lookup_struct_fields
(
struct_def
);
for
&
Spanned
{
node
:
ref
field
,
span
}
in
fields
{
if
generated_code
(
span
)
{
continue
;
}
let
sub_span
=
self
.span
.span_for_first_ident
(
span
);
for
f
in
&
struct_fields
{
if
f
.name
==
field
.ident.name
{
self
.fmt
.ref_str
(
recorder
::
VarRef
,
span
,
sub_span
,
f
.id
,
self
.cur_scope
);
break
;
}
}
self
.visit_pat
(
&
field
.pat
);
let
sub_span
=
self
.span
.span_for_first_ident
(
span
);
if
let
Some
(
f
)
=
variant
.find_field_named
(
field
.ident.name
)
{
self
.fmt
.ref_str
(
recorder
::
VarRef
,
span
,
sub_span
,
f
.did
,
self
.cur_scope
);
}
self
.visit_pat
(
&
field
.pat
);
}
}
_
=>
visit
::
walk_pat
(
self
,
p
)
...
...
@@ -1091,8 +1072,15 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
self
.process_path
(
ex
.id
,
path
,
None
);
visit
::
walk_expr
(
self
,
ex
);
}
ast
::
ExprStruct
(
ref
path
,
ref
fields
,
ref
base
)
=>
self
.process_struct_lit
(
ex
,
path
,
fields
,
base
),
ast
::
ExprStruct
(
ref
path
,
ref
fields
,
ref
base
)
=>
{
let
adt
=
self
.tcx
.expr_ty
(
ex
)
.ty_adt_def
()
.unwrap
();
let
def
=
self
.tcx
.resolve_expr
(
ex
);
self
.process_struct_lit
(
ex
,
path
,
fields
,
adt
.variant_of_def
(
def
),
base
)
}
ast
::
ExprMethodCall
(
_
,
_
,
ref
args
)
=>
self
.process_method_call
(
ex
,
args
),
ast
::
ExprField
(
ref
sub_ex
,
_
)
=>
{
if
generated_code
(
sub_ex
.span
)
{
...
...
@@ -1120,18 +1108,12 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
let
ty
=
&
self
.tcx
.expr_ty_adjusted
(
&**
sub_ex
)
.sty
;
match
*
ty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
def
.did
);
for
(
i
,
f
)
in
fields
.iter
()
.enumerate
()
{
if
i
==
idx
.node
{
let
sub_span
=
self
.span
.sub_span_after_token
(
ex
.span
,
token
::
Dot
);
self
.fmt
.ref_str
(
recorder
::
VarRef
,
ex
.span
,
sub_span
,
f
.id
,
self
.cur_scope
);
break
;
}
}
let
sub_span
=
self
.span
.sub_span_after_token
(
ex
.span
,
token
::
Dot
);
self
.fmt
.ref_str
(
recorder
::
VarRef
,
ex
.span
,
sub_span
,
def
.struct_variant
()
.fields
[
idx
.node
]
.did
,
self
.cur_scope
);
}
ty
::
TyTuple
(
_
)
=>
{}
_
=>
self
.sess
.span_bug
(
ex
.span
,
...
...
src/librustc_trans/save/mod.rs
浏览文件 @
5f3c1412
...
...
@@ -448,22 +448,14 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
let
ty
=
&
self
.tcx
.expr_ty_adjusted
(
&
sub_ex
)
.sty
;
match
*
ty
{
ty
::
TyStruct
(
def
,
_
)
=>
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
def
.did
);
for
f
in
&
fields
{
if
f
.name
==
ident
.node.name
{
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
expr
.span
);
return
Some
(
Data
::
VariableRefData
(
VariableRefData
{
name
:
ident
.node
.to_string
(),
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
expr
.id
),
ref_id
:
f
.id
,
}));
}
}
self
.tcx.sess
.span_bug
(
expr
.span
,
&
format!
(
"Couldn't find field {} on {:?}"
,
ident
.node
,
ty
))
let
f
=
def
.struct_variant
()
.field_named
(
ident
.node.name
);
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
expr
.span
);
return
Some
(
Data
::
VariableRefData
(
VariableRefData
{
name
:
ident
.node
.to_string
(),
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
expr
.id
),
ref_id
:
f
.did
,
}));
}
_
=>
{
debug!
(
"Expected struct type, found {:?}"
,
ty
);
...
...
@@ -621,26 +613,18 @@ fn trait_method_has_body(&self, mr: &ty::ImplOrTraitItem) -> bool {
pub
fn
get_field_ref_data
(
&
self
,
field_ref
:
&
ast
::
Field
,
struct_id
:
DefId
,
variant
:
&
ty
::
VariantDef
,
parent
:
NodeId
)
->
VariableRefData
{
let
fields
=
self
.tcx
.lookup_struct_fields
(
struct_id
);
let
field_name
=
field_ref
.ident.node
.to_string
();
for
f
in
&
fields
{
if
f
.name
==
field_ref
.ident.node.name
{
// We don't really need a sub-span here, but no harm done
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
field_ref
.ident.span
);
return
VariableRefData
{
name
:
field_name
,
span
:
sub_span
.unwrap
(),
scope
:
parent
,
ref_id
:
f
.id
,
};
}
let
f
=
variant
.field_named
(
field_ref
.ident.node.name
);
// We don't really need a sub-span here, but no harm done
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
field_ref
.ident.span
);
VariableRefData
{
name
:
field_ref
.ident.node
.to_string
(),
span
:
sub_span
.unwrap
(),
scope
:
parent
,
ref_id
:
f
.did
,
}
self
.tcx.sess
.span_bug
(
field_ref
.span
,
&
format!
(
"Couldn't find field {}"
,
field_name
));
}
pub
fn
get_data_for_id
(
&
self
,
_
id
:
&
NodeId
)
->
Data
{
...
...
src/librustc_trans/trans/_match.rs
浏览文件 @
5f3c1412
...
...
@@ -656,7 +656,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
opt_def
=
tcx
.def_map
.borrow
()
.get
(
&
cur
.id
)
.map
(|
d
|
d
.full_def
());
match
opt_def
{
Some
(
def
::
DefVariant
(
enum_id
,
var_id
,
_
))
=>
{
let
variant
=
tcx
.
enum_variant_with_id
(
enum_id
,
var_id
);
let
variant
=
tcx
.
lookup_adt_def
(
enum_id
)
.variant_with_id
(
var_id
);
Variant
(
variant
.disr_val
,
adt
::
represent_node
(
bcx
,
cur
.id
),
var_id
,
...
...
@@ -1190,10 +1190,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
// The last field is technically unsized but
// since we can only ever match that field behind
// a reference we construct a fat ptr here.
let
fields
=
bcx
.tcx
()
.lookup_struct_fields
(
def
.did
);
let
unsized_ty
=
fields
.iter
()
.last
()
.map
(|
field
|
{
let
fty
=
bcx
.tcx
()
.lookup_field_type
(
def
.did
,
field
.id
,
substs
);
monomorphize
::
normalize_associated_type
(
bcx
.tcx
(),
&
fty
)
let
unsized_ty
=
def
.struct_variant
()
.fields
.last
()
.map
(|
field
|
{
monomorphize
::
field_ty
(
bcx
.tcx
(),
substs
,
field
)
})
.unwrap
();
let
llty
=
type_of
::
type_of
(
bcx
.ccx
(),
unsized_ty
);
let
scratch
=
alloca_no_lifetime
(
bcx
,
llty
,
"__struct_field_fat_ptr"
);
...
...
@@ -1833,7 +1831,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match
opt_def
{
Some
(
def
::
DefVariant
(
enum_id
,
var_id
,
_
))
=>
{
let
repr
=
adt
::
represent_node
(
bcx
,
pat
.id
);
let
vinfo
=
ccx
.tcx
()
.
enum_variant_with_id
(
enum_id
,
var_id
);
let
vinfo
=
ccx
.tcx
()
.
lookup_adt_def
(
enum_id
)
.variant_with_id
(
var_id
);
let
args
=
extract_variant_args
(
bcx
,
&*
repr
,
vinfo
.disr_val
,
...
...
@@ -1877,21 +1875,20 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
tcx
=
bcx
.tcx
();
let
pat_ty
=
node_id_type
(
bcx
,
pat
.id
);
let
pat_repr
=
adt
::
represent_type
(
bcx
.ccx
(),
pat_ty
);
expr
::
with_field_tys
(
tcx
,
pat_ty
,
Some
(
pat
.id
),
|
discr
,
field_tys
|
{
for
f
in
fields
{
let
ix
=
tcx
.field_idx_strict
(
f
.node.ident.name
,
field_tys
);
let
fldptr
=
adt
::
trans_field_ptr
(
bcx
,
&*
pat_repr
,
val
.val
,
discr
,
ix
);
bcx
=
bind_irrefutable_pat
(
bcx
,
&*
f
.node.pat
,
MatchInput
::
from_val
(
fldptr
),
cleanup_scope
);
}
})
let
pat_v
=
VariantInfo
::
of_node
(
tcx
,
pat_ty
,
pat
.id
);
for
f
in
fields
{
let
name
=
f
.node.ident.name
;
let
fldptr
=
adt
::
trans_field_ptr
(
bcx
,
&*
pat_repr
,
val
.val
,
pat_v
.discr
,
pat_v
.field_index
(
name
));
bcx
=
bind_irrefutable_pat
(
bcx
,
&*
f
.node.pat
,
MatchInput
::
from_val
(
fldptr
),
cleanup_scope
);
}
}
ast
::
PatTup
(
ref
elems
)
=>
{
let
repr
=
adt
::
represent_node
(
bcx
,
pat
.id
);
...
...
src/librustc_trans/trans/adt.rs
浏览文件 @
5f3c1412
...
...
@@ -246,10 +246,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Univariant
(
mk_struct
(
cx
,
&
elems
[
..
],
false
,
t
),
0
)
}
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
fields
=
cx
.tcx
()
.lookup_struct_fields
(
def
.did
);
let
mut
ftys
=
fields
.iter
()
.map
(|
field
|
{
let
fty
=
cx
.tcx
()
.lookup_field_type
(
def
.did
,
field
.id
,
substs
);
monomorphize
::
normalize_associated_type
(
cx
.tcx
(),
&
fty
)
let
mut
ftys
=
def
.struct_variant
()
.fields
.iter
()
.map
(|
field
|
{
monomorphize
::
field_ty
(
cx
.tcx
(),
substs
,
field
)
})
.collect
::
<
Vec
<
_
>>
();
let
packed
=
cx
.tcx
()
.lookup_packed
(
def
.did
);
let
dtor
=
cx
.tcx
()
.ty_dtor
(
def
.did
)
.has_drop_flag
();
...
...
@@ -263,7 +261,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Univariant
(
mk_struct
(
cx
,
&
substs
.upvar_tys
,
false
,
t
),
0
)
}
ty
::
TyEnum
(
def
,
substs
)
=>
{
let
cases
=
get_cases
(
cx
.tcx
(),
def
.did
,
substs
);
let
cases
=
get_cases
(
cx
.tcx
(),
def
,
substs
);
let
hint
=
*
cx
.tcx
()
.lookup_repr_hints
(
def
.did
)
.get
(
0
)
.unwrap_or
(
&
attr
::
ReprAny
);
...
...
@@ -444,10 +442,10 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
// Is this the NonZero lang item wrapping a pointer or integer type?
ty
::
TyStruct
(
def
,
substs
)
if
Some
(
def
.did
)
==
tcx
.lang_items
.non_zero
()
=>
{
let
nonzero_fields
=
tcx
.lookup_struct_fields
(
def
.did
)
;
let
nonzero_fields
=
&
def
.struct_variant
()
.fields
;
assert_eq!
(
nonzero_fields
.len
(),
1
);
let
nonzero_field
=
tcx
.lookup_field_type
(
def
.did
,
nonzero_fields
[
0
]
.id
,
substs
);
match
nonzero_field
.sty
{
let
field_ty
=
monomorphize
::
field_ty
(
tcx
,
substs
,
&
nonzero_fields
[
0
]
);
match
field_ty
.sty
{
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
})
if
!
type_is_sized
(
tcx
,
ty
)
=>
{
path
.push_all
(
&
[
0
,
FAT_PTR_ADDR
]);
Some
(
path
)
...
...
@@ -463,9 +461,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
// Perhaps one of the fields of this struct is non-zero
// let's recurse and find out
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
fields
=
tcx
.lookup_struct_fields
(
def
.did
);
for
(
j
,
field
)
in
fields
.iter
()
.enumerate
()
{
let
field_ty
=
tcx
.lookup_field_type
(
def
.did
,
field
.id
,
substs
);
for
(
j
,
field
)
in
def
.struct_variant
()
.fields
.iter
()
.enumerate
()
{
// TODO(#27532)
let
field_ty
=
field
.ty
(
tcx
,
substs
);
if
let
Some
(
mut
fpath
)
=
find_discr_field_candidate
(
tcx
,
field_ty
,
path
.clone
())
{
fpath
.push
(
j
);
return
Some
(
fpath
);
...
...
@@ -530,14 +528,14 @@ fn find_ptr<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> Option<DiscrField> {
}
fn
get_cases
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
def_id
:
ast
::
DefId
,
adt
:
&
ty
::
ADTDef
<
'tcx
>
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
Vec
<
Case
<
'tcx
>>
{
tcx
.enum_variants
(
def_id
)
.iter
()
.map
(|
vi
|
{
let
arg_tys
=
vi
.args
.iter
()
.map
(|
&
raw_ty
|
{
monomorphize
::
apply_param_substs
(
tcx
,
substs
,
&
raw_ty
)
adt
.variants
.iter
()
.map
(|
vi
|
{
let
field_tys
=
vi
.fields
.iter
()
.map
(|
field
|
{
monomorphize
::
field_ty
(
tcx
,
substs
,
field
)
})
.collect
();
Case
{
discr
:
vi
.disr_val
,
tys
:
arg
_tys
}
Case
{
discr
:
vi
.disr_val
,
tys
:
field
_tys
}
})
.collect
()
}
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
5f3c1412
...
...
@@ -55,8 +55,8 @@
use
trans
::
closure
;
use
trans
::
common
::{
Block
,
C_bool
,
C_bytes_in_context
,
C_i32
,
C_int
,
C_integral
};
use
trans
::
common
::{
C_null
,
C_struct_in_context
,
C_u64
,
C_u8
,
C_undef
};
use
trans
::
common
::{
CrateContext
,
DropFlagHintsMap
,
FunctionContext
};
use
trans
::
common
::{
Result
,
NodeIdAndSpan
};
use
trans
::
common
::{
CrateContext
,
DropFlagHintsMap
,
F
ield
,
F
unctionContext
};
use
trans
::
common
::{
Result
,
NodeIdAndSpan
,
VariantInfo
};
use
trans
::
common
::{
node_id_type
,
return_type_is_void
};
use
trans
::
common
::{
type_is_immediate
,
type_is_zero_size
,
val_ty
};
use
trans
::
common
;
...
...
@@ -386,7 +386,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
fn
iter_variant
<
'blk
,
'tcx
,
F
>
(
cx
:
Block
<
'blk
,
'tcx
>
,
repr
:
&
adt
::
Repr
<
'tcx
>
,
av
:
ValueRef
,
variant
:
&
ty
::
Variant
Info
<
'tcx
>
,
variant
:
&
ty
::
Variant
Def
<
'tcx
>
,
substs
:
&
Substs
<
'tcx
>
,
f
:
&
mut
F
)
->
Block
<
'blk
,
'tcx
>
where
...
...
@@ -396,8 +396,8 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
let
tcx
=
cx
.tcx
();
let
mut
cx
=
cx
;
for
(
i
,
&
arg
)
in
variant
.arg
s
.iter
()
.enumerate
()
{
let
arg
=
monomorphize
::
apply_param_substs
(
tcx
,
substs
,
&
arg
);
for
(
i
,
field
)
in
variant
.field
s
.iter
()
.enumerate
()
{
let
arg
=
monomorphize
::
field_ty
(
tcx
,
substs
,
field
);
cx
=
f
(
cx
,
adt
::
trans_field_ptr
(
cx
,
repr
,
av
,
variant
.disr_val
,
i
),
arg
);
}
return
cx
;
...
...
@@ -415,22 +415,20 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
match
t
.sty
{
ty
::
TyStruct
(
..
)
=>
{
let
repr
=
adt
::
represent_type
(
cx
.ccx
(),
t
);
expr
::
with_field_tys
(
cx
.tcx
(),
t
,
None
,
|
discr
,
field_tys
|
{
for
(
i
,
field_ty
)
in
field_tys
.iter
()
.enumerate
()
{
let
field_ty
=
field_ty
.mt.ty
;
let
llfld_a
=
adt
::
trans_field_ptr
(
cx
,
&*
repr
,
data_ptr
,
discr
,
i
);
let
val
=
if
common
::
type_is_sized
(
cx
.tcx
(),
field_ty
)
{
llfld_a
}
else
{
let
scratch
=
datum
::
rvalue_scratch_datum
(
cx
,
field_ty
,
"__fat_ptr_iter"
);
Store
(
cx
,
llfld_a
,
GEPi
(
cx
,
scratch
.val
,
&
[
0
,
abi
::
FAT_PTR_ADDR
]));
Store
(
cx
,
info
.unwrap
(),
GEPi
(
cx
,
scratch
.val
,
&
[
0
,
abi
::
FAT_PTR_EXTRA
]));
scratch
.val
};
cx
=
f
(
cx
,
val
,
field_ty
);
}
})
let
VariantInfo
{
fields
,
discr
}
=
VariantInfo
::
from_ty
(
cx
.tcx
(),
t
,
None
);
for
(
i
,
&
Field
(
_
,
field_ty
))
in
fields
.iter
()
.enumerate
()
{
let
llfld_a
=
adt
::
trans_field_ptr
(
cx
,
&*
repr
,
data_ptr
,
discr
,
i
);
let
val
=
if
common
::
type_is_sized
(
cx
.tcx
(),
field_ty
)
{
llfld_a
}
else
{
let
scratch
=
datum
::
rvalue_scratch_datum
(
cx
,
field_ty
,
"__fat_ptr_iter"
);
Store
(
cx
,
llfld_a
,
GEPi
(
cx
,
scratch
.val
,
&
[
0
,
abi
::
FAT_PTR_ADDR
]));
Store
(
cx
,
info
.unwrap
(),
GEPi
(
cx
,
scratch
.val
,
&
[
0
,
abi
::
FAT_PTR_EXTRA
]));
scratch
.val
};
cx
=
f
(
cx
,
val
,
field_ty
);
}
}
ty
::
TyClosure
(
_
,
ref
substs
)
=>
{
let
repr
=
adt
::
represent_type
(
cx
.ccx
(),
t
);
...
...
@@ -460,8 +458,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
let
ccx
=
fcx
.ccx
;
let
repr
=
adt
::
represent_type
(
ccx
,
t
);
let
variants
=
ccx
.tcx
()
.enum_variants
(
en
.did
);
let
n_variants
=
(
*
variants
)
.len
();
let
n_variants
=
en
.variants
.len
();
// NB: we must hit the discriminant first so that structural
// comparison know not to proceed when the discriminants differ.
...
...
@@ -470,7 +467,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
(
_
match
::
Single
,
None
)
=>
{
if
n_variants
!=
0
{
assert
!
(
n_variants
==
1
);
cx
=
iter_variant
(
cx
,
&*
repr
,
av
,
&
*
(
*
variants
)
[
0
],
cx
=
iter_variant
(
cx
,
&*
repr
,
av
,
&
en
.variants
[
0
],
substs
,
&
mut
f
);
}
}
...
...
@@ -496,7 +493,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
n_variants
);
let
next_cx
=
fcx
.new_temp_block
(
"enum-iter-next"
);
for
variant
in
&
(
*
variants
)
{
for
variant
in
&
en
.variants
{
let
variant_cx
=
fcx
.new_temp_block
(
&
format!
(
"enum-iter-variant-{}"
,
...
...
@@ -513,7 +510,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
iter_variant
(
variant_cx
,
&*
repr
,
data_ptr
,
&**
variant
,
variant
,
substs
,
&
mut
f
);
Br
(
variant_cx
,
next_cx
.llbb
,
DebugLoc
::
None
);
...
...
@@ -1694,9 +1691,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
pub
fn
trans_enum_variant
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
_
enum_id
:
ast
::
NodeId
,
variant
:
&
ast
::
Variant
,
_
args
:
&
[
ast
::
VariantArg
],
ctor_id
:
ast
::
NodeId
,
disr
:
ty
::
Disr
,
param_substs
:
&
'tcx
Substs
<
'tcx
>
,
llfndecl
:
ValueRef
)
{
...
...
@@ -1704,7 +1699,7 @@ pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trans_enum_variant_or_tuple_like_struct
(
ccx
,
variant
.node.
id
,
ctor_
id
,
disr
,
param_substs
,
llfndecl
);
...
...
@@ -1776,7 +1771,6 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
pub
fn
trans_tuple_struct
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
_
fields
:
&
[
ast
::
StructField
],
ctor_id
:
ast
::
NodeId
,
param_substs
:
&
'tcx
Substs
<
'tcx
>
,
llfndecl
:
ValueRef
)
{
...
...
src/librustc_trans/trans/callee.rs
浏览文件 @
5f3c1412
...
...
@@ -182,10 +182,8 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
fn_callee
(
bcx
,
fn_datum
)
}
def
::
DefVariant
(
tid
,
vid
,
_
)
=>
{
let
vinfo
=
bcx
.tcx
()
.enum_variant_with_id
(
tid
,
vid
);
// Nullary variants are not callable
assert
!
(
!
vinfo
.args
.is_empty
());
let
vinfo
=
bcx
.tcx
()
.lookup_adt_def
(
tid
)
.variant_with_id
(
vid
);
assert_eq!
(
vinfo
.kind
(),
ty
::
VariantKind
::
Tuple
);
Callee
{
bcx
:
bcx
,
...
...
src/librustc_trans/trans/common.rs
浏览文件 @
5f3c1412
...
...
@@ -49,6 +49,7 @@
use
std
::
result
::
Result
as
StdResult
;
use
std
::
vec
::
Vec
;
use
syntax
::
ast
;
use
syntax
::
ast_util
::
local_def
;
use
syntax
::
codemap
::{
DUMMY_SP
,
Span
};
use
syntax
::
parse
::
token
::
InternedString
;
use
syntax
::
parse
::
token
;
...
...
@@ -174,11 +175,9 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
fn
type_is_newtype_immediate
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
match
ty
.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
fields
=
ccx
.tcx
()
.lookup_struct_fields
(
def
.did
)
;
let
fields
=
&
def
.struct_variant
()
.fields
;
fields
.len
()
==
1
&&
{
let
ty
=
ccx
.tcx
()
.lookup_field_type
(
def
.did
,
fields
[
0
]
.id
,
substs
);
let
ty
=
monomorphize
::
normalize_associated_type
(
ccx
.tcx
(),
&
ty
);
type_is_immediate
(
ccx
,
ty
)
type_is_immediate
(
ccx
,
monomorphize
::
field_ty
(
ccx
.tcx
(),
substs
,
&
fields
[
0
]))
}
}
_
=>
false
...
...
@@ -271,6 +270,67 @@ pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan {
NodeIdAndSpan
{
id
:
expr
.id
,
span
:
expr
.span
}
}
/// The concrete version of ty::FieldDef. The name is the field index if
/// the field is numeric.
pub
struct
Field
<
'tcx
>
(
pub
ast
::
Name
,
pub
Ty
<
'tcx
>
);
/// The concrete version of ty::VariantDef
pub
struct
VariantInfo
<
'tcx
>
{
pub
discr
:
ty
::
Disr
,
pub
fields
:
Vec
<
Field
<
'tcx
>>
}
impl
<
'tcx
>
VariantInfo
<
'tcx
>
{
pub
fn
from_ty
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
opt_def
:
Option
<
def
::
Def
>
)
->
Self
{
match
ty
.sty
{
ty
::
TyStruct
(
adt
,
substs
)
|
ty
::
TyEnum
(
adt
,
substs
)
=>
{
let
variant
=
match
opt_def
{
None
=>
adt
.struct_variant
(),
Some
(
def
)
=>
adt
.variant_of_def
(
def
)
};
VariantInfo
{
discr
:
variant
.disr_val
,
fields
:
variant
.fields
.iter
()
.map
(|
f
|
{
Field
(
f
.name
,
monomorphize
::
field_ty
(
tcx
,
substs
,
f
))
})
.collect
()
}
}
ty
::
TyTuple
(
ref
v
)
=>
{
VariantInfo
{
discr
:
0
,
fields
:
v
.iter
()
.enumerate
()
.map
(|(
i
,
&
t
)|
{
Field
(
token
::
intern
(
&
i
.to_string
()),
t
)
})
.collect
()
}
}
_
=>
{
tcx
.sess
.bug
(
&
format!
(
"cannot get field types from the type {:?}"
,
ty
));
}
}
}
/// Return the variant corresponding to a given node (e.g. expr)
pub
fn
of_node
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
id
:
ast
::
NodeId
)
->
Self
{
let
node_def
=
tcx
.def_map
.borrow
()
.get
(
&
id
)
.map
(|
v
|
v
.full_def
());
Self
::
from_ty
(
tcx
,
ty
,
node_def
)
}
pub
fn
field_index
(
&
self
,
name
:
ast
::
Name
)
->
usize
{
self
.fields
.iter
()
.position
(|
&
Field
(
n
,
_
)|
n
==
name
)
.unwrap_or_else
(||
{
panic!
(
"unknown field `{}`"
,
name
)
})
}
}
pub
struct
BuilderRef_res
{
pub
b
:
BuilderRef
,
}
...
...
@@ -1178,3 +1238,26 @@ pub fn langcall(bcx: Block,
}
}
}
/// Return the VariantDef corresponding to an inlined variant node
pub
fn
inlined_variant_def
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
inlined_vid
:
ast
::
NodeId
)
->
&
'tcx
ty
::
VariantDef
<
'tcx
>
{
let
ctor_ty
=
ccx
.tcx
()
.node_id_to_type
(
inlined_vid
);
debug!
(
"inlined_variant_def: ctor_ty={:?} inlined_vid={:?}"
,
ctor_ty
,
inlined_vid
);
let
adt_def
=
match
ctor_ty
.sty
{
ty
::
TyBareFn
(
_
,
&
ty
::
BareFnTy
{
sig
:
ty
::
Binder
(
ty
::
FnSig
{
output
:
ty
::
FnConverging
(
ty
),
..
}),
..
})
=>
ty
,
_
=>
ctor_ty
}
.ty_adt_def
()
.unwrap
();
adt_def
.variants
.iter
()
.find
(|
v
|
{
local_def
(
inlined_vid
)
==
v
.did
||
ccx
.external
()
.borrow
()
.get
(
&
v
.did
)
==
Some
(
&
Some
(
inlined_vid
))
})
.unwrap_or_else
(||
{
ccx
.sess
()
.bug
(
&
format!
(
"no variant for {:?}::{}"
,
adt_def
,
inlined_vid
))
})
}
src/librustc_trans/trans/consts.rs
浏览文件 @
5f3c1412
...
...
@@ -579,17 +579,15 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ast
::
ExprField
(
ref
base
,
field
)
=>
{
let
(
bv
,
bt
)
=
const_expr
(
cx
,
&**
base
,
param_substs
,
fn_args
);
let
brepr
=
adt
::
represent_type
(
cx
,
bt
);
expr
::
with_field_tys
(
cx
.tcx
(),
bt
,
None
,
|
discr
,
field_tys
|
{
let
ix
=
cx
.tcx
()
.field_idx_strict
(
field
.node.name
,
field_tys
);
adt
::
const_get_field
(
cx
,
&*
brepr
,
bv
,
discr
,
ix
)
})
let
vinfo
=
VariantInfo
::
from_ty
(
cx
.tcx
(),
bt
,
None
);
let
ix
=
vinfo
.field_index
(
field
.node.name
);
adt
::
const_get_field
(
cx
,
&*
brepr
,
bv
,
vinfo
.discr
,
ix
)
},
ast
::
ExprTupField
(
ref
base
,
idx
)
=>
{
let
(
bv
,
bt
)
=
const_expr
(
cx
,
&**
base
,
param_substs
,
fn_args
);
let
brepr
=
adt
::
represent_type
(
cx
,
bt
);
expr
::
with_field_tys
(
cx
.tcx
(),
bt
,
None
,
|
discr
,
_
|
{
adt
::
const_get_field
(
cx
,
&*
brepr
,
bv
,
discr
,
idx
.node
)
})
let
vinfo
=
VariantInfo
::
from_ty
(
cx
.tcx
(),
bt
,
None
);
adt
::
const_get_field
(
cx
,
&*
brepr
,
bv
,
vinfo
.discr
,
idx
.node
)
},
ast
::
ExprIndex
(
ref
base
,
ref
index
)
=>
{
...
...
@@ -664,8 +662,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
}
unsafe
{
match
(
CastTy
::
from_ty
(
cx
.tcx
(),
t_expr
)
.expect
(
"bad input type for cast"
),
CastTy
::
from_ty
(
cx
.tcx
(),
t_cast
)
.expect
(
"bad output type for cast"
),
CastTy
::
from_ty
(
t_expr
)
.expect
(
"bad input type for cast"
),
CastTy
::
from_ty
(
t_cast
)
.expect
(
"bad output type for cast"
),
)
{
(
CastTy
::
Int
(
IntTy
::
CEnum
),
CastTy
::
Int
(
_
))
=>
{
let
repr
=
adt
::
represent_type
(
cx
,
t_expr
);
...
...
@@ -748,21 +746,19 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
None
=>
None
};
expr
::
with_field_tys
(
cx
.tcx
(),
ety
,
Some
(
e
.id
),
|
discr
,
field_tys
|
{
let
cs
=
field_tys
.iter
()
.enumerate
()
.map
(|(
ix
,
&
field_ty
)|
{
match
(
fs
.iter
()
.find
(|
f
|
field_ty
.name
==
f
.ident.node.name
),
base_val
)
{
(
Some
(
ref
f
),
_
)
=>
const_expr
(
cx
,
&*
f
.expr
,
param_substs
,
fn_args
)
.0
,
(
_
,
Some
((
bv
,
_
)))
=>
adt
::
const_get_field
(
cx
,
&*
repr
,
bv
,
discr
,
ix
),
(
_
,
None
)
=>
cx
.sess
()
.span_bug
(
e
.span
,
"missing struct field"
),
}
})
.collect
::
<
Vec
<
_
>>
();
if
ety
.is_simd
(
cx
.tcx
())
{
C_vector
(
&
cs
[
..
])
}
else
{
adt
::
trans_const
(
cx
,
&*
repr
,
discr
,
&
cs
[
..
])
let
VariantInfo
{
discr
,
fields
}
=
VariantInfo
::
of_node
(
cx
.tcx
(),
ety
,
e
.id
);
let
cs
=
fields
.iter
()
.enumerate
()
.map
(|(
ix
,
&
Field
(
f_name
,
_
))|
{
match
(
fs
.iter
()
.find
(|
f
|
f_name
==
f
.ident.node.name
),
base_val
)
{
(
Some
(
ref
f
),
_
)
=>
const_expr
(
cx
,
&*
f
.expr
,
param_substs
,
fn_args
)
.0
,
(
_
,
Some
((
bv
,
_
)))
=>
adt
::
const_get_field
(
cx
,
&*
repr
,
bv
,
discr
,
ix
),
(
_
,
None
)
=>
cx
.sess
()
.span_bug
(
e
.span
,
"missing struct field"
),
}
})
})
.collect
::
<
Vec
<
_
>>
();
if
ety
.is_simd
(
cx
.tcx
())
{
C_vector
(
&
cs
[
..
])
}
else
{
adt
::
trans_const
(
cx
,
&*
repr
,
discr
,
&
cs
[
..
])
}
},
ast
::
ExprVec
(
ref
es
)
=>
{
let
unit_ty
=
ety
.sequence_element_type
(
cx
.tcx
());
...
...
@@ -806,14 +802,18 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
const_deref_ptr
(
cx
,
get_const_val
(
cx
,
def_id
,
e
))
}
def
::
DefVariant
(
enum_did
,
variant_did
,
_
)
=>
{
let
vinfo
=
cx
.tcx
()
.enum_variant_with_id
(
enum_did
,
variant_did
);
if
!
vinfo
.args
.is_empty
()
{
// N-ary variant.
expr
::
trans_def_fn_unadjusted
(
cx
,
e
,
def
,
param_substs
)
.val
}
else
{
// Nullary variant.
let
repr
=
adt
::
represent_type
(
cx
,
ety
);
adt
::
trans_const
(
cx
,
&*
repr
,
vinfo
.disr_val
,
&
[])
let
vinfo
=
cx
.tcx
()
.lookup_adt_def
(
enum_did
)
.variant_with_id
(
variant_did
);
match
vinfo
.kind
()
{
ty
::
VariantKind
::
Unit
=>
{
let
repr
=
adt
::
represent_type
(
cx
,
ety
);
adt
::
trans_const
(
cx
,
&*
repr
,
vinfo
.disr_val
,
&
[])
}
ty
::
VariantKind
::
Tuple
=>
{
expr
::
trans_def_fn_unadjusted
(
cx
,
e
,
def
,
param_substs
)
.val
}
ty
::
VariantKind
::
Dict
=>
{
cx
.sess
()
.span_bug
(
e
.span
,
"path-expr refers to a dict variant!"
)
}
}
}
def
::
DefStruct
(
_
)
=>
{
...
...
@@ -859,7 +859,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
def
::
DefVariant
(
enum_did
,
variant_did
,
_
)
=>
{
let
repr
=
adt
::
represent_type
(
cx
,
ety
);
let
vinfo
=
cx
.tcx
()
.
enum_variant_with_id
(
enum_did
,
variant_did
);
let
vinfo
=
cx
.tcx
()
.
lookup_adt_def
(
enum_did
)
.variant_with_id
(
variant_did
);
adt
::
trans_const
(
cx
,
&*
repr
,
vinfo
.disr_val
,
...
...
src/librustc_trans/trans/debuginfo/metadata.rs
浏览文件 @
5f3c1412
...
...
@@ -44,7 +44,7 @@
use
syntax
::
util
::
interner
::
Interner
;
use
syntax
::
codemap
::
Span
;
use
syntax
::{
ast
,
codemap
,
ast_util
};
use
syntax
::
parse
::
token
::{
self
,
special_idents
}
;
use
syntax
::
parse
::
token
;
const
DW_LANG_RUST
:
c_uint
=
0x9000
;
...
...
@@ -784,11 +784,9 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
unique_type_id
,
usage_site_span
)
.finalize
(
cx
)
}
ty
::
TyStruct
(
def
,
substs
)
=>
{
ty
::
TyStruct
(
..
)
=>
{
prepare_struct_metadata
(
cx
,
t
,
def
.did
,
substs
,
unique_type_id
,
usage_site_span
)
.finalize
(
cx
)
}
...
...
@@ -1096,7 +1094,8 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
// Creates MemberDescriptions for the fields of a struct
struct
StructMemberDescriptionFactory
<
'tcx
>
{
fields
:
Vec
<
ty
::
Field
<
'tcx
>>
,
variant
:
&
'tcx
ty
::
VariantDef
<
'tcx
>
,
substs
:
&
'tcx
subst
::
Substs
<
'tcx
>
,
is_simd
:
bool
,
span
:
Span
,
}
...
...
@@ -1104,34 +1103,40 @@ struct StructMemberDescriptionFactory<'tcx> {
impl
<
'tcx
>
StructMemberDescriptionFactory
<
'tcx
>
{
fn
create_member_descriptions
<
'a
>
(
&
self
,
cx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
Vec
<
MemberDescription
>
{
if
self
.fields
.is_empty
()
{
if
let
ty
::
VariantKind
::
Unit
=
self
.variant
.kind
()
{
return
Vec
::
new
();
}
let
field_size
=
if
self
.is_simd
{
machine
::
llsize_of_alloc
(
cx
,
type_of
::
type_of
(
cx
,
self
.fields
[
0
]
.mt.ty
))
as
usize
let
fty
=
monomorphize
::
field_ty
(
cx
.tcx
(),
self
.substs
,
&
self
.variant.fields
[
0
]);
Some
(
machine
::
llsize_of_alloc
(
cx
,
type_of
::
type_of
(
cx
,
fty
)
)
as
usize
)
}
else
{
0xdeadbeef
None
};
self
.
fields
.iter
()
.enumerate
()
.map
(|(
i
,
field
)|
{
let
name
=
if
field
.name
==
special_idents
::
unnamed_field
.name
{
self
.
variant.fields
.iter
()
.enumerate
()
.map
(|(
i
,
f
)|
{
let
name
=
if
let
ty
::
VariantKind
::
Tuple
=
self
.variant
.kind
()
{
format!
(
"__{}"
,
i
)
}
else
{
f
ield
.name
.to_string
()
f
.name
.to_string
()
};
let
fty
=
monomorphize
::
field_ty
(
cx
.tcx
(),
self
.substs
,
f
);
let
offset
=
if
self
.is_simd
{
assert
!
(
field_size
!=
0xdeadbeef
);
FixedMemberOffset
{
bytes
:
i
*
field_size
}
FixedMemberOffset
{
bytes
:
i
*
field_size
.unwrap
()
}
}
else
{
ComputedMemberOffset
};
MemberDescription
{
name
:
name
,
llvm_type
:
type_of
::
type_of
(
cx
,
f
ield
.mt.
ty
),
type_metadata
:
type_metadata
(
cx
,
f
ield
.mt.
ty
,
self
.span
),
llvm_type
:
type_of
::
type_of
(
cx
,
fty
),
type_metadata
:
type_metadata
(
cx
,
fty
,
self
.span
),
offset
:
offset
,
flags
:
FLAGS_NONE
,
}
...
...
@@ -1142,15 +1147,18 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
fn
prepare_struct_metadata
<
'a
,
'tcx
>
(
cx
:
&
CrateContext
<
'a
,
'tcx
>
,
struct_type
:
Ty
<
'tcx
>
,
def_id
:
ast
::
DefId
,
substs
:
&
subst
::
Substs
<
'tcx
>
,
unique_type_id
:
UniqueTypeId
,
span
:
Span
)
->
RecursiveTypeDescription
<
'tcx
>
{
let
struct_name
=
compute_debuginfo_type_name
(
cx
,
struct_type
,
false
);
let
struct_llvm_type
=
type_of
::
in_memory_type_of
(
cx
,
struct_type
);
let
(
containing_scope
,
_
)
=
get_namespace_and_span_for_item
(
cx
,
def_id
);
let
(
variant
,
substs
)
=
match
struct_type
.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
(
def
.struct_variant
(),
substs
),
_
=>
cx
.tcx
()
.sess
.bug
(
"prepare_struct_metadata on a non-struct"
)
};
let
(
containing_scope
,
_
)
=
get_namespace_and_span_for_item
(
cx
,
variant
.did
);
let
struct_metadata_stub
=
create_struct_stub
(
cx
,
struct_llvm_type
,
...
...
@@ -1158,14 +1166,6 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
unique_type_id
,
containing_scope
);
let
mut
fields
=
cx
.tcx
()
.struct_fields
(
def_id
,
substs
);
// The `Ty` values returned by `ty::struct_fields` can still contain
// `TyProjection` variants, so normalize those away.
for
field
in
&
mut
fields
{
field
.mt.ty
=
monomorphize
::
normalize_associated_type
(
cx
.tcx
(),
&
field
.mt.ty
);
}
create_and_register_recursive_type_forward_declaration
(
cx
,
struct_type
,
...
...
@@ -1173,7 +1173,8 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
struct_metadata_stub
,
struct_llvm_type
,
StructMDF
(
StructMemberDescriptionFactory
{
fields
:
fields
,
variant
:
variant
,
substs
:
substs
,
is_simd
:
struct_type
.is_simd
(
cx
.tcx
()),
span
:
span
,
})
...
...
@@ -1248,7 +1249,6 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
struct
EnumMemberDescriptionFactory
<
'tcx
>
{
enum_type
:
Ty
<
'tcx
>
,
type_rep
:
Rc
<
adt
::
Repr
<
'tcx
>>
,
variants
:
Rc
<
Vec
<
Rc
<
ty
::
VariantInfo
<
'tcx
>>>>
,
discriminant_type_metadata
:
Option
<
DIType
>
,
containing_scope
:
DIScope
,
file_metadata
:
DIFile
,
...
...
@@ -1258,11 +1258,11 @@ struct EnumMemberDescriptionFactory<'tcx> {
impl
<
'tcx
>
EnumMemberDescriptionFactory
<
'tcx
>
{
fn
create_member_descriptions
<
'a
>
(
&
self
,
cx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
Vec
<
MemberDescription
>
{
let
adt
=
&
self
.enum_type
.ty_adt_def
()
.unwrap
();
match
*
self
.type_rep
{
adt
::
General
(
_
,
ref
struct_defs
,
_
)
=>
{
let
discriminant_info
=
RegularDiscriminant
(
self
.discriminant_type_metadata
.expect
(
""
));
struct_defs
.iter
()
.enumerate
()
...
...
@@ -1273,7 +1273,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
describe_enum_variant
(
cx
,
self
.enum_type
,
struct_def
,
&
*
self
.variants
[
i
],
&
adt
.variants
[
i
],
discriminant_info
,
self
.containing_scope
,
self
.span
);
...
...
@@ -1295,9 +1295,9 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
})
.collect
()
},
adt
::
Univariant
(
ref
struct_def
,
_
)
=>
{
assert
!
(
self
.variants
.len
()
<=
1
);
assert
!
(
adt
.variants
.len
()
<=
1
);
if
self
.variants
.is_empty
()
{
if
adt
.variants
.is_empty
()
{
vec!
[]
}
else
{
let
(
variant_type_metadata
,
...
...
@@ -1306,7 +1306,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
describe_enum_variant
(
cx
,
self
.enum_type
,
struct_def
,
&
*
self
.variants
[
0
],
&
adt
.variants
[
0
],
NoDiscriminant
,
self
.containing_scope
,
self
.span
);
...
...
@@ -1335,7 +1335,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
// DWARF representation of enums uniform.
// First create a description of the artificial wrapper struct:
let
non_null_variant
=
&
self
.variants
[
non_null_variant_index
as
usize
];
let
non_null_variant
=
&
adt
.variants
[
non_null_variant_index
as
usize
];
let
non_null_variant_name
=
non_null_variant
.name
.as_str
();
// The llvm type and metadata of the pointer
...
...
@@ -1350,9 +1350,12 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
// For the metadata of the wrapper struct, we need to create a
// MemberDescription of the struct's single field.
let
sole_struct_member_description
=
MemberDescription
{
name
:
match
non_null_variant
.arg_names
{
Some
(
ref
names
)
=>
names
[
0
]
.to_string
(),
None
=>
"__0"
.to_string
()
name
:
match
non_null_variant
.kind
()
{
ty
::
VariantKind
::
Tuple
=>
"__0"
.to_string
(),
ty
::
VariantKind
::
Dict
=>
{
non_null_variant
.fields
[
0
]
.name
.to_string
()
}
ty
::
VariantKind
::
Unit
=>
unreachable!
()
},
llvm_type
:
non_null_llvm_type
,
type_metadata
:
non_null_type_metadata
,
...
...
@@ -1381,7 +1384,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
// Encode the information about the null variant in the union
// member's name.
let
null_variant_index
=
(
1
-
non_null_variant_index
)
as
usize
;
let
null_variant_name
=
self
.variants
[
null_variant_index
]
.name
;
let
null_variant_name
=
adt
.variants
[
null_variant_index
]
.name
;
let
union_member_name
=
format!
(
"RUST$ENCODED$ENUM${}${}"
,
0
,
null_variant_name
);
...
...
@@ -1406,7 +1409,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
describe_enum_variant
(
cx
,
self
.enum_type
,
struct_def
,
&
*
self
.variants
[
nndiscr
as
usize
],
&
adt
.variants
[
nndiscr
as
usize
],
OptimizedDiscriminant
,
self
.containing_scope
,
self
.span
);
...
...
@@ -1422,7 +1425,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
// Encode the information about the null variant in the union
// member's name.
let
null_variant_index
=
(
1
-
nndiscr
)
as
usize
;
let
null_variant_name
=
self
.variants
[
null_variant_index
]
.name
;
let
null_variant_name
=
adt
.variants
[
null_variant_index
]
.name
;
let
discrfield
=
discrfield
.iter
()
.skip
(
1
)
.map
(|
x
|
x
.to_string
())
...
...
@@ -1486,7 +1489,7 @@ enum EnumDiscriminantInfo {
fn
describe_enum_variant
<
'a
,
'tcx
>
(
cx
:
&
CrateContext
<
'a
,
'tcx
>
,
enum_type
:
Ty
<
'tcx
>
,
struct_def
:
&
adt
::
Struct
<
'tcx
>
,
variant
_info
:
&
ty
::
VariantInfo
<
'tcx
>
,
variant
:
&
ty
::
VariantDef
<
'tcx
>
,
discriminant_info
:
EnumDiscriminantInfo
,
containing_scope
:
DIScope
,
span
:
Span
)
...
...
@@ -1500,7 +1503,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
struct_def
.packed
);
// Could do some consistency checks here: size, align, field count, discr type
let
variant_name
=
variant
_info
.name
.as_str
();
let
variant_name
=
variant
.name
.as_str
();
let
unique_type_id
=
debug_context
(
cx
)
.type_map
.borrow_mut
()
.get_unique_type_id_of_enum_variant
(
...
...
@@ -1515,18 +1518,20 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
containing_scope
);
// Get the argument names from the enum variant info
let
mut
arg_names
:
Vec
<
_
>
=
match
variant_info
.arg_names
{
Some
(
ref
names
)
=>
{
names
.iter
()
.map
(|
name
|
name
.to_string
())
.collect
()
let
mut
arg_names
:
Vec
<
_
>
=
match
variant
.kind
()
{
ty
::
VariantKind
::
Unit
=>
vec!
[],
ty
::
VariantKind
::
Tuple
=>
{
variant
.fields
.iter
()
.enumerate
()
.map
(|(
i
,
_
)|
format!
(
"__{}"
,
i
))
.collect
()
}
None
=>
{
variant_info
.args
.iter
()
.enumerate
()
.map
(|(
i
,
_
)|
format!
(
"__{}"
,
i
))
.collect
()
ty
::
VariantKind
::
Dict
=>
{
variant
.fields
.iter
()
.map
(|
f
|
f
.name
.to_string
())
.collect
()
}
};
...
...
@@ -1569,7 +1574,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let
loc
=
span_start
(
cx
,
definition_span
);
let
file_metadata
=
file_metadata
(
cx
,
&
loc
.file.name
);
let
variants
=
cx
.tcx
()
.enum_variants
(
enum_def_id
)
;
let
variants
=
&
enum_type
.ty_adt_def
()
.unwrap
()
.variants
;
let
enumerators_metadata
:
Vec
<
DIDescriptor
>
=
variants
.iter
()
...
...
@@ -1671,7 +1676,6 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
EnumMDF
(
EnumMemberDescriptionFactory
{
enum_type
:
enum_type
,
type_rep
:
type_rep
.clone
(),
variants
:
variants
,
discriminant_type_metadata
:
discriminant_type_metadata
,
containing_scope
:
containing_scope
,
file_metadata
:
file_metadata
,
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
5f3c1412
...
...
@@ -68,7 +68,6 @@
use
trans
::
glue
;
use
trans
::
machine
;
use
trans
::
meth
;
use
trans
::
monomorphize
;
use
trans
::
tvec
;
use
trans
::
type_of
;
use
middle
::
cast
::{
CastKind
,
CastTy
};
...
...
@@ -708,7 +707,7 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
base
:
&
ast
::
Expr
,
get_idx
:
F
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
where
F
:
FnOnce
(
&
'blk
ty
::
ctxt
<
'tcx
>
,
&
[
ty
::
Field
<
'tcx
>
]
)
->
usize
,
F
:
FnOnce
(
&
'blk
ty
::
ctxt
<
'tcx
>
,
&
VariantInfo
<
'tcx
>
)
->
usize
,
{
let
mut
bcx
=
bcx
;
let
_
icx
=
push_ctxt
(
"trans_rec_field"
);
...
...
@@ -716,27 +715,26 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let
base_datum
=
unpack_datum!
(
bcx
,
trans_to_lvalue
(
bcx
,
base
,
"field"
));
let
bare_ty
=
base_datum
.ty
;
let
repr
=
adt
::
represent_type
(
bcx
.ccx
(),
bare_ty
);
with_field_tys
(
bcx
.tcx
(),
bare_ty
,
None
,
move
|
discr
,
field_tys
|
{
let
ix
=
get_idx
(
bcx
.tcx
(),
field_tys
);
let
d
=
base_datum
.get_element
(
bcx
,
field_tys
[
ix
]
.mt.ty
,
|
srcval
|
adt
::
trans_field_ptr
(
bcx
,
&*
repr
,
srcval
,
discr
,
ix
));
if
type_is_sized
(
bcx
.tcx
(),
d
.ty
)
{
DatumBlock
{
datum
:
d
.to_expr_datum
(),
bcx
:
bcx
}
}
else
{
let
scratch
=
rvalue_scratch_datum
(
bcx
,
d
.ty
,
""
);
Store
(
bcx
,
d
.val
,
get_dataptr
(
bcx
,
scratch
.val
));
let
info
=
Load
(
bcx
,
get_len
(
bcx
,
base_datum
.val
));
Store
(
bcx
,
info
,
get_len
(
bcx
,
scratch
.val
));
let
vinfo
=
VariantInfo
::
from_ty
(
bcx
.tcx
(),
bare_ty
,
None
);
// Always generate an lvalue datum, because this pointer doesn't own
// the data and cleanup is scheduled elsewhere.
DatumBlock
::
new
(
bcx
,
Datum
::
new
(
scratch
.val
,
scratch
.ty
,
LvalueExpr
(
d
.kind
)))
}
})
let
ix
=
get_idx
(
bcx
.tcx
(),
&
vinfo
);
let
d
=
base_datum
.get_element
(
bcx
,
vinfo
.fields
[
ix
]
.1
,
|
srcval
|
adt
::
trans_field_ptr
(
bcx
,
&*
repr
,
srcval
,
vinfo
.discr
,
ix
));
if
type_is_sized
(
bcx
.tcx
(),
d
.ty
)
{
DatumBlock
{
datum
:
d
.to_expr_datum
(),
bcx
:
bcx
}
}
else
{
let
scratch
=
rvalue_scratch_datum
(
bcx
,
d
.ty
,
""
);
Store
(
bcx
,
d
.val
,
get_dataptr
(
bcx
,
scratch
.val
));
let
info
=
Load
(
bcx
,
get_len
(
bcx
,
base_datum
.val
));
Store
(
bcx
,
info
,
get_len
(
bcx
,
scratch
.val
));
// Always generate an lvalue datum, because this pointer doesn't own
// the data and cleanup is scheduled elsewhere.
DatumBlock
::
new
(
bcx
,
Datum
::
new
(
scratch
.val
,
scratch
.ty
,
LvalueExpr
(
d
.kind
)))
}
}
/// Translates `base.field`.
...
...
@@ -744,7 +742,7 @@ fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
base
:
&
ast
::
Expr
,
field
:
ast
::
Name
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
{
trans_field
(
bcx
,
base
,
|
tcx
,
field_tys
|
tcx
.field_idx_strict
(
field
,
field_tys
))
trans_field
(
bcx
,
base
,
|
_
,
vinfo
|
vinfo
.field_index
(
field
))
}
/// Translates `base.<idx>`.
...
...
@@ -1249,8 +1247,8 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match
def
{
def
::
DefVariant
(
tid
,
vid
,
_
)
=>
{
let
variant
_info
=
bcx
.tcx
()
.enum_variant_with_id
(
tid
,
vid
);
if
!
variant_info
.args
.is_empty
()
{
let
variant
=
bcx
.tcx
()
.lookup_adt_def
(
tid
)
.variant_with_id
(
vid
);
if
let
ty
::
VariantKind
::
Tuple
=
variant
.kind
()
{
// N-ary variant.
let
llfn
=
callee
::
trans_fn_ref
(
bcx
.ccx
(),
vid
,
ExprId
(
ref_expr
.id
),
...
...
@@ -1261,8 +1259,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Nullary variant.
let
ty
=
expr_ty
(
bcx
,
ref_expr
);
let
repr
=
adt
::
represent_type
(
bcx
.ccx
(),
ty
);
adt
::
trans_set_discr
(
bcx
,
&*
repr
,
lldest
,
variant_info
.disr_val
);
adt
::
trans_set_discr
(
bcx
,
&*
repr
,
lldest
,
variant
.disr_val
);
return
bcx
;
}
}
...
...
@@ -1362,71 +1359,6 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
/// Helper for enumerating the field types of structs, enums, or records. The optional node ID here
/// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly
/// an enum variant (so, if it is and `node_id_opt` is none, this function panics).
pub
fn
with_field_tys
<
'tcx
,
R
,
F
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
node_id_opt
:
Option
<
ast
::
NodeId
>
,
op
:
F
)
->
R
where
F
:
FnOnce
(
ty
::
Disr
,
&
[
ty
::
Field
<
'tcx
>
])
->
R
,
{
match
ty
.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
fields
=
tcx
.struct_fields
(
def
.did
,
substs
);
let
fields
=
monomorphize
::
normalize_associated_type
(
tcx
,
&
fields
);
op
(
0
,
&
fields
[
..
])
}
ty
::
TyTuple
(
ref
v
)
=>
{
let
fields
:
Vec
<
_
>
=
v
.iter
()
.enumerate
()
.map
(|(
i
,
&
f
)|
{
ty
::
Field
{
name
:
token
::
intern
(
&
i
.to_string
()),
mt
:
ty
::
TypeAndMut
{
ty
:
f
,
mutbl
:
ast
::
MutImmutable
}
}
})
.collect
();
op
(
0
,
&
fields
)
}
ty
::
TyEnum
(
_
,
substs
)
=>
{
// We want the *variant* ID here, not the enum ID.
match
node_id_opt
{
None
=>
{
tcx
.sess
.bug
(
&
format!
(
"cannot get field types from the enum type {:?}
\
without a node ID"
,
ty
));
}
Some
(
node_id
)
=>
{
let
def
=
tcx
.def_map
.borrow
()
.get
(
&
node_id
)
.unwrap
()
.full_def
();
match
def
{
def
::
DefVariant
(
enum_id
,
variant_id
,
_
)
=>
{
let
variant_info
=
tcx
.enum_variant_with_id
(
enum_id
,
variant_id
);
let
fields
=
tcx
.struct_fields
(
variant_id
,
substs
);
let
fields
=
monomorphize
::
normalize_associated_type
(
tcx
,
&
fields
);
op
(
variant_info
.disr_val
,
&
fields
[
..
])
}
_
=>
{
tcx
.sess
.bug
(
"resolve didn't map this expr to a
\
variant ID"
)
}
}
}
}
}
_
=>
{
tcx
.sess
.bug
(
&
format!
(
"cannot get field types from the type {:?}"
,
ty
));
}
}
}
fn
trans_struct
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
fields
:
&
[
ast
::
Field
],
base
:
Option
<&
ast
::
Expr
>
,
...
...
@@ -1437,52 +1369,42 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
_
icx
=
push_ctxt
(
"trans_rec"
);
let
tcx
=
bcx
.tcx
();
with_field_tys
(
tcx
,
ty
,
Some
(
expr_id
),
|
discr
,
field_tys
|
{
let
mut
need_base
=
vec!
[
true
;
field_tys
.len
()];
let
numbered_fields
=
fields
.iter
()
.map
(|
field
|
{
let
opt_pos
=
field_tys
.iter
()
.position
(|
field_ty
|
field_ty
.name
==
field
.ident.node.name
);
let
result
=
match
opt_pos
{
Some
(
i
)
=>
{
need_base
[
i
]
=
false
;
(
i
,
&*
field
.expr
)
}
None
=>
{
tcx
.sess
.span_bug
(
field
.span
,
"Couldn't find field in struct type"
)
let
vinfo
=
VariantInfo
::
of_node
(
tcx
,
ty
,
expr_id
);
let
mut
need_base
=
vec!
[
true
;
vinfo
.fields
.len
()];
let
numbered_fields
=
fields
.iter
()
.map
(|
field
|
{
let
pos
=
vinfo
.field_index
(
field
.ident.node.name
);
need_base
[
pos
]
=
false
;
(
pos
,
&*
field
.expr
)
})
.collect
::
<
Vec
<
_
>>
();
let
optbase
=
match
base
{
Some
(
base_expr
)
=>
{
let
mut
leftovers
=
Vec
::
new
();
for
(
i
,
b
)
in
need_base
.iter
()
.enumerate
()
{
if
*
b
{
leftovers
.push
((
i
,
vinfo
.fields
[
i
]
.1
));
}
};
result
})
.collect
::
<
Vec
<
_
>>
();
let
optbase
=
match
base
{
Some
(
base_expr
)
=>
{
let
mut
leftovers
=
Vec
::
new
();
for
(
i
,
b
)
in
need_base
.iter
()
.enumerate
()
{
if
*
b
{
leftovers
.push
((
i
,
field_tys
[
i
]
.mt.ty
));
}
}
Some
(
StructBaseInfo
{
expr
:
base_expr
,
fields
:
leftovers
})
}
None
=>
{
if
need_base
.iter
()
.any
(|
b
|
*
b
)
{
tcx
.sess
.span_bug
(
expr_span
,
"missing fields and no base expr"
)
}
None
Some
(
StructBaseInfo
{
expr
:
base_expr
,
fields
:
leftovers
})
}
None
=>
{
if
need_base
.iter
()
.any
(|
b
|
*
b
)
{
tcx
.sess
.span_bug
(
expr_span
,
"missing fields and no base expr"
)
}
};
None
}
};
trans_adt
(
bcx
,
ty
,
discr
,
&
numbered_fields
,
optbase
,
dest
,
DebugLoc
::
At
(
expr_id
,
expr_span
))
})
trans_adt
(
bcx
,
ty
,
vinfo
.discr
,
&
numbered_fields
,
optbase
,
dest
,
DebugLoc
::
At
(
expr_id
,
expr_span
))
}
/// Information that `trans_adt` needs in order to fill in the fields
...
...
@@ -2126,8 +2048,8 @@ fn float_cast(bcx: Block,
}
}
let
r_t_in
=
CastTy
::
from_ty
(
bcx
.tcx
(),
t_in
)
.expect
(
"bad input type for cast"
);
let
r_t_out
=
CastTy
::
from_ty
(
bcx
.tcx
(),
t_out
)
.expect
(
"bad output type for cast"
);
let
r_t_in
=
CastTy
::
from_ty
(
t_in
)
.expect
(
"bad input type for cast"
);
let
r_t_out
=
CastTy
::
from_ty
(
t_out
)
.expect
(
"bad output type for cast"
);
let
(
llexpr
,
signed
)
=
if
let
Int
(
CEnum
)
=
r_t_in
{
let
repr
=
adt
::
represent_type
(
ccx
,
t_in
);
...
...
src/librustc_trans/trans/glue.rs
浏览文件 @
5f3c1412
...
...
@@ -432,9 +432,8 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
// Recurse to get the size of the dynamically sized field (must be
// the last field).
let
fields
=
bcx
.tcx
()
.struct_fields
(
def
.did
,
substs
);
let
last_field
=
fields
[
fields
.len
()
-
1
];
let
field_ty
=
last_field
.mt.ty
;
let
last_field
=
def
.struct_variant
()
.fields
.last
()
.unwrap
();
let
field_ty
=
monomorphize
::
field_ty
(
bcx
.tcx
(),
substs
,
last_field
);
let
(
unsized_size
,
unsized_align
)
=
size_and_align_of_dst
(
bcx
,
field_ty
,
info
);
let
dbloc
=
DebugLoc
::
None
;
...
...
src/librustc_trans/trans/inline.rs
浏览文件 @
5f3c1412
...
...
@@ -100,30 +100,32 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
ccx
.external
()
.borrow_mut
()
.insert
(
parent_id
,
Some
(
item
.id
));
ccx
.external_srcs
()
.borrow_mut
()
.insert
(
item
.id
,
parent_id
);
let
mut
my_id
=
0
;
match
item
.node
{
ast
::
ItemEnum
(
_
,
_
)
=>
{
let
vs_here
=
ccx
.tcx
()
.enum_variants
(
local_def
(
item
.id
));
let
vs_there
=
ccx
.tcx
()
.enum_variants
(
parent_id
);
for
(
here
,
there
)
in
vs_here
.iter
()
.zip
(
vs_there
.iter
())
{
if
there
.id
==
fn_id
{
my_id
=
here
.id.node
;
}
ccx
.external
()
.borrow_mut
()
.insert
(
there
.id
,
Some
(
here
.id.node
));
}
}
ast
::
ItemStruct
(
ref
struct_def
,
_
)
=>
{
match
struct_def
.ctor_id
{
None
=>
{}
Some
(
ctor_id
)
=>
{
ccx
.external
()
.borrow_mut
()
.insert
(
fn_id
,
Some
(
ctor_id
));
my_id
=
ctor_id
;
let
mut
my_id
=
0
;
match
item
.node
{
ast
::
ItemEnum
(
ref
ast_def
,
_
)
=>
{
let
ast_vs
=
&
ast_def
.variants
;
let
ty_vs
=
&
ccx
.tcx
()
.lookup_adt_def
(
parent_id
)
.variants
;
assert_eq!
(
ast_vs
.len
(),
ty_vs
.len
());
for
(
ast_v
,
ty_v
)
in
ast_vs
.iter
()
.zip
(
ty_vs
.iter
())
{
if
ty_v
.did
==
fn_id
{
my_id
=
ast_v
.node.id
;
}
ccx
.external
()
.borrow_mut
()
.insert
(
ty_v
.did
,
Some
(
ast_v
.node.id
));
}
}
}
}
_
=>
ccx
.sess
()
.bug
(
"instantiate_inline: item has a
\
ast
::
ItemStruct
(
ref
struct_def
,
_
)
=>
{
match
struct_def
.ctor_id
{
None
=>
ccx
.sess
()
.bug
(
"instantiate_inline: called on a
\
non-tuple struct"
),
Some
(
ctor_id
)
=>
{
ccx
.external
()
.borrow_mut
()
.insert
(
fn_id
,
Some
(
ctor_id
));
my_id
=
ctor_id
;
}
}
}
_
=>
ccx
.sess
()
.bug
(
"instantiate_inline: item has a
\
non-enum, non-struct parent"
)
}
trans_item
(
ccx
,
&**
item
);
my_id
}
trans_item
(
ccx
,
&**
item
);
my_id
}
csearch
::
FoundAst
::
FoundParent
(
_
,
_
)
=>
{
ccx
.sess
()
.bug
(
"maybe_get_item_ast returned a FoundParent
\
...
...
src/librustc_trans/trans/monomorphize.rs
浏览文件 @
5f3c1412
...
...
@@ -29,7 +29,6 @@
use
syntax
::
abi
;
use
syntax
::
ast
;
use
syntax
::
ast_util
::
local_def
;
use
syntax
::
attr
;
use
syntax
::
codemap
::
DUMMY_SP
;
use
std
::
hash
::{
Hasher
,
Hash
,
SipHasher
};
...
...
@@ -192,24 +191,11 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
ast_map
::
NodeVariant
(
v
)
=>
{
let
parent
=
ccx
.tcx
()
.map
.get_parent
(
fn_id
.node
);
let
tvs
=
ccx
.tcx
()
.enum_variants
(
local_def
(
parent
));
let
this_tv
=
tvs
.iter
()
.find
(|
tv
|
{
tv
.id.node
==
fn_id
.node
})
.unwrap
();
let
variant
=
inlined_variant_def
(
ccx
,
fn_id
.node
);
assert_eq!
(
v
.node.name.name
,
variant
.name
);
let
d
=
mk_lldecl
(
abi
::
Rust
);
attributes
::
inline
(
d
,
attributes
::
InlineAttr
::
Hint
);
match
v
.node.kind
{
ast
::
TupleVariantKind
(
ref
args
)
=>
{
trans_enum_variant
(
ccx
,
parent
,
&*
v
,
&
args
[
..
],
this_tv
.disr_val
,
psubsts
,
d
);
}
ast
::
StructVariantKind
(
_
)
=>
ccx
.sess
()
.bug
(
"can't monomorphize struct variants"
),
}
trans_enum_variant
(
ccx
,
fn_id
.node
,
variant
.disr_val
,
psubsts
,
d
);
d
}
ast_map
::
NodeImplItem
(
impl_item
)
=>
{
...
...
@@ -255,7 +241,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
d
=
mk_lldecl
(
abi
::
Rust
);
attributes
::
inline
(
d
,
attributes
::
InlineAttr
::
Hint
);
base
::
trans_tuple_struct
(
ccx
,
&
struct_def
.fields
,
struct_def
.ctor_id
.expect
(
"ast-mapped tuple struct
\
didn't have a ctor id"
),
psubsts
,
...
...
@@ -302,6 +287,16 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>,
normalize_associated_type
(
tcx
,
&
substituted
)
}
/// Returns the normalized type of a struct field
pub
fn
field_ty
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
param_substs
:
&
Substs
<
'tcx
>
,
f
:
&
ty
::
FieldDef
<
'tcx
>
)
->
Ty
<
'tcx
>
{
normalize_associated_type
(
tcx
,
&
f
.ty
(
tcx
,
param_substs
))
}
/// Removes associated types, if any. Since this during
/// monomorphization, we know that only concrete types are involved,
/// and hence we can be sure that all associated types will be
...
...
src/librustc_typeck/check/_match.rs
浏览文件 @
5f3c1412
...
...
@@ -528,7 +528,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
let
tcx
=
pcx
.fcx.ccx.tcx
;
let
def
=
tcx
.def_map
.borrow
()
.get
(
&
pat
.id
)
.unwrap
()
.full_def
();
let
(
adt_def
,
variant
_def_id
)
=
match
def
{
let
(
adt_def
,
variant
)
=
match
def
{
def
::
DefTrait
(
_
)
=>
{
let
name
=
pprust
::
path_to_string
(
path
);
span_err!
(
tcx
.sess
,
pat
.span
,
E0168
,
...
...
@@ -544,11 +544,10 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
let
def_type
=
tcx
.lookup_item_type
(
def
.def_id
());
match
def_type
.ty.sty
{
ty
::
TyStruct
(
struct_def
,
_
)
=>
(
struct_def
,
struct_def
.
did
),
(
struct_def
,
struct_def
.
struct_variant
()
),
ty
::
TyEnum
(
enum_def
,
_
)
// TODO: wut?
if
def
==
def
::
DefVariant
(
enum_def
.did
,
def
.def_id
(),
true
)
=>
(
enum_def
,
def
.def_id
(
)),
(
enum_def
,
enum_def
.variant_of_def
(
def
)),
_
=>
{
let
name
=
pprust
::
path_to_string
(
path
);
span_err!
(
tcx
.sess
,
pat
.span
,
E0163
,
...
...
@@ -582,9 +581,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
.map
(|
substs
|
substs
.substs
.clone
())
.unwrap_or_else
(||
Substs
::
empty
());
let
struct_fields
=
tcx
.struct_fields
(
variant_def_id
,
&
item_substs
);
check_struct_pat_fields
(
pcx
,
pat
.span
,
fields
,
&
struct_fields
,
variant_def_id
,
etc
);
check_struct_pat_fields
(
pcx
,
pat
.span
,
fields
,
variant
,
&
item_substs
,
etc
);
}
pub
fn
check_pat_enum
<
'a
,
'tcx
>
(
pcx
:
&
pat_ctxt
<
'a
,
'tcx
>
,
...
...
@@ -651,19 +648,23 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
ty
::
TyEnum
(
enum_def
,
expected_substs
)
if
def
==
def
::
DefVariant
(
enum_def
.did
,
def
.def_id
(),
false
)
=>
{
let
variant
=
tcx
.enum_variant_with_id
(
enum_def
.did
,
def
.def_id
());
(
variant
.args
.iter
()
.map
(|
t
|
fcx
.instantiate_type_scheme
(
pat
.span
,
expected_substs
,
t
))
.collect
(),
let
variant
=
enum_def
.variant_of_def
(
def
);
(
variant
.fields
.iter
()
.map
(|
f
|
fcx
.instantiate_type_scheme
(
pat
.span
,
expected_substs
,
&
f
.unsubst_ty
()))
.collect
(),
"variant"
)
}
ty
::
TyStruct
(
struct_def
,
expected_substs
)
=>
{
let
struct_fields
=
tcx
.struct_fields
(
struct_def
.did
,
expected_substs
);
(
struct_fields
.iter
()
.map
(|
field
|
fcx
.instantiate_type_scheme
(
pat
.span
,
expected_substs
,
&
field
.mt.ty
))
.collect
(),
(
struct_def
.struct_variant
()
.fields
.iter
()
.map
(|
f
|
fcx
.instantiate_type_scheme
(
pat
.span
,
expected_substs
,
&
f
.unsubst_ty
()))
.collect
(),
"struct"
)
}
_
=>
{
...
...
@@ -716,15 +717,15 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
pub
fn
check_struct_pat_fields
<
'a
,
'tcx
>
(
pcx
:
&
pat_ctxt
<
'a
,
'tcx
>
,
span
:
Span
,
fields
:
&
'tcx
[
Spanned
<
ast
::
FieldPat
>
],
struct_fields
:
&
[
ty
::
Field
<
'tcx
>
]
,
s
truct_id
:
ast
::
DefId
,
variant
:
&
ty
::
VariantDef
<
'tcx
>
,
s
ubsts
:
&
Substs
<
'tcx
>
,
etc
:
bool
)
{
let
tcx
=
pcx
.fcx.ccx.tcx
;
// Index the struct fields' types.
let
field_
type_map
=
struct_
fields
let
field_
map
=
variant
.
fields
.iter
()
.map
(|
field
|
(
field
.name
,
field
.mt.ty
))
.map
(|
field
|
(
field
.name
,
field
))
.collect
::
<
FnvHashMap
<
_
,
_
>>
();
// Keep track of which fields have already appeared in the pattern.
...
...
@@ -732,7 +733,7 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
// Typecheck each field.
for
&
Spanned
{
node
:
ref
field
,
span
}
in
fields
{
let
field_ty
pe
=
match
used_fields
.entry
(
field
.ident.name
)
{
let
field_ty
=
match
used_fields
.entry
(
field
.ident.name
)
{
Occupied
(
occupied
)
=>
{
span_err!
(
tcx
.sess
,
span
,
E0025
,
"field `{}` bound multiple times in the pattern"
,
...
...
@@ -744,25 +745,24 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
}
Vacant
(
vacant
)
=>
{
vacant
.insert
(
span
);
field_type_map
.get
(
&
field
.ident.name
)
.cloned
()
field_map
.get
(
&
field
.ident.name
)
.map
(|
f
|
pcx
.fcx
.field_ty
(
span
,
f
,
substs
))
.unwrap_or_else
(||
{
span_err!
(
tcx
.sess
,
span
,
E0026
,
"struct `{}` does not have a field named `{}`"
,
tcx
.item_path_str
(
struct_
id
),
tcx
.item_path_str
(
variant
.d
id
),
field
.ident
);
tcx
.types.err
})
}
};
let
field_type
=
pcx
.fcx
.normalize_associated_types_in
(
span
,
&
field_type
);
check_pat
(
pcx
,
&*
field
.pat
,
field_type
);
check_pat
(
pcx
,
&*
field
.pat
,
field_ty
);
}
// Report an error if not all the fields were specified.
if
!
etc
{
for
field
in
struct_
fields
for
field
in
variant
.
fields
.iter
()
.filter
(|
field
|
!
used_fields
.contains_key
(
&
field
.name
))
{
span_err!
(
tcx
.sess
,
span
,
E0027
,
...
...
src/librustc_typeck/check/cast.rs
浏览文件 @
5f3c1412
...
...
@@ -80,9 +80,10 @@ fn unsize_kind<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
Some
(
UnsizeKind
::
Length
),
ty
::
TyTrait
(
ref
tty
)
=>
Some
(
UnsizeKind
::
Vtable
(
tty
.principal_def_id
())),
ty
::
TyStruct
(
def
,
substs
)
=>
{
match
fcx
.tcx
()
.struct_fields
(
def
.did
,
substs
)
.pop
()
{
// FIXME(arielb1): do some kind of normalization
match
def
.struct_variant
()
.fields
.last
()
{
None
=>
None
,
Some
(
f
)
=>
unsize_kind
(
fcx
,
f
.
mt.ty
)
Some
(
f
)
=>
unsize_kind
(
fcx
,
f
.
ty
(
fcx
.tcx
(),
substs
)
)
}
}
// We should really try to normalize here.
...
...
@@ -223,8 +224,8 @@ fn do_check<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
use
middle
::
cast
::
IntTy
::
*
;
use
middle
::
cast
::
CastTy
::
*
;
let
(
t_from
,
t_cast
)
=
match
(
CastTy
::
from_ty
(
fcx
.tcx
(),
self
.expr_ty
),
CastTy
::
from_ty
(
fcx
.tcx
(),
self
.cast_ty
))
{
let
(
t_from
,
t_cast
)
=
match
(
CastTy
::
from_ty
(
self
.expr_ty
),
CastTy
::
from_ty
(
self
.cast_ty
))
{
(
Some
(
t_from
),
Some
(
t_cast
))
=>
(
t_from
,
t_cast
),
_
=>
{
return
Err
(
CastError
::
NonScalar
)
...
...
src/librustc_typeck/check/dropck.rs
浏览文件 @
5f3c1412
...
...
@@ -285,26 +285,28 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
// no need for an additional note if the overflow
// was somehow on the root.
}
TypeContext
::
EnumVariant
{
def_id
,
variant
,
arg
_index
}
=>
{
TypeContext
::
ADT
{
def_id
,
variant
,
field
,
field
_index
}
=>
{
// FIXME (pnkfelix): eventually lookup arg_name
// for the given index on struct variants.
span_note!
(
rcx
.tcx
()
.sess
,
span
,
"overflowed on enum {} variant {} argument {} type: {}"
,
tcx
.item_path_str
(
def_id
),
variant
,
arg_index
,
detected_on_typ
);
}
TypeContext
::
Struct
{
def_id
,
field
}
=>
{
span_note!
(
rcx
.tcx
()
.sess
,
span
,
"overflowed on struct {} field {} type: {}"
,
tcx
.item_path_str
(
def_id
),
field
,
detected_on_typ
);
// TODO: be saner
if
let
ty
::
ADTKind
::
Enum
=
tcx
.lookup_adt_def
(
def_id
)
.adt_kind
()
{
span_note!
(
rcx
.tcx
()
.sess
,
span
,
"overflowed on enum {} variant {} argument {} type: {}"
,
tcx
.item_path_str
(
def_id
),
variant
,
field_index
,
detected_on_typ
);
}
else
{
span_note!
(
rcx
.tcx
()
.sess
,
span
,
"overflowed on struct {} field {} type: {}"
,
tcx
.item_path_str
(
def_id
),
field
,
detected_on_typ
);
}
}
}
}
...
...
@@ -318,14 +320,11 @@ enum Error<'tcx> {
#[derive(Copy,
Clone)]
enum
TypeContext
{
Root
,
EnumVariant
{
ADT
{
def_id
:
ast
::
DefId
,
variant
:
ast
::
Name
,
arg_index
:
usize
,
},
Struct
{
def_id
:
ast
::
DefId
,
field
:
ast
::
Name
,
field_index
:
usize
}
}
...
...
@@ -437,41 +436,23 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
cx
,
context
,
ity
,
depth
+
1
)
}
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
did
=
def
.did
;
let
fields
=
tcx
.lookup_struct_fields
(
did
);
for
field
in
&
fields
{
let
fty
=
tcx
.lookup_field_type
(
did
,
field
.id
,
substs
);
let
fty
=
cx
.rcx.fcx
.resolve_type_vars_if_possible
(
cx
.rcx.fcx
.normalize_associated_types_in
(
cx
.span
,
&
fty
));
try!
(
iterate_over_potentially_unsafe_regions_in_type
(
cx
,
TypeContext
::
Struct
{
def_id
:
did
,
field
:
field
.name
,
},
fty
,
depth
+
1
))
}
Ok
(())
}
ty
::
TyEnum
(
def
,
substs
)
=>
{
ty
::
TyStruct
(
def
,
substs
)
|
ty
::
TyEnum
(
def
,
substs
)
=>
{
let
did
=
def
.did
;
let
all_variant_info
=
tcx
.substd_enum_variants
(
did
,
substs
);
for
variant_info
in
&
all_variant_info
{
for
(
i
,
fty
)
in
variant_info
.args
.iter
()
.enumerate
()
{
for
variant
in
&
def
.variants
{
for
(
i
,
field
)
in
variant
.fields
.iter
()
.enumerate
()
{
let
fty
=
field
.ty
(
tcx
,
substs
);
let
fty
=
cx
.rcx.fcx
.resolve_type_vars_if_possible
(
cx
.rcx.fcx
.normalize_associated_types_in
(
cx
.span
,
&
fty
));
try!
(
iterate_over_potentially_unsafe_regions_in_type
(
cx
,
TypeContext
::
EnumVariant
{
TypeContext
::
ADT
{
def_id
:
did
,
variant
:
variant_info
.name
,
arg_index
:
i
,
field
:
field
.name
,
variant
:
variant
.name
,
field_index
:
i
},
fty
,
depth
+
1
))
;
depth
+
1
))
}
}
Ok
(())
...
...
src/librustc_typeck/check/method/suggest.rs
浏览文件 @
5f3c1412
...
...
@@ -66,9 +66,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// If the item has the name of a field, give a help note
if
let
(
&
ty
::
TyStruct
(
def
,
substs
),
Some
(
expr
))
=
(
&
rcvr_ty
.sty
,
rcvr_expr
)
{
let
fields
=
cx
.lookup_struct_fields
(
def
.did
);
if
let
Some
(
field
)
=
fields
.iter
()
.find
(|
f
|
f
.name
==
item_name
)
{
if
let
Some
(
field
)
=
def
.struct_variant
()
.find_field_named
(
item_name
)
{
let
expr_string
=
match
cx
.sess
.codemap
()
.span_to_snippet
(
expr
.span
)
{
Ok
(
expr_string
)
=>
expr_string
,
_
=>
"s"
.into
()
// Default to a generic placeholder for the
...
...
@@ -89,7 +87,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
};
// Determine if the field can be used as a function in some way
let
field_ty
=
cx
.lookup_field_type
(
def
.did
,
field
.id
,
substs
);
let
field_ty
=
field
.ty
(
cx
,
substs
);
if
let
Ok
(
fn_once_trait_did
)
=
cx
.lang_items
.require
(
FnOnceTraitLangItem
)
{
let
infcx
=
fcx
.infcx
();
infcx
.probe
(|
_
|
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
5f3c1412
...
...
@@ -1674,34 +1674,19 @@ pub fn add_obligations_for_parameters(&self,
}
}
// Only for fields! Returns <none> for methods>
// Indifferent to privacy flags
pub
fn
lookup_field_ty
(
&
self
,
span
:
Span
,
struct_def
:
&
'tcx
ty
::
ADTDef
<
'tcx
>
,
items
:
&
[
ty
::
FieldTy
],
fieldname
:
ast
::
Name
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
Option
<
Ty
<
'tcx
>>
{
let
o_field
=
items
.iter
()
.find
(|
f
|
f
.name
==
fieldname
);
o_field
.map
(|
f
|
self
.tcx
()
.lookup_field_type
(
struct_def
.did
,
f
.id
,
substs
))
.map
(|
t
|
self
.normalize_associated_types_in
(
span
,
&
t
))
}
pub
fn
lookup_tup_field_ty
(
&
self
,
span
:
Span
,
struct_def
:
&
'tcx
ty
::
ADTDef
<
'tcx
>
,
items
:
&
[
ty
::
FieldTy
],
idx
:
usize
,
substs
:
&
subst
::
Substs
<
'tcx
>
)
->
Option
<
Ty
<
'tcx
>>
// FIXME(arielb1): use this instead of field.ty everywhere
pub
fn
field_ty
(
&
self
,
span
:
Span
,
field
:
&
ty
::
FieldDef
<
'tcx
>
,
substs
:
&
Substs
<
'tcx
>
)
->
Ty
<
'tcx
>
{
let
o_field
=
if
idx
<
items
.len
()
{
Some
(
&
items
[
idx
])
}
else
{
None
};
o_field
.map
(|
f
|
self
.tcx
()
.lookup_field_type
(
struct_def
.did
,
f
.id
,
substs
))
.map
(|
t
|
self
.normalize_associated_types_in
(
span
,
&
t
))
self
.normalize_associated_types_in
(
span
,
&
field
.ty
(
self
.tcx
(),
substs
))
}
// Only for fields! Returns <none> for methods>
// Indifferent to privacy flags
fn
check_casts
(
&
self
)
{
let
mut
deferred_cast_checks
=
self
.inh.deferred_cast_checks
.borrow_mut
();
for
cast
in
deferred_cast_checks
.drain
(
..
)
{
...
...
@@ -2880,9 +2865,9 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
match
base_t
.sty
{
ty
::
TyStruct
(
base_def
,
substs
)
=>
{
debug!
(
"struct named {:?}"
,
base_t
);
let
fields
=
tcx
.lookup_struct_fields
(
base_def
.did
);
fcx
.lookup_field_ty
(
expr
.span
,
base_def
,
&
fields
[
..
],
field
.node.name
,
&
(
*
substs
))
base_def
.struct_variant
()
.find_field_named
(
field
.node.name
)
.map
(|
f
|
fcx
.field_ty
(
expr
.span
,
f
,
substs
))
}
_
=>
None
}
...
...
@@ -2920,7 +2905,7 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
},
expr_t
,
None
);
if
let
ty
::
TyStruct
(
def
,
_
)
=
expr_t
.sty
{
suggest_field_names
(
def
.
did
,
field
,
tcx
,
vec!
[]);
suggest_field_names
(
def
.
struct_variant
()
,
field
,
tcx
,
vec!
[]);
}
}
...
...
@@ -2928,23 +2913,22 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
}
// displays hints about the closest matches in field names
fn
suggest_field_names
<
'tcx
>
(
variant
_id
:
ast
::
DefId
,
fn
suggest_field_names
<
'tcx
>
(
variant
:
&
ty
::
VariantDef
<
'tcx
>
,
field
:
&
ast
::
SpannedIdent
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
skip
:
Vec
<
InternedString
>
)
{
let
name
=
field
.node.name
.as_str
();
// only find fits with at least one matching letter
let
mut
best_dist
=
name
.len
();
let
fields
=
tcx
.lookup_struct_fields
(
variant_id
);
let
mut
best
=
None
;
for
elem
in
&
fields
{
for
elem
in
&
variant
.
fields
{
let
n
=
elem
.name
.as_str
();
// ignore already set fields
if
skip
.iter
()
.any
(|
x
|
*
x
==
n
)
{
continue
;
}
// ignore private fields from non-local crates
if
variant
_
id
.krate
!=
ast
::
LOCAL_CRATE
&&
elem
.vis
!=
Visibility
::
Public
{
if
variant
.d
id.krate
!=
ast
::
LOCAL_CRATE
&&
elem
.vis
!=
Visibility
::
Public
{
continue
;
}
let
dist
=
lev_distance
(
&
n
,
&
name
);
...
...
@@ -2965,7 +2949,6 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
lvalue_pref
:
LvaluePreference
,
base
:
&
'tcx
ast
::
Expr
,
idx
:
codemap
::
Spanned
<
usize
>
)
{
let
tcx
=
fcx
.ccx.tcx
;
check_expr_with_lvalue_pref
(
fcx
,
base
,
lvalue_pref
);
let
expr_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
fcx
.expr_ty
(
base
));
...
...
@@ -2983,9 +2966,10 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
tuple_like
=
base_def
.struct_variant
()
.is_tuple_struct
();
if
tuple_like
{
debug!
(
"tuple struct named {:?}"
,
base_t
);
let
fields
=
tcx
.lookup_struct_fields
(
base_def
.did
);
fcx
.lookup_tup_field_ty
(
expr
.span
,
base_def
,
&
fields
[
..
],
idx
.node
,
&
(
*
substs
))
base_def
.struct_variant
()
.fields
.get
(
idx
.node
)
.map
(|
f
|
fcx
.field_ty
(
expr
.span
,
f
,
substs
))
}
else
{
None
}
...
...
@@ -3025,71 +3009,63 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
fcx
.write_error
(
expr
.id
);
}
fn
report_unknown_field
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
variant
:
&
ty
::
VariantDef
<
'tcx
>
,
field
:
&
ast
::
Field
,
skip_fields
:
&
[
ast
::
Field
])
{
fcx
.type_error_message
(
field
.ident.span
,
|
actual
|
if
let
ty
::
TyEnum
(
..
)
=
ty
.sty
{
format!
(
"struct variant `{}::{}` has no field named `{}`"
,
actual
,
variant
.name
.as_str
(),
field
.ident.node
)
}
else
{
format!
(
"structure `{}` has no field named `{}`"
,
actual
,
field
.ident.node
)
},
ty
,
None
);
// prevent all specified fields from being suggested
let
skip_fields
=
skip_fields
.iter
()
.map
(|
ref
x
|
x
.ident.node.name
.as_str
());
suggest_field_names
(
variant
,
&
field
.ident
,
fcx
.tcx
(),
skip_fields
.collect
());
}
fn
check_struct_or_variant_fields
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
adt_ty
:
Ty
<
'tcx
>
,
span
:
Span
,
variant_id
:
ast
::
DefId
,
substitutions
:
&
'tcx
subst
::
Substs
<
'tcx
>
,
field_types
:
&
[
ty
::
FieldTy
],
ast_fields
:
&
'tcx
[
ast
::
Field
],
check_completeness
:
bool
)
->
Result
<
(),()
>
{
let
tcx
=
fcx
.ccx.tcx
;
let
(
adt_def
,
is_enum
)
=
match
adt_ty
.sty
{
ty
::
TyStruct
(
def
,
_
)
=>
(
def
,
false
),
ty
::
TyEnum
(
def
,
_
)
=>
(
def
,
true
),
let
(
adt_def
,
substs
)
=
match
adt_ty
.sty
{
ty
::
TyStruct
(
def
,
substs
)
|
ty
::
TyEnum
(
def
,
substs
)
=>
(
def
,
substs
),
_
=>
tcx
.sess
.span_bug
(
span
,
"non-ADT passed to check_struct_or_variant_fields"
)
};
let
variant
=
adt_def
.variant_with_id
(
variant_id
);
let
mut
class_field_map
=
FnvHashMap
();
let
mut
fields_found
=
0
;
for
field
in
field_types
{
class_field_map
.insert
(
field
.name
,
(
field
.id
,
false
));
let
mut
remaining_fields
=
FnvHashMap
();
for
field
in
&
variant
.fields
{
remaining_fields
.insert
(
field
.name
,
field
);
}
let
mut
error_happened
=
false
;
// Typecheck each field.
for
field
in
ast_fields
{
let
mut
expected_field_type
=
tcx
.types.err
;
let
pair
=
class_field_map
.get
(
&
field
.ident.node.name
)
.cloned
();
match
pair
{
None
=>
{
fcx
.type_error_message
(
field
.ident.span
,
|
actual
|
if
is_enum
{
let
variant_type
=
tcx
.enum_variant_with_id
(
adt_def
.did
,
variant_id
);
format!
(
"struct variant `{}::{}` has no field named `{}`"
,
actual
,
variant_type
.name
.as_str
(),
field
.ident.node
)
}
else
{
format!
(
"structure `{}` has no field named `{}`"
,
actual
,
field
.ident.node
)
},
adt_ty
,
None
);
// prevent all specified fields from being suggested
let
skip_fields
=
ast_fields
.iter
()
.map
(|
ref
x
|
x
.ident.node.name
.as_str
());
suggest_field_names
(
variant_id
,
&
field
.ident
,
tcx
,
skip_fields
.collect
());
error_happened
=
true
;
}
Some
((
_
,
true
))
=>
{
let
expected_field_type
;
if
let
Some
(
v_field
)
=
remaining_fields
.remove
(
&
field
.ident.node.name
)
{
expected_field_type
=
fcx
.field_ty
(
field
.span
,
v_field
,
substs
);
}
else
{
error_happened
=
true
;
expected_field_type
=
tcx
.types.err
;
if
let
Some
(
_
)
=
variant
.find_field_named
(
field
.ident.node.name
)
{
span_err!
(
fcx
.tcx
()
.sess
,
field
.ident.span
,
E0062
,
"field `{}` specified more than once"
,
field
.ident.node
);
error_happened
=
true
;
}
Some
((
field_id
,
false
))
=>
{
expected_field_type
=
tcx
.lookup_field_type
(
variant_id
,
field_id
,
substitutions
);
expected_field_type
=
fcx
.normalize_associated_types_in
(
field
.span
,
&
expected_field_type
);
class_field_map
.insert
(
field
.ident.node.name
,
(
field_id
,
true
));
fields_found
+=
1
;
}
else
{
report_unknown_field
(
fcx
,
adt_ty
,
variant
,
field
,
ast_fields
);
}
}
...
...
@@ -3098,25 +3074,19 @@ fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
check_expr_coercable_to_type
(
fcx
,
&*
field
.expr
,
expected_field_type
);
}
if
check_completeness
&&
!
error_happened
{
// Make sure the programmer specified all the fields.
assert
!
(
fields_found
<=
field_types
.len
());
if
fields_found
<
field_types
.len
()
{
let
mut
missing_fields
=
Vec
::
new
();
for
class_field
in
field_types
{
let
name
=
class_field
.name
;
let
(
_
,
seen
)
=
*
class_field_map
.get
(
&
name
)
.unwrap
();
if
!
seen
{
missing_fields
.push
(
format!
(
"`{}`"
,
name
))
}
}
span_err!
(
tcx
.sess
,
span
,
E0063
,
"missing field{}: {}"
,
if
missing_fields
.len
()
==
1
{
""
}
else
{
"s"
},
missing_fields
.join
(
", "
));
}
if
check_completeness
&&
!
error_happened
&&
!
remaining_fields
.is_empty
()
{
error_happened
=
true
;
span_err!
(
tcx
.sess
,
span
,
E0063
,
"missing field{}: {}"
,
if
remaining_fields
.len
()
==
1
{
""
}
else
{
"s"
},
remaining_fields
.keys
()
.map
(|
n
|
format!
(
"`{}`"
,
n
))
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
));
}
if
error_happened
{
Err
(())
}
else
{
Ok
(())
}
...
...
@@ -3133,17 +3103,14 @@ fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
// Generate the struct type.
let
TypeAndSubsts
{
ty
:
mut
struct_type
,
substs
:
struct_substs
substs
:
_
}
=
fcx
.instantiate_type
(
span
,
struct_def
.did
);
// Look up and check the fields.
let
class_fields
=
tcx
.lookup_struct_fields
(
struct_def
.did
);
let
res
=
check_struct_or_variant_fields
(
fcx
,
struct_type
,
span
,
struct_def
.did
,
fcx
.ccx.tcx
.mk_substs
(
struct_substs
),
&
class_fields
[
..
],
fields
,
base_expr
.is_none
());
if
res
.is_err
()
{
...
...
@@ -3168,23 +3135,18 @@ fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
enum_id
:
ast
::
DefId
,
variant_id
:
ast
::
DefId
,
fields
:
&
'tcx
[
ast
::
Field
])
{
let
tcx
=
fcx
.ccx.tcx
;
// Look up the number of type parameters and the raw type, and
// determine whether the enum is region-parameterized.
let
TypeAndSubsts
{
ty
:
enum_type
,
substs
:
substitutions
substs
:
_
}
=
fcx
.instantiate_type
(
span
,
enum_id
);
// Look up and check the enum variant fields.
let
variant_fields
=
tcx
.lookup_struct_fields
(
variant_id
);
let
_
=
check_struct_or_variant_fields
(
fcx
,
enum_type
,
span
,
variant_id
,
fcx
.ccx.tcx
.mk_substs
(
substitutions
),
&
variant_fields
[
..
],
fields
,
true
);
fcx
.write_ty
(
id
,
enum_type
);
...
...
@@ -4295,14 +4257,13 @@ pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
}
match
t
.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
fields
=
tcx
.lookup_struct_fields
(
def
.did
)
;
let
fields
=
&
def
.struct_variant
()
.fields
;
if
fields
.is_empty
()
{
span_err!
(
tcx
.sess
,
sp
,
E0075
,
"SIMD vector cannot be empty"
);
return
;
}
let
e
=
tcx
.lookup_field_type
(
def
.did
,
fields
[
0
]
.id
,
substs
);
if
!
fields
.iter
()
.all
(
|
f
|
tcx
.lookup_field_type
(
def
.did
,
f
.id
,
substs
)
==
e
)
{
let
e
=
fields
[
0
]
.ty
(
tcx
,
substs
);
if
!
fields
.iter
()
.all
(|
f
|
f
.ty
(
tcx
,
substs
)
==
e
)
{
span_err!
(
tcx
.sess
,
sp
,
E0076
,
"SIMD vector should be homogeneous"
);
return
;
}
...
...
@@ -4370,10 +4331,7 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let
def_id
=
local_def
(
id
);
// ty::enum_variants guards against discriminant overflows, so
// we need not check for that.
let
variants
=
ccx
.tcx
.enum_variants
(
def_id
);
let
variants
=
&
ccx
.tcx
.lookup_adt_def
(
def_id
)
.variants
;
for
(
v
,
variant
)
in
vs
.iter
()
.zip
(
variants
.iter
())
{
let
current_disr_val
=
variant
.disr_val
;
...
...
@@ -4382,7 +4340,7 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
Some
(
i
)
=>
{
span_err!
(
ccx
.tcx.sess
,
v
.span
,
E0081
,
"discriminant value `{}` already exists"
,
disr_vals
[
i
]);
span_note!
(
ccx
.tcx.sess
,
ccx
.tcx.map
.span
(
variants
[
i
]
.id.node
),
span_note!
(
ccx
.tcx.sess
,
ccx
.tcx.map
.span
(
variants
[
i
]
.
d
id.node
),
"conflicting discriminant here"
)
}
None
=>
{}
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
5f3c1412
...
...
@@ -483,10 +483,9 @@ fn check_implementations_of_coerce_unsized(&self) {
}
let
origin
=
infer
::
Misc
(
span
);
let
fields
=
tcx
.lookup_struct_fields
(
def_a
.did
)
;
let
fields
=
&
def_a
.struct_variant
()
.fields
;
let
diff_fields
=
fields
.iter
()
.enumerate
()
.filter_map
(|(
i
,
f
)|
{
let
ty
=
tcx
.lookup_field_type_unsubstituted
(
def_a
.did
,
f
.id
);
let
(
a
,
b
)
=
(
ty
.subst
(
tcx
,
substs_a
),
ty
.subst
(
tcx
,
substs_b
));
let
(
a
,
b
)
=
(
f
.ty
(
tcx
,
substs_a
),
f
.ty
(
tcx
,
substs_b
));
if
infcx
.sub_types
(
false
,
origin
,
b
,
a
)
.is_ok
()
{
None
}
else
{
...
...
src/librustc_typeck/collect.rs
浏览文件 @
5f3c1412
...
...
@@ -1174,33 +1174,50 @@ fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
Ok
(
ConstVal
::
Int
(
val
))
=>
Some
(
val
as
ty
::
Disr
),
Ok
(
ConstVal
::
Uint
(
val
))
=>
Some
(
val
as
ty
::
Disr
),
Ok
(
_
)
=>
{
// let sign_desc = if repr_type
.is_signed() {
//
"signed"
//
} else {
//
"unsigned"
//
};
// span_err!(self
.sess, e.span, E0079,
//
"expected {} integer constant",
//
sign_desc);
let
sign_desc
=
if
repr_ty
.is_signed
()
{
"signed"
}
else
{
"unsigned"
};
span_err!
(
tcx
.sess
,
e
.span
,
E0079
,
"expected {} integer constant"
,
sign_desc
);
None
},
Err
(
_
)
=>
{
// span_err!(self
.sess, err.span, E0080,
//
"constant evaluation error: {}",
//
err.description());
Err
(
err
)
=>
{
span_err!
(
tcx
.sess
,
err
.span
,
E0080
,
"constant evaluation error: {}"
,
err
.description
());
None
}
}
}
fn
next_disr
(
repr_type
:
attr
::
IntType
,
fn
report_discrim_overflow
(
tcx
:
&
ty
::
ctxt
,
variant_span
:
Span
,
variant_name
:
&
str
,
repr_type
:
attr
::
IntType
,
prev_val
:
ty
::
Disr
)
{
let
computed_value
=
repr_type
.disr_wrap_incr
(
Some
(
prev_val
));
let
computed_value
=
repr_type
.disr_string
(
computed_value
);
let
prev_val
=
repr_type
.disr_string
(
prev_val
);
let
repr_type
=
repr_type
.to_ty
(
tcx
);
span_err!
(
tcx
.sess
,
variant_span
,
E0370
,
"enum discriminant overflowed on value after {}: {};
\
set explicitly via {} = {} if that is desired outcome"
,
prev_val
,
repr_type
,
variant_name
,
computed_value
);
}
fn
next_disr
(
tcx
:
&
ty
::
ctxt
,
v
:
&
ast
::
Variant
,
repr_type
:
attr
::
IntType
,
prev_disr_val
:
Option
<
ty
::
Disr
>
)
->
Option
<
ty
::
Disr
>
{
if
let
Some
(
prev_disr_val
)
=
prev_disr_val
{
let
result
=
repr_type
.disr_incr
(
prev_disr_val
);
//
if let None = result {
// self.report_discrim_overflow(
v.span, &v.node.name.name.as_str(),
//
repr_type, prev_disr_val);
//
}
if
let
None
=
result
{
report_discrim_overflow
(
tcx
,
v
.span
,
&
v
.node.name.name
.as_str
(),
repr_type
,
prev_disr_val
);
}
result
}
else
{
Some
(
ty
::
INITIAL_DISCRIMINANT_VALUE
)
...
...
@@ -1240,7 +1257,7 @@ fn convert_enum_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
let
variants
=
def
.variants
.iter
()
.map
(|
v
|
{
let
disr
=
match
v
.node.disr_expr
{
Some
(
ref
e
)
=>
evaluate_disr_expr
(
tcx
,
repr_type_ty
,
e
),
None
=>
next_disr
(
repr_type
,
prev_disr
)
None
=>
next_disr
(
tcx
,
v
,
repr_type
,
prev_disr
)
}
.unwrap_or
(
repr_type
.disr_wrap_incr
(
prev_disr
));
let
v
=
convert_enum_variant
(
tcx
,
v
,
disr
);
...
...
src/librustc_typeck/diagnostics.rs
浏览文件 @
5f3c1412
...
...
@@ -883,6 +883,64 @@ struct Foo { x: Option<Box<Foo>> }
```
"##
,
E0079
:
r##"
Enum variants which contain no data can be given a custom integer
representation. This error indicates that the value provided is not an integer
literal and is therefore invalid.
For example, in the following code,
```
enum Foo {
Q = "32"
}
```
we try to set the representation to a string.
There's no general fix for this; if you can work with an integer then just set
it to one:
```
enum Foo {
Q = 32
}
```
however if you actually wanted a mapping between variants and non-integer
objects, it may be preferable to use a method with a match instead:
```
enum Foo { Q }
impl Foo {
fn get_str(&self) -> &'static str {
match *self {
Foo::Q => "32",
}
}
}
```
"##
,
E0080
:
r##"
This error indicates that the compiler was unable to sensibly evaluate an
integer expression provided as an enum discriminant. Attempting to divide by 0
or causing integer overflow are two ways to induce this error. For example:
```
enum Enum {
X = (1 << 500),
Y = (1 / 0)
}
```
Ensure that the expressions given can be evaluated as the desired integer type.
See the FFI section of the Reference for more information about using a custom
integer type:
https://doc.rust-lang.org/reference.html#ffi-attributes
"##
,
E0081
:
r##"
Enum discriminants are used to differentiate enum variants stored in memory.
This error indicates that the same value was used for two or more variants,
...
...
@@ -2510,6 +2568,7 @@ struct Foo<'a, T: 'a> {
E0366
,
// dropck forbid specialization to concrete type or region
E0367
,
// dropck forbid specialization to predicate not in struct/enum
E0369
,
// binary operation `<op>` cannot be applied to types
E0370
,
// discriminant overflow
E0374
,
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, none found
E0375
,
// the trait `CoerceUnsized` may only be implemented for a coercion
...
...
src/librustc_typeck/variance.rs
浏览文件 @
5f3c1412
...
...
@@ -602,7 +602,7 @@ fn visit_item(&mut self, item: &ast::Item) {
debug!
(
"visit_item item={}"
,
tcx
.map
.node_to_string
(
item
.id
));
match
item
.node
{
ast
::
ItemEnum
(
ref
enum_definition
,
_
)
=>
{
ast
::
ItemEnum
(
..
)
|
ast
::
ItemStruct
(
..
)
=>
{
let
scheme
=
tcx
.lookup_item_type
(
did
);
// Not entirely obvious: constraints on structs/enums do not
...
...
@@ -611,44 +611,12 @@ fn visit_item(&mut self, item: &ast::Item) {
//
// self.add_constraints_from_generics(&scheme.generics);
// Hack: If we directly call `ty::enum_variants`, it
// annoyingly takes it upon itself to run off and
// evaluate the discriminants eagerly (*grumpy* that's
// not the typical pattern). This results in double
// error messages because typeck goes off and does
// this at a later time. All we really care about is
// the types of the variant arguments, so we just call
// `ty::VariantInfo::from_ast_variant()` ourselves
// here, mainly so as to mask the differences between
// struct-like enums and so forth.
for
ast_variant
in
&
enum_definition
.variants
{
let
variant
=
ty
::
VariantInfo
::
from_ast_variant
(
tcx
,
&**
ast_variant
,
/*discriminant*/
0
);
for
arg_ty
in
&
variant
.args
{
self
.add_constraints_from_ty
(
&
scheme
.generics
,
*
arg_ty
,
self
.covariant
);
}
for
field
in
tcx
.lookup_adt_def
(
did
)
.all_fields
()
{
self
.add_constraints_from_ty
(
&
scheme
.generics
,
field
.unsubst_ty
(),
self
.covariant
);
}
}
ast
::
ItemStruct
(
..
)
=>
{
let
scheme
=
tcx
.lookup_item_type
(
did
);
// Not entirely obvious: constraints on structs/enums do not
// affect the variance of their type parameters. See discussion
// in comment at top of module.
//
// self.add_constraints_from_generics(&scheme.generics);
let
struct_fields
=
tcx
.lookup_struct_fields
(
did
);
for
field_info
in
&
struct_fields
{
assert_eq!
(
field_info
.id.krate
,
ast
::
LOCAL_CRATE
);
let
field_ty
=
tcx
.node_id_to_type
(
field_info
.id.node
);
self
.add_constraints_from_ty
(
&
scheme
.generics
,
field_ty
,
self
.covariant
);
}
}
ast
::
ItemTrait
(
..
)
=>
{
let
trait_def
=
tcx
.lookup_trait_def
(
did
);
self
.add_constraints_from_trait_ref
(
&
trait_def
.generics
,
...
...
src/librustdoc/clean/inline.rs
浏览文件 @
5f3c1412
...
...
@@ -185,17 +185,17 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
let
t
=
tcx
.lookup_item_type
(
did
);
let
predicates
=
tcx
.lookup_predicates
(
did
);
let
fields
=
tcx
.lookup_struct_fields
(
did
);
let
variant
=
tcx
.lookup_adt_def
(
did
)
.struct_variant
(
);
clean
::
Struct
{
struct_type
:
match
&*
fields
{
struct_type
:
match
&*
variant
.
fields
{
[]
=>
doctree
::
Unit
,
[
ref
f
]
if
f
.name
==
unnamed_field
.name
=>
doctree
::
Newtype
,
[
ref
f
,
..
]
if
f
.name
==
unnamed_field
.name
=>
doctree
::
Tuple
,
_
=>
doctree
::
Plain
,
},
generics
:
(
&
t
.generics
,
&
predicates
,
subst
::
TypeSpace
)
.clean
(
cx
),
fields
:
fields
.clean
(
cx
),
fields
:
variant
.
fields
.clean
(
cx
),
fields_stripped
:
false
,
}
}
...
...
@@ -208,7 +208,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn
return
clean
::
EnumItem
(
clean
::
Enum
{
generics
:
(
&
t
.generics
,
&
predicates
,
subst
::
TypeSpace
)
.clean
(
cx
),
variants_stripped
:
false
,
variants
:
tcx
.enum_variants
(
edef
.did
)
.clean
(
cx
),
variants
:
edef
.variants
.clean
(
cx
),
})
}
_
=>
{}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
5f3c1412
...
...
@@ -1730,29 +1730,27 @@ fn clean(&self, cx: &DocContext) -> Item {
}
}
impl
Clean
<
Item
>
for
ty
::
FieldTy
{
impl
<
'tcx
>
Clean
<
Item
>
for
ty
::
FieldDef
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
Item
{
use
syntax
::
parse
::
token
::
special_idents
::
unnamed_field
;
use
rustc
::
metadata
::
csearch
;
let
attr_map
=
csearch
::
get_struct_field_attrs
(
&
cx
.tcx
()
.sess.cstore
,
self
.id
);
let
attr_map
=
csearch
::
get_struct_field_attrs
(
&
cx
.tcx
()
.sess.cstore
,
self
.
d
id
);
let
(
name
,
attrs
)
=
if
self
.name
==
unnamed_field
.name
{
(
None
,
None
)
}
else
{
(
Some
(
self
.name
),
Some
(
attr_map
.get
(
&
self
.id.node
)
.unwrap
()))
(
Some
(
self
.name
),
Some
(
attr_map
.get
(
&
self
.
d
id.node
)
.unwrap
()))
};
let
ty
=
cx
.tcx
()
.lookup_item_type
(
self
.id
);
Item
{
name
:
name
.clean
(
cx
),
attrs
:
attrs
.unwrap_or
(
&
Vec
::
new
())
.clean
(
cx
),
source
:
Span
::
empty
(),
visibility
:
Some
(
self
.vis
),
stability
:
get_stability
(
cx
,
self
.id
),
def_id
:
self
.id
,
inner
:
StructFieldItem
(
TypedStructField
(
ty
.ty
.clean
(
cx
))),
stability
:
get_stability
(
cx
,
self
.
d
id
),
def_id
:
self
.
d
id
,
inner
:
StructFieldItem
(
TypedStructField
(
self
.unsubst_ty
()
.clean
(
cx
))),
}
}
}
...
...
@@ -1858,22 +1856,24 @@ fn clean(&self, cx: &DocContext) -> Item {
}
}
impl
<
'tcx
>
Clean
<
Item
>
for
ty
::
Variant
Info
<
'tcx
>
{
impl
<
'tcx
>
Clean
<
Item
>
for
ty
::
Variant
Def
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
Item
{
// use syntax::parse::token::special_idents::unnamed_field;
let
kind
=
match
self
.arg_names
.as_ref
()
.map
(|
s
|
&**
s
)
{
None
|
Some
([])
if
self
.args
.is_empty
()
=>
CLikeVariant
,
None
|
Some
([])
=>
{
TupleVariant
(
self
.args
.clean
(
cx
))
let
kind
=
match
self
.kind
()
{
ty
::
VariantKind
::
Unit
=>
CLikeVariant
,
ty
::
VariantKind
::
Tuple
=>
{
TupleVariant
(
self
.fields
.iter
()
.map
(|
f
|
f
.unsubst_ty
()
.clean
(
cx
))
.collect
()
)
}
Some
(
s
)
=>
{
ty
::
VariantKind
::
Dict
=>
{
StructVariant
(
VariantStruct
{
struct_type
:
doctree
::
Plain
,
fields_stripped
:
false
,
fields
:
s
.iter
()
.zip
(
&
self
.args
)
.map
(|(
name
,
ty
)
|
{
fields
:
s
elf
.fields
.iter
()
.map
(|
field
|
{
Item
{
source
:
Span
::
empty
(),
name
:
Some
(
name
.clean
(
cx
)),
name
:
Some
(
field
.
name
.clean
(
cx
)),
attrs
:
Vec
::
new
(),
visibility
:
Some
(
ast
::
Public
),
// FIXME: this is not accurate, we need an id for
...
...
@@ -1883,10 +1883,10 @@ fn clean(&self, cx: &DocContext) -> Item {
// Struct variants are experimental and need
// more infrastructure work before we can get
// at the needed information here.
def_id
:
self
.id
,
stability
:
get_stability
(
cx
,
self
.id
),
def_id
:
self
.
d
id
,
stability
:
get_stability
(
cx
,
self
.
d
id
),
inner
:
StructFieldItem
(
TypedStructField
(
ty
.clean
(
cx
))
TypedStructField
(
field
.unsubst_ty
()
.clean
(
cx
))
)
}
})
.collect
()
...
...
@@ -1895,12 +1895,12 @@ fn clean(&self, cx: &DocContext) -> Item {
};
Item
{
name
:
Some
(
self
.name
.clean
(
cx
)),
attrs
:
inline
::
load_attrs
(
cx
,
cx
.tcx
(),
self
.id
),
attrs
:
inline
::
load_attrs
(
cx
,
cx
.tcx
(),
self
.
d
id
),
source
:
Span
::
empty
(),
visibility
:
Some
(
ast
::
Public
),
def_id
:
self
.id
,
def_id
:
self
.
d
id
,
inner
:
VariantItem
(
Variant
{
kind
:
kind
}),
stability
:
get_stability
(
cx
,
self
.id
),
stability
:
get_stability
(
cx
,
self
.
d
id
),
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录