Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4816e606
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,发现更多精彩内容 >>
提交
4816e606
编写于
7月 22, 2015
作者:
A
Ariel Ben-Yehuda
提交者:
Ariel Ben-Yehuda
8月 06, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
create VariantDef-s (but don't actually use them)
上级
213b6d71
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
504 addition
and
183 deletion
+504
-183
src/librustc/metadata/csearch.rs
src/librustc/metadata/csearch.rs
+2
-2
src/librustc/metadata/decoder.rs
src/librustc/metadata/decoder.rs
+104
-5
src/librustc/metadata/encoder.rs
src/librustc/metadata/encoder.rs
+44
-48
src/librustc/middle/check_match.rs
src/librustc/middle/check_match.rs
+1
-1
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+133
-18
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+1
-1
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+219
-108
未找到文件。
src/librustc/metadata/csearch.rs
浏览文件 @
4816e606
...
...
@@ -222,10 +222,10 @@ pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDe
decoder
::
get_trait_def
(
&*
cdata
,
def
.node
,
tcx
)
}
pub
fn
get_adt_def
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
def
:
ast
::
DefId
)
->
&
'tcx
ty
::
ADTDef
<
'tcx
>
{
pub
fn
get_adt_def
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
def
:
ast
::
DefId
)
->
&
'tcx
ty
::
ADTDef
_
<
'tcx
,
'tcx
>
{
let
cstore
=
&
tcx
.sess.cstore
;
let
cdata
=
cstore
.get_crate_data
(
def
.krate
);
decoder
::
get_adt_def
(
&*
cdata
,
def
.node
,
tcx
)
decoder
::
get_adt_def
(
&
cstore
.intr
,
&
*
cdata
,
def
.node
,
tcx
)
}
pub
fn
get_predicates
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
def
:
ast
::
DefId
)
...
...
src/librustc/metadata/decoder.rs
浏览文件 @
4816e606
...
...
@@ -108,7 +108,7 @@ fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8]) -> rbml::Doc<'a> {
find_item
(
item_id
,
items
)
}
#[derive(PartialEq)]
#[derive(
Debug,
PartialEq)]
enum
Family
{
ImmStatic
,
// c
MutStatic
,
// b
...
...
@@ -390,12 +390,111 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
}
}
pub
fn
get_adt_def
<
'tcx
>
(
cdata
:
Cmd
,
pub
fn
get_adt_def
<
'tcx
>
(
intr
:
&
IdentInterner
,
cdata
:
Cmd
,
item_id
:
ast
::
NodeId
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
&
'tcx
ty
::
ADTDef
<
'tcx
>
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
&
'tcx
ty
::
ADTDef
_
<
'tcx
,
'tcx
>
{
tcx
.intern_adt_def
(
ast
::
DefId
{
krate
:
cdata
.cnum
,
node
:
item_id
},
ty
::
ADTKind
::
Enum
)
fn
get_enum_variants
<
'tcx
>
(
intr
:
&
IdentInterner
,
cdata
:
Cmd
,
doc
:
rbml
::
Doc
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
Vec
<
ty
::
VariantDef_
<
'tcx
,
'tcx
>>
{
let
mut
disr_val
=
0
;
reader
::
tagged_docs
(
doc
,
tag_items_data_item_variant
)
.map
(|
p
|
{
let
did
=
translated_def_id
(
cdata
,
p
);
let
item
=
lookup_item
(
did
.node
,
cdata
.data
());
if
let
Some
(
disr
)
=
variant_disr_val
(
item
)
{
disr_val
=
disr
;
}
let
disr
=
disr_val
;
disr_val
=
disr_val
.wrapping_add
(
1
);
ty
::
VariantDef_
{
did
:
did
,
name
:
item_name
(
intr
,
item
),
fields
:
get_variant_fields
(
intr
,
cdata
,
item
,
tcx
),
disr_val
:
disr
}
})
.collect
()
}
fn
get_variant_fields
<
'tcx
>
(
intr
:
&
IdentInterner
,
cdata
:
Cmd
,
doc
:
rbml
::
Doc
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
Vec
<
ty
::
FieldDef_
<
'tcx
,
'tcx
>>
{
reader
::
tagged_docs
(
doc
,
tag_item_field
)
.map
(|
f
|
{
let
ff
=
item_family
(
f
);
match
ff
{
PublicField
|
InheritedField
=>
{},
_
=>
tcx
.sess
.bug
(
&
format!
(
"expected field, found {:?}"
,
ff
))
};
ty
::
FieldDef_
::
new
(
item_def_id
(
f
,
cdata
),
item_name
(
intr
,
f
),
struct_field_family_to_visibility
(
ff
))
})
.chain
(
reader
::
tagged_docs
(
doc
,
tag_item_unnamed_field
)
.map
(|
f
|
{
let
ff
=
item_family
(
f
);
ty
::
FieldDef_
::
new
(
item_def_id
(
f
,
cdata
),
special_idents
::
unnamed_field
.name
,
struct_field_family_to_visibility
(
ff
))
}))
.collect
()
}
fn
get_struct_variant
<
'tcx
>
(
intr
:
&
IdentInterner
,
cdata
:
Cmd
,
doc
:
rbml
::
Doc
,
did
:
ast
::
DefId
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
ty
::
VariantDef_
<
'tcx
,
'tcx
>
{
ty
::
VariantDef_
{
did
:
did
,
name
:
item_name
(
intr
,
doc
),
fields
:
get_variant_fields
(
intr
,
cdata
,
doc
,
tcx
),
disr_val
:
0
}
}
let
doc
=
lookup_item
(
item_id
,
cdata
.data
());
let
did
=
ast
::
DefId
{
krate
:
cdata
.cnum
,
node
:
item_id
};
let
(
kind
,
variants
)
=
match
item_family
(
doc
)
{
Enum
=>
(
ty
::
ADTKind
::
Enum
,
get_enum_variants
(
intr
,
cdata
,
doc
,
tcx
)),
Struct
=>
(
ty
::
ADTKind
::
Struct
,
vec!
[
get_struct_variant
(
intr
,
cdata
,
doc
,
did
,
tcx
)]),
_
=>
tcx
.sess
.bug
(
"get_adt_def called on a non-ADT"
)
};
let
adt
=
tcx
.intern_adt_def
(
did
,
kind
,
variants
);
// this needs to be done *after* the variant is interned,
// to support recursive structures
for
variant
in
&
adt
.variants
{
if
variant
.kind
()
==
ty
::
VariantKind
::
Tuple
&&
adt
.adt_kind
()
==
ty
::
ADTKind
::
Enum
{
// tuple-like enum variant fields aren't real items - get the types
// from the ctor.
debug!
(
"evaluating the ctor-type of {:?}"
,
variant
.name
);
let
ctor_ty
=
get_type
(
cdata
,
variant
.did.node
,
tcx
)
.ty
;
debug!
(
"evaluating the ctor-type of {:?}.. {:?}"
,
variant
.name
,
ctor_ty
);
let
field_tys
=
match
ctor_ty
.sty
{
ty
::
TyBareFn
(
_
,
ref
f
)
=>
&
f
.sig
.skip_binder
()
.inputs
,
_
=>
tcx
.sess
.bug
(
"tuple-variant ctor is not an ADT"
)
};
for
(
field
,
&
ty
)
in
variant
.fields
.iter
()
.zip
(
field_tys
.iter
())
{
field
.fulfill_ty
(
ty
);
}
}
else
{
for
field
in
&
variant
.fields
{
debug!
(
"evaluating the type of {:?}::{:?}"
,
variant
.name
,
field
.name
);
let
ty
=
get_type
(
cdata
,
field
.did.node
,
tcx
)
.ty
;
field
.fulfill_ty
(
ty
);
debug!
(
"evaluating the type of {:?}::{:?}: {:?}"
,
variant
.name
,
field
.name
,
ty
);
}
}
}
adt
}
pub
fn
get_predicates
<
'tcx
>
(
cdata
:
Cmd
,
...
...
src/librustc/metadata/encoder.rs
浏览文件 @
4816e606
...
...
@@ -41,7 +41,6 @@
use
syntax
::
diagnostic
::
SpanHandler
;
use
syntax
::
parse
::
token
::
special_idents
;
use
syntax
::
print
::
pprust
;
use
syntax
::
ptr
::
P
;
use
syntax
::
visit
::
Visitor
;
use
syntax
::
visit
;
use
syntax
;
...
...
@@ -266,7 +265,7 @@ fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
}
fn
encode_struct_fields
(
rbml_w
:
&
mut
Encoder
,
fields
:
&
[
ty
::
Field
Ty
],
fields
:
&
[
ty
::
Field
Def
],
origin
:
DefId
)
{
for
f
in
fields
{
if
f
.name
==
special_idents
::
unnamed_field
.name
{
...
...
@@ -276,7 +275,7 @@ fn encode_struct_fields(rbml_w: &mut Encoder,
encode_name
(
rbml_w
,
f
.name
);
}
encode_struct_field_family
(
rbml_w
,
f
.vis
);
encode_def_id
(
rbml_w
,
f
.id
);
encode_def_id
(
rbml_w
,
f
.
d
id
);
rbml_w
.wr_tagged_u64
(
tag_item_field_origin
,
def_to_u64
(
origin
));
rbml_w
.end_tag
();
}
...
...
@@ -285,57 +284,56 @@ fn encode_struct_fields(rbml_w: &mut Encoder,
fn
encode_enum_variant_info
(
ecx
:
&
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
id
:
NodeId
,
v
ariants
:
&
[
P
<
ast
::
Variant
>
]
,
v
is
:
ast
::
Visibility
,
index
:
&
mut
Vec
<
entry
<
i64
>>
)
{
debug!
(
"encode_enum_variant_info(id={})"
,
id
);
let
mut
disr_val
=
0
;
let
mut
i
=
0
;
let
vi
=
ecx
.tcx
.enum_variants
(
local_def
(
id
));
for
variant
in
variants
{
let
def_id
=
local_def
(
variant
.node.id
);
let
def
=
ecx
.tcx
.lookup_adt_def
(
local_def
(
id
))
;
for
variant
in
&
def
.variants
{
let
vid
=
variant
.did
;
assert
!
(
is_local
(
vid
)
);
index
.push
(
entry
{
val
:
v
ariant
.node.id
as
i64
,
val
:
v
id
.node
as
i64
,
pos
:
rbml_w
.mark_stable_position
(),
});
rbml_w
.start_tag
(
tag_items_data_item
);
encode_def_id
(
rbml_w
,
def_
id
);
match
variant
.node.kind
{
ast
::
TupleVariantKind
(
_
)
=>
encode_family
(
rbml_w
,
'v'
)
,
ast
::
StructVariantKind
(
_
)
=>
encode_family
(
rbml_w
,
'V'
)
}
encode_name
(
rbml_w
,
variant
.n
ode.name.n
ame
);
encode_def_id
(
rbml_w
,
v
id
);
encode_family
(
rbml_w
,
match
variant
.kind
()
{
ty
::
VariantKind
::
Unit
|
ty
::
VariantKind
::
Tuple
=>
'v'
,
ty
::
VariantKind
::
Dict
=>
'V'
}
);
encode_name
(
rbml_w
,
variant
.name
);
encode_parent_item
(
rbml_w
,
local_def
(
id
));
encode_visibility
(
rbml_w
,
variant
.node.vis
);
encode_attributes
(
rbml_w
,
&
variant
.node.attrs
);
encode_repr_attrs
(
rbml_w
,
ecx
,
&
variant
.node.attrs
);
encode_visibility
(
rbml_w
,
vis
);
let
attrs
=
ecx
.tcx
.get_attrs
(
vid
);
encode_attributes
(
rbml_w
,
&
attrs
);
encode_repr_attrs
(
rbml_w
,
ecx
,
&
attrs
);
let
stab
=
stability
::
lookup
(
ecx
.tcx
,
ast_util
::
local_def
(
variant
.node.id
)
);
let
stab
=
stability
::
lookup
(
ecx
.tcx
,
vid
);
encode_stability
(
rbml_w
,
stab
);
match
variant
.node.kind
{
ast
::
TupleVariantKind
(
_
)
=>
{},
ast
::
StructVariantKind
(
_
)
=>
{
let
fields
=
ecx
.tcx
.lookup_struct_fields
(
def_id
);
let
idx
=
encode_info_for_struct
(
ecx
,
rbml_w
,
&
fields
[
..
],
index
);
encode_struct_fields
(
rbml_w
,
&
fields
[
..
],
def_id
);
encode_index
(
rbml_w
,
idx
,
write_i64
);
}
if
let
ty
::
VariantKind
::
Dict
=
variant
.kind
()
{
let
idx
=
encode_info_for_struct
(
ecx
,
rbml_w
,
&
variant
.fields
,
index
);
encode_index
(
rbml_w
,
idx
,
write_i64
);
}
let
specified_disr_val
=
vi
[
i
]
.disr_val
;
encode_struct_fields
(
rbml_w
,
&
variant
.fields
,
vid
);
let
specified_disr_val
=
variant
.disr_val
;
if
specified_disr_val
!=
disr_val
{
encode_disr_val
(
ecx
,
rbml_w
,
specified_disr_val
);
disr_val
=
specified_disr_val
;
}
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
def_id
.local_id
()
);
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
vid
.node
);
ecx
.tcx.map
.with_path
(
v
ariant
.node.id
,
|
path
|
encode_path
(
rbml_w
,
path
));
ecx
.tcx.map
.with_path
(
v
id
.node
,
|
path
|
encode_path
(
rbml_w
,
path
));
rbml_w
.end_tag
();
disr_val
=
disr_val
.wrapping_add
(
1
);
i
+=
1
;
}
}
...
...
@@ -630,11 +628,11 @@ fn encode_provided_source(rbml_w: &mut Encoder,
}
/* Returns an index of items in this class */
fn
encode_info_for_struct
(
ecx
:
&
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
fields
:
&
[
ty
::
FieldTy
],
global_index
:
&
mut
Vec
<
entry
<
i64
>>
)
->
Vec
<
entry
<
i64
>>
{
fn
encode_info_for_struct
<
'a
,
'tcx
>
(
ecx
:
&
EncodeContext
<
'a
,
'tcx
>
,
rbml_w
:
&
mut
Encoder
,
fields
:
&
[
ty
::
FieldDef
<
'tcx
>
],
global_index
:
&
mut
Vec
<
entry
<
i64
>>
)
->
Vec
<
entry
<
i64
>>
{
/* Each class has its own index, since different classes
may have fields with the same name */
let
mut
index
=
Vec
::
new
();
...
...
@@ -642,7 +640,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
private fields to get the offsets right */
for
field
in
fields
{
let
nm
=
field
.name
;
let
id
=
field
.id.node
;
let
id
=
field
.
d
id.node
;
let
pos
=
rbml_w
.mark_stable_position
();
index
.push
(
entry
{
val
:
id
as
i64
,
pos
:
pos
});
...
...
@@ -658,7 +656,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
encode_bounds_and_type_for_item
(
rbml_w
,
ecx
,
id
);
encode_def_id
(
rbml_w
,
local_def
(
id
));
let
stab
=
stability
::
lookup
(
ecx
.tcx
,
field
.id
);
let
stab
=
stability
::
lookup
(
ecx
.tcx
,
field
.
d
id
);
encode_stability
(
rbml_w
,
stab
);
rbml_w
.end_tag
();
...
...
@@ -1150,20 +1148,18 @@ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
encode_enum_variant_info
(
ecx
,
rbml_w
,
item
.id
,
&
(
*
enum_definition
)
.variant
s
,
vi
s
,
index
);
}
ast
::
ItemStruct
(
ref
struct_def
,
_
)
=>
{
let
fields
=
tcx
.lookup_struct_fields
(
def_id
);
let
def
=
ecx
.tcx
.lookup_adt_def
(
def_id
);
let
fields
=
&
def
.struct_variant
()
.fields
;
/* First, encode the fields
These come first because we need to write them to make
the index, and the index needs to be in the item for the
class itself */
let
idx
=
encode_info_for_struct
(
ecx
,
rbml_w
,
&
fields
[
..
],
index
);
let
idx
=
encode_info_for_struct
(
ecx
,
rbml_w
,
&
fields
,
index
);
/* Index the class*/
add_to_index
(
item
,
rbml_w
,
index
);
...
...
@@ -1185,7 +1181,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
/* Encode def_ids for each field and method
for methods, write all the stuff get_trait_method
needs to know*/
encode_struct_fields
(
rbml_w
,
&
fields
[
..
]
,
def_id
);
encode_struct_fields
(
rbml_w
,
&
fields
,
def_id
);
encode_inlined_item
(
ecx
,
rbml_w
,
IIItemRef
(
item
));
...
...
src/librustc/middle/check_match.rs
浏览文件 @
4816e606
...
...
@@ -513,7 +513,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
&
Variant
(
vid
)
=>
(
vid
,
cx
.tcx
.enum_variant_with_id
(
cid
.did
,
vid
)
.arg_names
.is_some
()),
_
=>
(
cid
.did
,
!
cid
.
is_tuple_struct
(
cx
.tcx
))
(
cid
.did
,
!
cid
.
struct_variant
()
.is_tuple_struct
(
))
};
if
is_structure
{
let
fields
=
cx
.tcx
.lookup_struct_fields
(
vid
);
...
...
src/librustc/middle/ty.rs
浏览文件 @
4816e606
...
...
@@ -74,10 +74,12 @@
use
std
::
cmp
;
use
std
::
fmt
;
use
std
::
hash
::{
Hash
,
SipHasher
,
Hasher
};
use
std
::
iter
;
use
std
::
marker
::
PhantomData
;
use
std
::
mem
;
use
std
::
ops
;
use
std
::
rc
::
Rc
;
use
std
::
slice
;
use
std
::
vec
::
IntoIter
;
use
collections
::
enum_set
::{
self
,
EnumSet
,
CLike
};
use
core
::
nonzero
::
NonZero
;
...
...
@@ -90,7 +92,7 @@
use
syntax
::
ast_util
::{
self
,
is_local
,
local_def
};
use
syntax
::
attr
::{
self
,
AttrMetaMethods
,
SignedInt
,
UnsignedInt
};
use
syntax
::
codemap
::
Span
;
use
syntax
::
parse
::
token
::{
self
,
InternedString
,
special_idents
};
use
syntax
::
parse
::
token
::{
InternedString
,
special_idents
};
use
syntax
::
print
::
pprust
;
use
syntax
::
ptr
::
P
;
use
syntax
::
ast
;
...
...
@@ -211,7 +213,7 @@ pub fn has_drop_flag(&self) -> bool {
}
}
trait
IntTypeExt
{
pub
trait
IntTypeExt
{
fn
to_ty
<
'tcx
>
(
&
self
,
cx
:
&
ctxt
<
'tcx
>
)
->
Ty
<
'tcx
>
;
fn
i64_to_disr
(
&
self
,
val
:
i64
)
->
Option
<
Disr
>
;
fn
u64_to_disr
(
&
self
,
val
:
u64
)
->
Option
<
Disr
>
;
...
...
@@ -852,7 +854,7 @@ pub struct ctxt<'tcx> {
pub
impl_trait_refs
:
RefCell
<
DefIdMap
<
Option
<
TraitRef
<
'tcx
>>>>
,
pub
trait_defs
:
RefCell
<
DefIdMap
<&
'tcx
TraitDef
<
'tcx
>>>
,
pub
adt_defs
:
RefCell
<
DefIdMap
<&
'tcx
ADTDef
<
'tcx
>>>
,
pub
adt_defs
:
RefCell
<
DefIdMap
<&
'tcx
ADTDef
_
<
'tcx
,
'tcx
>>>
,
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
/// associated predicates.
...
...
@@ -1023,8 +1025,12 @@ pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
interned
}
pub
fn
intern_adt_def
(
&
self
,
did
:
DefId
,
kind
:
ADTKind
)
->
&
'tcx
ADTDef_
<
'tcx
,
'tcx
>
{
let
def
=
ADTDef_
::
new
(
self
,
did
,
kind
);
pub
fn
intern_adt_def
(
&
self
,
did
:
DefId
,
kind
:
ADTKind
,
variants
:
Vec
<
VariantDef_
<
'tcx
,
'tcx
>>
)
->
&
'tcx
ADTDef_
<
'tcx
,
'tcx
>
{
let
def
=
ADTDef_
::
new
(
self
,
did
,
kind
,
variants
);
let
interned
=
self
.arenas.adt_defs
.alloc
(
def
);
// this will need a transmute when reverse-variance is removed
self
.adt_defs
.borrow_mut
()
.insert
(
did
,
interned
);
...
...
@@ -2190,7 +2196,7 @@ pub struct ExistentialBounds<'tcx> {
pub
struct
BuiltinBounds
(
EnumSet
<
BuiltinBound
>
);
impl
BuiltinBounds
{
pub
fn
empty
()
->
BuiltinBounds
{
pub
fn
empty
()
->
BuiltinBounds
{
BuiltinBounds
(
EnumSet
::
new
())
}
...
...
@@ -3274,17 +3280,21 @@ pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
}
pub
type
ADTDef
<
'tcx
>
=
ADTDef_
<
'tcx
,
'static
>
;
pub
type
VariantDef
<
'tcx
>
=
VariantDef_
<
'tcx
,
'static
>
;
pub
type
FieldDef
<
'tcx
>
=
FieldDef_
<
'tcx
,
'static
>
;
pub
struct
VariantDef
<
'tcx
,
'lt
:
'tcx
>
{
pub
struct
VariantDef
_
<
'tcx
,
'lt
:
'tcx
>
{
pub
did
:
DefId
,
pub
name
:
Name
,
// struct's name if this is a struct
pub
disr_val
:
Disr
,
pub
fields
:
Vec
<
FieldDef
<
'tcx
,
'lt
>>
pub
fields
:
Vec
<
FieldDef
_
<
'tcx
,
'lt
>>
}
pub
struct
FieldDef
<
'tcx
,
'lt
:
'tcx
>
{
pub
struct
FieldDef
_
<
'tcx
,
'lt
:
'tcx
>
{
pub
did
:
DefId
,
pub
name
:
Name
,
// XXX if tuple-like
// special_idents::unnamed_field.name
// if this is a tuple-like field
pub
name
:
Name
,
pub
vis
:
ast
::
Visibility
,
// TyIVar is used here to allow for
ty
:
TyIVar
<
'tcx
,
'lt
>
...
...
@@ -3294,7 +3304,7 @@ pub struct FieldDef<'tcx, 'lt: 'tcx> {
/// is here so 'tcx can be variant.
pub
struct
ADTDef_
<
'tcx
,
'lt
:
'tcx
>
{
pub
did
:
DefId
,
pub
variants
:
Vec
<
VariantDef
<
'tcx
,
'lt
>>
,
pub
variants
:
Vec
<
VariantDef
_
<
'tcx
,
'lt
>>
,
flags
:
Cell
<
ADTFlags
>
,
}
...
...
@@ -3313,11 +3323,18 @@ fn hash<H: Hasher>(&self, s: &mut H) {
}
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug,
Eq,
PartialEq)]
pub
enum
ADTKind
{
Struct
,
Enum
}
#[derive(Copy,
Clone,
Debug,
Eq,
PartialEq)]
pub
enum
VariantKind
{
Dict
,
Tuple
,
Unit
}
impl
<
'tcx
,
'lt
>
ADTDef_
<
'tcx
,
'lt
>
{
fn
new
(
tcx
:
&
ctxt
<
'tcx
>
,
did
:
DefId
,
kind
:
ADTKind
)
->
Self
{
fn
new
(
tcx
:
&
ctxt
<
'tcx
>
,
did
:
DefId
,
kind
:
ADTKind
,
variants
:
Vec
<
VariantDef_
<
'tcx
,
'lt
>>
)
->
Self
{
let
mut
flags
=
ADTFlags
::
NO_ADT_FLAGS
;
if
tcx
.has_attr
(
did
,
"fundamental"
)
{
flags
=
flags
|
ADTFlags
::
IS_FUNDAMENTAL
;
...
...
@@ -3330,7 +3347,7 @@ fn new(tcx: &ctxt<'tcx>, did: DefId, kind: ADTKind) -> Self {
}
ADTDef
{
did
:
did
,
variants
:
v
ec!
[]
,
variants
:
v
ariants
,
flags
:
Cell
::
new
(
flags
),
}
}
...
...
@@ -3374,9 +3391,9 @@ pub fn has_dtor(&self, tcx: &ctxt<'tcx>) -> bool {
tcx
.destructor_for_type
.borrow
()
.contains_key
(
&
self
.did
)
}
pub
fn
is_tuple_struct
(
&
self
,
tcx
:
&
ctxt
<
'tcx
>
)
->
bool
{
let
fields
=
tcx
.lookup_struct_fields
(
self
.did
);
!
fields
.is_empty
()
&&
fields
.iter
()
.all
(|
f
|
f
.name
==
token
::
special_names
::
unnamed_field
)
pub
fn
struct_variant
(
&
self
)
->
&
ty
::
VariantDef_
<
'tcx
,
'lt
>
{
assert
!
(
self
.adt_kind
()
==
ADTKind
::
Struct
);
&
self
.variants
[
0
]
}
#[inline]
...
...
@@ -3388,6 +3405,104 @@ pub fn type_scheme(&self, tcx: &ctxt<'tcx>) -> TypeScheme<'tcx> {
pub
fn
predicates
(
&
self
,
tcx
:
&
ctxt
<
'tcx
>
)
->
GenericPredicates
<
'tcx
>
{
tcx
.lookup_predicates
(
self
.did
)
}
#[inline]
pub
fn
all_fields
(
&
self
)
->
iter
::
FlatMap
<
slice
::
Iter
<
VariantDef_
<
'tcx
,
'lt
>>
,
slice
::
Iter
<
FieldDef_
<
'tcx
,
'lt
>>
,
for
<
's
>
fn
(
&
's
VariantDef_
<
'tcx
,
'lt
>
)
->
slice
::
Iter
<
's
,
FieldDef_
<
'tcx
,
'lt
>>
>
{
self
.variants
.iter
()
.flat_map
(
VariantDef_
::
fields_iter
)
}
#[inline]
pub
fn
is_empty
(
&
self
)
->
bool
{
// FIXME(#TODO(wxyz)): be smarter here
self
.variants
.is_empty
()
}
#[inline]
pub
fn
is_univariant
(
&
self
)
->
bool
{
self
.variants
.len
()
==
1
}
pub
fn
is_payloadfree
(
&
self
)
->
bool
{
!
self
.variants
.is_empty
()
&&
self
.variants
.iter
()
.all
(|
v
|
v
.fields
.is_empty
())
}
pub
fn
variant_with_id
(
&
self
,
vid
:
DefId
)
->
&
VariantDef_
<
'tcx
,
'lt
>
{
self
.variants
.iter
()
.find
(|
v
|
v
.did
==
vid
)
.expect
(
"variant_with_id: unknown variant"
)
}
pub
fn
variant_of_def
(
&
self
,
def
:
def
::
Def
)
->
&
VariantDef_
<
'tcx
,
'lt
>
{
match
def
{
def
::
DefVariant
(
_
,
vid
,
_
)
=>
self
.variant_with_id
(
vid
),
def
::
DefStruct
(
..
)
|
def
::
DefTy
(
..
)
=>
self
.struct_variant
(),
_
=>
panic!
(
"unexpected def {:?} in variant_of_def"
,
def
)
}
}
}
impl
<
'tcx
,
'lt
>
VariantDef_
<
'tcx
,
'lt
>
{
#[inline]
fn
fields_iter
(
&
self
)
->
slice
::
Iter
<
FieldDef_
<
'tcx
,
'lt
>>
{
self
.fields
.iter
()
}
pub
fn
kind
(
&
self
)
->
VariantKind
{
match
self
.fields
.get
(
0
)
{
None
=>
VariantKind
::
Unit
,
Some
(
&
FieldDef_
{
name
,
..
})
if
name
==
special_idents
::
unnamed_field
.name
=>
{
VariantKind
::
Tuple
}
Some
(
_
)
=>
VariantKind
::
Dict
}
}
pub
fn
is_tuple_struct
(
&
self
)
->
bool
{
self
.kind
()
==
VariantKind
::
Tuple
}
#[inline]
pub
fn
find_field_named
(
&
self
,
name
:
ast
::
Name
)
->
Option
<&
FieldDef_
<
'tcx
,
'lt
>>
{
self
.fields
.iter
()
.find
(|
f
|
f
.name
==
name
)
}
#[inline]
pub
fn
field_named
(
&
self
,
name
:
ast
::
Name
)
->
&
FieldDef_
<
'tcx
,
'lt
>
{
self
.find_field_named
(
name
)
.unwrap
()
}
}
impl
<
'tcx
,
'lt
>
FieldDef_
<
'tcx
,
'lt
>
{
pub
fn
new
(
did
:
DefId
,
name
:
Name
,
vis
:
ast
::
Visibility
)
->
Self
{
FieldDef_
{
did
:
did
,
name
:
name
,
vis
:
vis
,
ty
:
TyIVar
::
new
()
}
}
pub
fn
ty
(
&
self
,
tcx
:
&
ctxt
<
'tcx
>
,
subst
:
&
Substs
<
'tcx
>
)
->
Ty
<
'tcx
>
{
self
.unsubst_ty
()
.subst
(
tcx
,
subst
)
}
pub
fn
unsubst_ty
(
&
self
)
->
Ty
<
'tcx
>
{
self
.ty
.unwrap
()
}
pub
fn
fulfill_ty
(
&
self
,
ty
:
Ty
<
'lt
>
)
{
self
.ty
.fulfill
(
ty
);
}
}
/// Records the substitutions used to translate the polytype for an
...
...
@@ -6132,7 +6247,7 @@ pub fn lookup_trait_def(&self, did: ast::DefId) -> &'tcx TraitDef<'tcx> {
}
/// Given the did of a trait, returns its canonical trait ref.
pub
fn
lookup_adt_def
(
&
self
,
did
:
ast
::
DefId
)
->
&
'tcx
ADTDef
<
'tcx
>
{
pub
fn
lookup_adt_def
(
&
self
,
did
:
ast
::
DefId
)
->
&
'tcx
ADTDef
_
<
'tcx
,
'tcx
>
{
lookup_locally_or_in_crate_store
(
"adt_defs"
,
did
,
&
self
.adt_defs
,
||
csearch
::
get_adt_def
(
self
,
did
)
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
4816e606
...
...
@@ -2980,7 +2980,7 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
base_t
,
_
|
{
match
base_t
.sty
{
ty
::
TyStruct
(
base_def
,
substs
)
=>
{
tuple_like
=
base_def
.
is_tuple_struct
(
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
);
...
...
src/librustc_typeck/collect.rs
浏览文件 @
4816e606
...
...
@@ -71,9 +71,12 @@
use
middle
::
free_region
::
FreeRegionMap
;
use
middle
::
region
;
use
middle
::
resolve_lifetime
;
use
middle
::
const_eval
::{
self
,
ConstVal
};
use
middle
::
const_eval
::
EvalHint
::
UncheckedExprHint
;
use
middle
::
subst
::{
Substs
,
FnSpace
,
ParamSpace
,
SelfSpace
,
TypeSpace
,
VecPerParamSpace
};
use
middle
::
ty
::{
ToPredicate
,
ImplContainer
,
ImplOrTraitItemContainer
,
TraitContainer
};
use
middle
::
ty
::{
self
,
RegionEscape
,
ToPolyTraitRef
,
Ty
,
TypeScheme
};
use
middle
::
ty
::{
self
,
RegionEscape
,
ToPolyTraitRef
,
Ty
,
TypeScheme
,
IntTypeExt
};
use
middle
::
ty
::{
VariantKind
};
use
middle
::
ty_fold
::{
self
,
TypeFolder
,
TypeFoldable
};
use
middle
::
infer
;
use
rscope
::
*
;
...
...
@@ -89,8 +92,10 @@
use
syntax
::
abi
;
use
syntax
::
ast
;
use
syntax
::
ast_util
::
local_def
;
use
syntax
::
attr
;
use
syntax
::
codemap
::
Span
;
use
syntax
::
parse
::
token
::
special_idents
;
use
syntax
::
print
::
pprust
;
use
syntax
::
ptr
::
P
;
use
syntax
::
visit
;
...
...
@@ -563,48 +568,6 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
}
}
fn
get_enum_variant_types
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
enum_scheme
:
ty
::
TypeScheme
<
'tcx
>
,
enum_predicates
:
ty
::
GenericPredicates
<
'tcx
>
,
variants
:
&
[
P
<
ast
::
Variant
>
])
{
let
tcx
=
ccx
.tcx
;
let
icx
=
ccx
.icx
(
&
enum_predicates
);
// Create a set of parameter types shared among all the variants.
for
variant
in
variants
{
let
variant_def_id
=
local_def
(
variant
.node.id
);
// Nullary enum constructors get turned into constants; n-ary enum
// constructors get turned into functions.
let
result_ty
=
match
variant
.node.kind
{
ast
::
TupleVariantKind
(
ref
args
)
if
!
args
.is_empty
()
=>
{
let
rs
=
ExplicitRscope
;
let
input_tys
:
Vec
<
_
>
=
args
.iter
()
.map
(|
va
|
icx
.to_ty
(
&
rs
,
&*
va
.ty
))
.collect
();
tcx
.mk_ctor_fn
(
variant_def_id
,
&
input_tys
,
enum_scheme
.ty
)
}
ast
::
TupleVariantKind
(
_
)
=>
{
enum_scheme
.ty
}
ast
::
StructVariantKind
(
ref
struct_def
)
=>
{
convert_struct
(
ccx
,
&**
struct_def
,
enum_scheme
.clone
(),
enum_predicates
.clone
(),
variant
.node.id
);
enum_scheme
.ty
}
};
let
variant_scheme
=
TypeScheme
{
generics
:
enum_scheme
.generics
.clone
(),
ty
:
result_ty
};
tcx
.register_item_type
(
variant_def_id
,
variant_scheme
.clone
());
tcx
.predicates
.borrow_mut
()
.insert
(
variant_def_id
,
enum_predicates
.clone
());
write_ty_to_tcx
(
tcx
,
variant
.node.id
,
result_ty
);
}
}
fn
convert_method
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
container
:
ImplOrTraitItemContainer
,
sig
:
&
ast
::
MethodSig
,
...
...
@@ -657,10 +620,12 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
struct_generics
:
&
ty
::
Generics
<
'tcx
>
,
struct_predicates
:
&
ty
::
GenericPredicates
<
'tcx
>
,
v
:
&
ast
::
StructField
,
ty_f
:
&
'tcx
ty
::
FieldDef_
<
'tcx
,
'tcx
>
,
origin
:
ast
::
DefId
)
->
ty
::
FieldTy
{
let
tt
=
ccx
.icx
(
struct_predicates
)
.to_ty
(
&
ExplicitRscope
,
&*
v
.node.ty
);
ty_f
.fulfill_ty
(
tt
);
write_ty_to_tcx
(
ccx
.tcx
,
v
.node.id
,
tt
);
/* add the field to the tcache */
...
...
@@ -803,10 +768,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
ast
::
ItemEnum
(
ref
enum_definition
,
_
)
=>
{
let
(
scheme
,
predicates
)
=
convert_typed_item
(
ccx
,
it
);
write_ty_to_tcx
(
tcx
,
it
.id
,
scheme
.ty
);
get_enum_variant_types
(
ccx
,
scheme
,
predicates
,
&
enum_definition
.variants
);
convert_enum_variant_types
(
ccx
,
tcx
.lookup_adt_def
(
local_def
(
it
.id
)),
scheme
,
predicates
,
&
enum_definition
.variants
);
},
ast
::
ItemDefaultImpl
(
_
,
ref
ast_trait_ref
)
=>
{
let
trait_ref
=
...
...
@@ -1048,10 +1014,14 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
}
},
ast
::
ItemStruct
(
ref
struct_def
,
_
)
=>
{
// Write the class type.
let
(
scheme
,
predicates
)
=
convert_typed_item
(
ccx
,
it
);
write_ty_to_tcx
(
tcx
,
it
.id
,
scheme
.ty
);
convert_struct
(
ccx
,
&**
struct_def
,
scheme
,
predicates
,
it
.id
);
let
variant
=
tcx
.lookup_adt_def
(
local_def
(
it
.id
))
.struct_variant
();
convert_struct_variant_types
(
ccx
,
&
struct_def
,
variant
,
&
scheme
,
&
predicates
);
if
let
Some
(
ctor_id
)
=
struct_def
.ctor_id
{
convert_variant_ctor
(
tcx
,
ctor_id
,
variant
,
scheme
,
predicates
);
}
},
ast
::
ItemTy
(
_
,
ref
generics
)
=>
{
ensure_no_ty_param_bounds
(
ccx
,
it
.span
,
generics
,
"type"
);
...
...
@@ -1068,74 +1038,216 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
}
}
fn
convert_struct
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
struct_def
:
&
ast
::
StructDef
,
scheme
:
ty
::
TypeScheme
<
'tcx
>
,
predicates
:
ty
::
GenericPredicates
<
'tcx
>
,
id
:
ast
::
NodeId
)
{
fn
convert_variant_ctor
<
'a
,
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ctor_id
:
ast
::
NodeId
,
variant
:
&
'tcx
ty
::
VariantDef
<
'tcx
>
,
scheme
:
ty
::
TypeScheme
<
'tcx
>
,
predicates
:
ty
::
GenericPredicates
<
'tcx
>
)
{
let
ctor_ty
=
match
variant
.kind
()
{
VariantKind
::
Unit
|
VariantKind
::
Dict
=>
scheme
.ty
,
VariantKind
::
Tuple
=>
{
let
inputs
:
Vec
<
_
>
=
variant
.fields
.iter
()
.map
(|
field
|
field
.unsubst_ty
())
.collect
();
tcx
.mk_ctor_fn
(
local_def
(
ctor_id
),
&
inputs
[
..
],
scheme
.ty
)
}
};
write_ty_to_tcx
(
tcx
,
ctor_id
,
ctor_ty
);
tcx
.predicates
.borrow_mut
()
.insert
(
local_def
(
ctor_id
),
predicates
);
tcx
.register_item_type
(
local_def
(
ctor_id
),
TypeScheme
{
generics
:
scheme
.generics
,
ty
:
ctor_ty
});
}
fn
convert_struct_variant_types
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
def
:
&
ast
::
StructDef
,
variant
:
&
'tcx
ty
::
VariantDef_
<
'tcx
,
'tcx
>
,
scheme
:
&
ty
::
TypeScheme
<
'tcx
>
,
predicates
:
&
ty
::
GenericPredicates
<
'tcx
>
)
{
let
field_tys
=
def
.fields
.iter
()
.zip
(
variant
.fields
.iter
())
.map
(|(
f
,
ty_f
)|
{
convert_field
(
ccx
,
&
scheme
.generics
,
&
predicates
,
f
,
ty_f
,
variant
.did
)
})
.collect
();
ccx
.tcx.struct_fields
.borrow_mut
()
.insert
(
variant
.did
,
Rc
::
new
(
field_tys
));
}
fn
convert_enum_variant_types
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
def
:
&
'tcx
ty
::
ADTDef_
<
'tcx
,
'tcx
>
,
scheme
:
ty
::
TypeScheme
<
'tcx
>
,
predicates
:
ty
::
GenericPredicates
<
'tcx
>
,
variants
:
&
[
P
<
ast
::
Variant
>
])
{
let
tcx
=
ccx
.tcx
;
let
icx
=
ccx
.icx
(
&
predicates
);
// Write the type of each of the members and check for duplicate fields.
let
mut
seen_fields
:
FnvHashMap
<
ast
::
Name
,
Span
>
=
FnvHashMap
();
let
field_tys
=
struct_def
.fields
.iter
()
.map
(|
f
|
{
let
result
=
convert_field
(
ccx
,
&
scheme
.generics
,
&
predicates
,
f
,
local_def
(
id
));
// Create a set of parameter types shared among all the variants.
for
(
variant
,
ty_variant
)
in
variants
.iter
()
.zip
(
def
.variants
.iter
())
{
match
variant
.node.kind
{
ast
::
TupleVariantKind
(
ref
args
)
=>
{
let
rs
=
ExplicitRscope
;
let
input_tys
:
Vec
<
_
>
=
args
.iter
()
.map
(|
va
|
icx
.to_ty
(
&
rs
,
&*
va
.ty
))
.collect
();
for
(
field
,
&
ty
)
in
ty_variant
.fields
.iter
()
.zip
(
input_tys
.iter
())
{
field
.fulfill_ty
(
ty
);
}
}
ast
::
StructVariantKind
(
ref
struct_def
)
=>
{
convert_struct_variant_types
(
ccx
,
&
struct_def
,
ty_variant
,
&
scheme
,
&
predicates
);
}
};
if
result
.name
!=
special_idents
::
unnamed_field
.name
{
let
dup
=
match
seen_fields
.get
(
&
result
.name
)
{
Some
(
prev_span
)
=>
{
convert_variant_ctor
(
tcx
,
variant
.node.id
,
ty_variant
,
scheme
.clone
(),
predicates
.clone
()
);
}
}
fn
convert_struct_variant
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
did
:
ast
::
DefId
,
name
:
ast
::
Name
,
disr_val
:
ty
::
Disr
,
def
:
&
ast
::
StructDef
)
->
ty
::
VariantDef_
<
'tcx
,
'tcx
>
{
let
mut
seen_fields
:
FnvHashMap
<
ast
::
Name
,
Span
>
=
FnvHashMap
();
let
fields
=
def
.fields
.iter
()
.map
(|
f
|
{
let
fid
=
local_def
(
f
.node.id
);
match
f
.node.kind
{
ast
::
NamedField
(
ident
,
vis
)
=>
{
let
dup_span
=
seen_fields
.get
(
&
ident
.name
)
.cloned
();
if
let
Some
(
prev_span
)
=
dup_span
{
span_err!
(
tcx
.sess
,
f
.span
,
E0124
,
"field `{}` is already declared"
,
resul
t
.name
);
span_note!
(
tcx
.sess
,
*
prev_span
,
"previously declared here"
);
true
},
None
=>
false
,
};
// FIXME(#6393) this whole dup thing is just to satisfy
// the borrow checker :-(
if
!
dup
{
seen_fields
.insert
(
result
.name
,
f
.span
);
iden
t
.name
);
span_note!
(
tcx
.sess
,
prev_span
,
"previously declared here"
);
}
else
{
seen_fields
.insert
(
ident
.name
,
f
.span
);
}
ty
::
FieldDef_
::
new
(
fid
,
ident
.name
,
vis
)
},
ast
::
UnnamedField
(
vis
)
=>
{
ty
::
FieldDef_
::
new
(
fid
,
special_idents
::
unnamed_field
.name
,
vis
)
}
}
result
})
.collect
();
ty
::
VariantDef_
{
did
:
did
,
name
:
name
,
disr_val
:
disr_val
,
fields
:
fields
}
}
tcx
.struct_fields
.borrow_mut
()
.insert
(
local_def
(
id
),
Rc
::
new
(
field_tys
));
fn
convert_struct_def
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
it
:
&
ast
::
Item
,
def
:
&
ast
::
StructDef
)
->
&
'tcx
ty
::
ADTDef_
<
'tcx
,
'tcx
>
{
let
did
=
local_def
(
it
.id
);
tcx
.intern_adt_def
(
did
,
ty
::
ADTKind
::
Struct
,
vec!
[
convert_struct_variant
(
tcx
,
did
,
it
.ident.name
,
0
,
def
)]
)
}
// If this struct is enum-like or tuple-like, create the type of its
// constructor.
if
let
Some
(
ctor_id
)
=
struct_def
.ctor_id
{
let
substs
=
mk_item_substs
(
ccx
,
&
scheme
.generics
);
let
selfty
=
tcx
.mk_struct
(
tcx
.lookup_adt_def
(
local_def
(
id
)),
tcx
.mk_substs
(
substs
));
if
struct_def
.fields
.is_empty
()
{
// Enum-like.
write_ty_to_tcx
(
tcx
,
ctor_id
,
selfty
);
fn
convert_enum_def
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
it
:
&
ast
::
Item
,
def
:
&
ast
::
EnumDef
)
->
&
'tcx
ty
::
ADTDef_
<
'tcx
,
'tcx
>
{
fn
evaluate_disr_expr
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
repr_ty
:
Ty
<
'tcx
>
,
e
:
&
ast
::
Expr
)
->
Option
<
ty
::
Disr
>
{
debug!
(
"disr expr, checking {}"
,
pprust
::
expr_to_string
(
e
));
let
hint
=
UncheckedExprHint
(
repr_ty
);
match
const_eval
::
eval_const_expr_partial
(
tcx
,
e
,
hint
)
{
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);
None
},
Err
(
_
)
=>
{
// span_err!(self.sess, err.span, E0080,
// "constant evaluation error: {}",
// err.description());
None
}
}
}
tcx
.register_item_type
(
local_def
(
ctor_id
),
scheme
);
tcx
.predicates
.borrow_mut
()
.insert
(
local_def
(
ctor_id
),
predicates
);
}
else
if
struct_def
.fields
[
0
]
.node.kind
.is_unnamed
()
{
// Tuple-like.
let
inputs
:
Vec
<
_
>
=
struct_def
.fields
.iter
()
.map
(|
field
|
tcx
.lookup_item_type
(
local_def
(
field
.node.id
))
.ty
)
.collect
();
let
ctor_fn_ty
=
tcx
.mk_ctor_fn
(
local_def
(
ctor_id
),
&
inputs
[
..
],
selfty
);
write_ty_to_tcx
(
tcx
,
ctor_id
,
ctor_fn_ty
);
tcx
.register_item_type
(
local_def
(
ctor_id
),
TypeScheme
{
generics
:
scheme
.generics
,
ty
:
ctor_fn_ty
});
tcx
.predicates
.borrow_mut
()
.insert
(
local_def
(
ctor_id
),
predicates
);
fn
next_disr
(
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);
// }
result
}
else
{
Some
(
ty
::
INITIAL_DISCRIMINANT_VALUE
)
}
}
fn
convert_enum_variant
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
v
:
&
ast
::
Variant
,
disr
:
ty
::
Disr
)
->
ty
::
VariantDef_
<
'tcx
,
'tcx
>
{
let
did
=
local_def
(
v
.node.id
);
let
name
=
v
.node.name.name
;
match
v
.node.kind
{
ast
::
TupleVariantKind
(
ref
va
)
=>
{
ty
::
VariantDef_
{
did
:
did
,
name
:
name
,
disr_val
:
disr
,
fields
:
va
.iter
()
.map
(|
&
ast
::
VariantArg
{
id
,
..
}|
{
ty
::
FieldDef_
::
new
(
local_def
(
id
),
special_idents
::
unnamed_field
.name
,
ast
::
Visibility
::
Public
)
})
.collect
()
}
}
ast
::
StructVariantKind
(
ref
def
)
=>
{
convert_struct_variant
(
tcx
,
did
,
name
,
disr
,
&
def
)
}
}
}
let
did
=
local_def
(
it
.id
);
let
repr_hints
=
tcx
.lookup_repr_hints
(
did
);
let
(
repr_type
,
repr_type_ty
)
=
tcx
.enum_repr_type
(
repr_hints
.get
(
0
));
let
mut
prev_disr
=
None
;
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
)
}
.unwrap_or
(
repr_type
.disr_wrap_incr
(
prev_disr
));
let
v
=
convert_enum_variant
(
tcx
,
v
,
disr
);
prev_disr
=
Some
(
disr
);
v
})
.collect
();
tcx
.intern_adt_def
(
local_def
(
it
.id
),
ty
::
ADTKind
::
Enum
,
variants
)
}
/// Ensures that the super-predicates of the trait with def-id
...
...
@@ -1469,18 +1581,17 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
let
ty
=
ccx
.icx
(
generics
)
.to_ty
(
&
ExplicitRscope
,
&**
t
);
ty
::
TypeScheme
{
ty
:
ty
,
generics
:
ty_generics
}
}
ast
::
ItemEnum
(
_
,
ref
generics
)
=>
{
// Create a new generic polytype.
ast
::
ItemEnum
(
ref
ei
,
ref
generics
)
=>
{
let
ty_generics
=
ty_generics_for_type_or_impl
(
ccx
,
generics
);
let
substs
=
mk_item_substs
(
ccx
,
&
ty_generics
);
let
def
=
tcx
.intern_adt_def
(
local_def
(
it
.id
),
ty
::
ADTKind
::
Enum
);
let
def
=
convert_enum_def
(
tcx
,
it
,
ei
);
let
t
=
tcx
.mk_enum
(
def
,
tcx
.mk_substs
(
substs
));
ty
::
TypeScheme
{
ty
:
t
,
generics
:
ty_generics
}
}
ast
::
ItemStruct
(
_
,
ref
generics
)
=>
{
ast
::
ItemStruct
(
ref
si
,
ref
generics
)
=>
{
let
ty_generics
=
ty_generics_for_type_or_impl
(
ccx
,
generics
);
let
substs
=
mk_item_substs
(
ccx
,
&
ty_generics
);
let
def
=
tcx
.intern_adt_def
(
local_def
(
it
.id
),
ty
::
ADTKind
::
Struct
);
let
def
=
convert_struct_def
(
tcx
,
it
,
si
);
let
t
=
tcx
.mk_struct
(
def
,
tcx
.mk_substs
(
substs
));
ty
::
TypeScheme
{
ty
:
t
,
generics
:
ty_generics
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录