Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
9b1865a7
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
9b1865a7
编写于
1月 29, 2014
作者:
J
Jason Fager
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add a limited prim type lookup for safer const expr evaluation
上级
edfb546e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
285 addition
and
209 deletion
+285
-209
src/librustc/middle/const_eval.rs
src/librustc/middle/const_eval.rs
+13
-2
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+15
-4
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/astconv.rs
+223
-202
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/mod.rs
+0
-1
src/test/run-pass/issue-5900.rs
src/test/run-pass/issue-5900.rs
+21
-0
src/test/run-pass/issue-9942.rs
src/test/run-pass/issue-9942.rs
+13
-0
未找到文件。
src/librustc/middle/const_eval.rs
浏览文件 @
9b1865a7
...
...
@@ -11,7 +11,9 @@
use
metadata
::
csearch
;
use
middle
::
astencode
;
use
middle
::
ty
;
use
middle
::
typeck
::
astconv
;
use
middle
;
use
syntax
::{
ast
,
ast_map
,
ast_util
};
...
...
@@ -445,8 +447,17 @@ fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
_
=>
Err
(
~
"Bad operands for binary"
)
}
}
ExprCast
(
base
,
_
)
=>
{
let
ety
=
tcx
.expr_ty
(
e
);
ExprCast
(
base
,
target_ty
)
=>
{
// This tends to get called w/o the type actually having been
// populated in the ctxt, which was causing things to blow up
// (#5900). Fall back to doing a limited lookup to get past it.
let
ety
=
ty
::
expr_ty_opt
(
tcx
.ty_ctxt
(),
e
)
.or_else
(||
astconv
::
ast_ty_to_prim_ty
(
tcx
.ty_ctxt
(),
target_ty
))
.unwrap_or_else
(||
tcx
.ty_ctxt
()
.sess
.span_fatal
(
target_ty
.span
,
format!
(
"Target type not found for const cast"
)
));
let
base
=
eval_const_expr_partial
(
tcx
,
base
);
match
base
{
Err
(
_
)
=>
base
,
...
...
src/librustc/middle/ty.rs
浏览文件 @
9b1865a7
...
...
@@ -2617,10 +2617,8 @@ pub fn node_id_to_trait_ref(cx: ctxt, id: ast::NodeId) -> @ty::TraitRef {
}
pub
fn
node_id_to_type
(
cx
:
ctxt
,
id
:
ast
::
NodeId
)
->
t
{
//printfln!("{:?}/{:?}", id, cx.node_types.len());
let
node_types
=
cx
.node_types
.borrow
();
match
node_types
.get
()
.find
(
&
(
id
as
uint
))
{
Some
(
&
t
)
=>
t
,
match
node_id_to_type_opt
(
cx
,
id
)
{
Some
(
t
)
=>
t
,
None
=>
cx
.sess
.bug
(
format!
(
"node_id_to_type: no type for node `{}`"
,
ast_map
::
node_id_to_str
(
cx
.items
,
id
,
...
...
@@ -2628,6 +2626,15 @@ pub fn node_id_to_type(cx: ctxt, id: ast::NodeId) -> t {
}
}
pub
fn
node_id_to_type_opt
(
cx
:
ctxt
,
id
:
ast
::
NodeId
)
->
Option
<
t
>
{
let
node_types
=
cx
.node_types
.borrow
();
debug!
(
"id: {:?}, node_types: {:?}"
,
id
,
node_types
);
match
node_types
.get
()
.find
(
&
(
id
as
uint
))
{
Some
(
&
t
)
=>
Some
(
t
),
None
=>
None
}
}
// FIXME(pcwalton): Makes a copy, bleh. Probably better to not do that.
pub
fn
node_id_to_type_params
(
cx
:
ctxt
,
id
:
ast
::
NodeId
)
->
~
[
t
]
{
let
node_type_substs
=
cx
.node_type_substs
.borrow
();
...
...
@@ -2798,6 +2805,10 @@ pub fn expr_ty(cx: ctxt, expr: &ast::Expr) -> t {
return
node_id_to_type
(
cx
,
expr
.id
);
}
pub
fn
expr_ty_opt
(
cx
:
ctxt
,
expr
:
&
ast
::
Expr
)
->
Option
<
t
>
{
return
node_id_to_type_opt
(
cx
,
expr
.id
);
}
pub
fn
expr_ty_adjusted
(
cx
:
ctxt
,
expr
:
&
ast
::
Expr
)
->
t
{
/*!
*
...
...
src/librustc/middle/typeck/astconv.rs
浏览文件 @
9b1865a7
...
...
@@ -276,6 +276,74 @@ pub fn ast_path_to_ty<AC:AstConv,RS:RegionScope>(
pub
static
NO_REGIONS
:
uint
=
1
;
pub
static
NO_TPS
:
uint
=
2
;
fn
check_path_args
(
tcx
:
ty
::
ctxt
,
path
:
&
ast
::
Path
,
flags
:
uint
)
{
if
(
flags
&
NO_TPS
)
!=
0u
{
if
!
path
.segments
.iter
()
.all
(|
s
|
s
.types
.is_empty
())
{
tcx
.sess
.span_err
(
path
.span
,
"type parameters are not allowed on this type"
);
}
}
if
(
flags
&
NO_REGIONS
)
!=
0u
{
if
!
path
.segments
.last
()
.unwrap
()
.lifetimes
.is_empty
()
{
tcx
.sess
.span_err
(
path
.span
,
"region parameters are not allowed on this type"
);
}
}
}
pub
fn
ast_ty_to_prim_ty
(
tcx
:
ty
::
ctxt
,
ast_ty
:
&
ast
::
Ty
)
->
Option
<
ty
::
t
>
{
match
ast_ty
.node
{
ast
::
TyPath
(
ref
path
,
_
,
id
)
=>
{
let
def_map
=
tcx
.def_map
.borrow
();
let
a_def
=
match
def_map
.get
()
.find
(
&
id
)
{
None
=>
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
,
tcx
.sess
.intr
()))),
Some
(
&
d
)
=>
d
};
match
a_def
{
ast
::
DefPrimTy
(
nty
)
=>
{
match
nty
{
ast
::
TyBool
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
Some
(
ty
::
mk_bool
())
}
ast
::
TyChar
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
Some
(
ty
::
mk_char
())
}
ast
::
TyInt
(
it
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
Some
(
ty
::
mk_mach_int
(
it
))
}
ast
::
TyUint
(
uit
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
Some
(
ty
::
mk_mach_uint
(
uit
))
}
ast
::
TyFloat
(
ft
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
Some
(
ty
::
mk_mach_float
(
ft
))
}
ast
::
TyStr
=>
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"bare `str` is not a type"
);
// return /something/ so they can at least get more errors
Some
(
ty
::
mk_str
(
tcx
,
ty
::
vstore_uniq
))
}
}
}
_
=>
None
}
}
_
=>
None
}
}
// Parses the programmer's textual representation of a type into our
// internal notion of a type.
pub
fn
ast_ty_to_ty
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
...
...
@@ -361,26 +429,6 @@ fn mk_pointer<AC:AstConv,
return
constr
(
seq_ty
);
}
fn
check_path_args
(
tcx
:
ty
::
ctxt
,
path
:
&
ast
::
Path
,
flags
:
uint
)
{
if
(
flags
&
NO_TPS
)
!=
0u
{
if
!
path
.segments
.iter
()
.all
(|
s
|
s
.types
.is_empty
())
{
tcx
.sess
.span_err
(
path
.span
,
"type parameters are not allowed on this type"
);
}
}
if
(
flags
&
NO_REGIONS
)
!=
0u
{
if
!
path
.segments
.last
()
.unwrap
()
.lifetimes
.is_empty
()
{
tcx
.sess
.span_err
(
path
.span
,
"region parameters are not allowed on this type"
);
}
}
}
let
tcx
=
this
.tcx
();
{
...
...
@@ -398,191 +446,164 @@ fn check_path_args(tcx: ty::ctxt,
ast_ty_to_ty_cache
.get
()
.insert
(
ast_ty
.id
,
ty
::
atttce_unresolved
);
}
let
typ
=
match
ast_ty
.node
{
ast
::
TyNil
=>
ty
::
mk_nil
(),
ast
::
TyBot
=>
ty
::
mk_bot
(),
ast
::
TyBox
(
ty
)
=>
{
let
mt
=
ast
::
MutTy
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
};
mk_pointer
(
this
,
rscope
,
&
mt
,
ty
::
vstore_box
,
|
tmt
|
ty
::
mk_box
(
tcx
,
tmt
.ty
))
}
ast
::
TyUniq
(
ty
)
=>
{
let
mt
=
ast
::
MutTy
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
};
mk_pointer
(
this
,
rscope
,
&
mt
,
ty
::
vstore_uniq
,
|
tmt
|
ty
::
mk_uniq
(
tcx
,
tmt
.ty
))
}
ast
::
TyVec
(
ty
)
=>
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"bare `[]` is not a type"
);
// return /something/ so they can at least get more errors
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_uniq
)
}
ast
::
TyPtr
(
ref
mt
)
=>
{
ty
::
mk_ptr
(
tcx
,
ast_mt_to_mt
(
this
,
rscope
,
mt
))
}
ast
::
TyRptr
(
ref
region
,
ref
mt
)
=>
{
let
r
=
opt_ast_region_to_region
(
this
,
rscope
,
ast_ty
.span
,
region
);
debug!
(
"ty_rptr r={}"
,
r
.repr
(
this
.tcx
()));
mk_pointer
(
this
,
rscope
,
mt
,
ty
::
vstore_slice
(
r
),
|
tmt
|
ty
::
mk_rptr
(
tcx
,
r
,
tmt
))
}
ast
::
TyTup
(
ref
fields
)
=>
{
let
flds
=
fields
.map
(|
&
t
|
ast_ty_to_ty
(
this
,
rscope
,
t
));
ty
::
mk_tup
(
tcx
,
flds
)
}
ast
::
TyBareFn
(
ref
bf
)
=>
{
if
bf
.decl.variadic
&&
!
bf
.abis
.is_c
()
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"variadic function must have C calling convention"
);
}
ty
::
mk_bare_fn
(
tcx
,
ty_of_bare_fn
(
this
,
ast_ty
.id
,
bf
.purity
,
bf
.abis
,
bf
.decl
))
}
ast
::
TyClosure
(
ref
f
)
=>
{
if
f
.sigil
==
ast
::
ManagedSigil
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"managed closures are not supported"
);
}
let
bounds
=
conv_builtin_bounds
(
this
.tcx
(),
&
f
.bounds
,
match
f
.sigil
{
// Use corresponding trait store to figure out default bounds
// if none were specified.
ast
::
BorrowedSigil
=>
ty
::
RegionTraitStore
(
ty
::
ReEmpty
),
// dummy region
ast
::
OwnedSigil
=>
ty
::
UniqTraitStore
,
ast
::
ManagedSigil
=>
ty
::
BoxTraitStore
,
});
let
fn_decl
=
ty_of_closure
(
this
,
rscope
,
ast_ty
.id
,
f
.sigil
,
f
.purity
,
f
.onceness
,
bounds
,
&
f
.region
,
f
.decl
,
None
,
ast_ty
.span
);
ty
::
mk_closure
(
tcx
,
fn_decl
)
}
ast
::
TyPath
(
ref
path
,
ref
bounds
,
id
)
=>
{
let
def_map
=
tcx
.def_map
.borrow
();
let
a_def
=
match
def_map
.get
()
.find
(
&
id
)
{
None
=>
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
,
tcx
.sess
.intr
()))),
Some
(
&
d
)
=>
d
};
// Kind bounds on path types are only supported for traits.
match
a_def
{
// But don't emit the error if the user meant to do a trait anyway.
ast
::
DefTrait
(
..
)
=>
{
},
_
if
bounds
.is_some
()
=>
tcx
.sess
.span_err
(
ast_ty
.span
,
"kind bounds can only be used on trait types"
),
_
=>
{
},
}
match
a_def
{
ast
::
DefTrait
(
_
)
=>
{
let
path_str
=
path_to_str
(
path
,
tcx
.sess
.intr
());
tcx
.sess
.span_err
(
ast_ty
.span
,
format!
(
"reference to trait `{}` where a type is expected;
\
try `@{}`, `~{}`, or `&{}`"
,
path_str
,
path_str
,
path_str
,
path_str
));
ty
::
mk_err
()
}
ast
::
DefTy
(
did
)
|
ast
::
DefStruct
(
did
)
=>
{
ast_path_to_ty
(
this
,
rscope
,
did
,
path
)
.ty
}
ast
::
DefPrimTy
(
nty
)
=>
{
match
nty
{
ast
::
TyBool
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_bool
()
}
ast
::
TyChar
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_char
()
}
ast
::
TyInt
(
it
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_mach_int
(
it
)
}
ast
::
TyUint
(
uit
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_mach_uint
(
uit
)
}
ast
::
TyFloat
(
ft
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_mach_float
(
ft
)
}
ast
::
TyStr
=>
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"bare `str` is not a type"
);
let
typ
=
ast_ty_to_prim_ty
(
tcx
,
ast_ty
)
.unwrap_or_else
(||
match
ast_ty
.node
{
ast
::
TyNil
=>
ty
::
mk_nil
(),
ast
::
TyBot
=>
ty
::
mk_bot
(),
ast
::
TyBox
(
ty
)
=>
{
let
mt
=
ast
::
MutTy
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
};
mk_pointer
(
this
,
rscope
,
&
mt
,
ty
::
vstore_box
,
|
tmt
|
ty
::
mk_box
(
tcx
,
tmt
.ty
))
}
ast
::
TyUniq
(
ty
)
=>
{
let
mt
=
ast
::
MutTy
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
};
mk_pointer
(
this
,
rscope
,
&
mt
,
ty
::
vstore_uniq
,
|
tmt
|
ty
::
mk_uniq
(
tcx
,
tmt
.ty
))
}
ast
::
TyVec
(
ty
)
=>
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"bare `[]` is not a type"
);
// return /something/ so they can at least get more errors
ty
::
mk_str
(
tcx
,
ty
::
vstore_uniq
)
}
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_uniq
)
}
}
ast
::
DefTyParam
(
id
,
n
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_param
(
tcx
,
n
,
id
)
}
ast
::
DefSelfTy
(
id
)
=>
{
// n.b.: resolve guarantees that the this type only appears in a
// trait, which we rely upon in various places when creating
// substs
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
let
did
=
ast_util
::
local_def
(
id
);
ty
::
mk_self
(
tcx
,
did
)
}
ast
::
DefMod
(
id
)
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"found module name used as a type: {}"
,
ast_map
::
node_id_to_str
(
tcx
.items
,
id
.node
,
token
::
get_ident_interner
())));
}
_
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"found value name used as a type: {:?}"
,
a_def
));
}
}
}
ast
::
TyFixedLengthVec
(
ty
,
e
)
=>
{
match
const_eval
::
eval_const_expr_partial
(
&
tcx
,
e
)
{
Ok
(
ref
r
)
=>
{
match
*
r
{
const_eval
::
const_int
(
i
)
=>
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_fixed
(
i
as
uint
)),
const_eval
::
const_uint
(
i
)
=>
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_fixed
(
i
as
uint
)),
_
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
"expected constant expr for vector length"
);
}
ast
::
TyPtr
(
ref
mt
)
=>
{
ty
::
mk_ptr
(
tcx
,
ast_mt_to_mt
(
this
,
rscope
,
mt
))
}
}
Err
(
ref
r
)
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"expected constant expr for vector length: {}"
,
*
r
));
}
}
}
ast
::
TyTypeof
(
_
e
)
=>
{
tcx
.sess
.span_bug
(
ast_ty
.span
,
"typeof is reserved but unimplemented"
);
}
ast
::
TyInfer
=>
{
// ty_infer should only appear as the type of arguments or return
// values in a fn_expr, or as the type of local variables. Both of
// these cases are handled specially and should not descend into this
// routine.
this
.tcx
()
.sess
.span_bug
(
ast_ty
.span
,
"found `ty_infer` in unexpected place"
);
}
};
ast
::
TyRptr
(
ref
region
,
ref
mt
)
=>
{
let
r
=
opt_ast_region_to_region
(
this
,
rscope
,
ast_ty
.span
,
region
);
debug!
(
"ty_rptr r={}"
,
r
.repr
(
this
.tcx
()));
mk_pointer
(
this
,
rscope
,
mt
,
ty
::
vstore_slice
(
r
),
|
tmt
|
ty
::
mk_rptr
(
tcx
,
r
,
tmt
))
}
ast
::
TyTup
(
ref
fields
)
=>
{
let
flds
=
fields
.map
(|
&
t
|
ast_ty_to_ty
(
this
,
rscope
,
t
));
ty
::
mk_tup
(
tcx
,
flds
)
}
ast
::
TyBareFn
(
ref
bf
)
=>
{
if
bf
.decl.variadic
&&
!
bf
.abis
.is_c
()
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"variadic function must have C calling convention"
);
}
ty
::
mk_bare_fn
(
tcx
,
ty_of_bare_fn
(
this
,
ast_ty
.id
,
bf
.purity
,
bf
.abis
,
bf
.decl
))
}
ast
::
TyClosure
(
ref
f
)
=>
{
if
f
.sigil
==
ast
::
ManagedSigil
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"managed closures are not supported"
);
}
let
bounds
=
conv_builtin_bounds
(
this
.tcx
(),
&
f
.bounds
,
match
f
.sigil
{
// Use corresponding trait store to figure out default bounds
// if none were specified.
ast
::
BorrowedSigil
=>
ty
::
RegionTraitStore
(
ty
::
ReEmpty
),
// dummy region
ast
::
OwnedSigil
=>
ty
::
UniqTraitStore
,
ast
::
ManagedSigil
=>
ty
::
BoxTraitStore
,
});
let
fn_decl
=
ty_of_closure
(
this
,
rscope
,
ast_ty
.id
,
f
.sigil
,
f
.purity
,
f
.onceness
,
bounds
,
&
f
.region
,
f
.decl
,
None
,
ast_ty
.span
);
ty
::
mk_closure
(
tcx
,
fn_decl
)
}
ast
::
TyPath
(
ref
path
,
ref
bounds
,
id
)
=>
{
let
def_map
=
tcx
.def_map
.borrow
();
let
a_def
=
match
def_map
.get
()
.find
(
&
id
)
{
None
=>
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
,
tcx
.sess
.intr
()))),
Some
(
&
d
)
=>
d
};
// Kind bounds on path types are only supported for traits.
match
a_def
{
// But don't emit the error if the user meant to do a trait anyway.
ast
::
DefTrait
(
..
)
=>
{
},
_
if
bounds
.is_some
()
=>
tcx
.sess
.span_err
(
ast_ty
.span
,
"kind bounds can only be used on trait types"
),
_
=>
{
},
}
match
a_def
{
ast
::
DefTrait
(
_
)
=>
{
let
path_str
=
path_to_str
(
path
,
tcx
.sess
.intr
());
tcx
.sess
.span_err
(
ast_ty
.span
,
format!
(
"reference to trait `{}` where a type is expected;
\
try `@{}`, `~{}`, or `&{}`"
,
path_str
,
path_str
,
path_str
,
path_str
));
ty
::
mk_err
()
}
ast
::
DefTy
(
did
)
|
ast
::
DefStruct
(
did
)
=>
{
ast_path_to_ty
(
this
,
rscope
,
did
,
path
)
.ty
}
ast
::
DefTyParam
(
id
,
n
)
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
ty
::
mk_param
(
tcx
,
n
,
id
)
}
ast
::
DefSelfTy
(
id
)
=>
{
// n.b.: resolve guarantees that the this type only appears in a
// trait, which we rely upon in various places when creating
// substs
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
let
did
=
ast_util
::
local_def
(
id
);
ty
::
mk_self
(
tcx
,
did
)
}
ast
::
DefMod
(
id
)
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"found module name used as a type: {}"
,
ast_map
::
node_id_to_str
(
tcx
.items
,
id
.node
,
token
::
get_ident_interner
())));
}
ast
::
DefPrimTy
(
_
)
=>
{
fail
!
(
"DefPrimTy arm missed in previous ast_ty_to_prim_ty call"
);
}
_
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"found value name used as a type: {:?}"
,
a_def
));
}
}
}
ast
::
TyFixedLengthVec
(
ty
,
e
)
=>
{
match
const_eval
::
eval_const_expr_partial
(
&
tcx
,
e
)
{
Ok
(
ref
r
)
=>
{
match
*
r
{
const_eval
::
const_int
(
i
)
=>
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_fixed
(
i
as
uint
)),
const_eval
::
const_uint
(
i
)
=>
ty
::
mk_vec
(
tcx
,
ast_ty_to_mt
(
this
,
rscope
,
ty
),
ty
::
vstore_fixed
(
i
as
uint
)),
_
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
"expected constant expr for vector length"
);
}
}
}
Err
(
ref
r
)
=>
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
format!
(
"expected constant expr for vector length: {}"
,
*
r
));
}
}
}
ast
::
TyTypeof
(
_
e
)
=>
{
tcx
.sess
.span_bug
(
ast_ty
.span
,
"typeof is reserved but unimplemented"
);
}
ast
::
TyInfer
=>
{
// ty_infer should only appear as the type of arguments or return
// values in a fn_expr, or as the type of local variables. Both of
// these cases are handled specially and should not descend into this
// routine.
this
.tcx
()
.sess
.span_bug
(
ast_ty
.span
,
"found `ty_infer` in unexpected place"
);
}
});
let
mut
ast_ty_to_ty_cache
=
tcx
.ast_ty_to_ty_cache
.borrow_mut
();
ast_ty_to_ty_cache
.get
()
.insert
(
ast_ty
.id
,
ty
::
atttce_resolved
(
typ
));
...
...
src/librustc/middle/typeck/check/mod.rs
浏览文件 @
9b1865a7
...
...
@@ -4285,4 +4285,3 @@ fn param(ccx: @CrateCtxt, n: uint) -> ty::t {
ppaux
::
ty_to_str
(
ccx
.tcx
,
fty
)));
}
}
src/test/run-pass/issue-5900.rs
0 → 100644
浏览文件 @
9b1865a7
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub
mod
foo
{
use
super
::
Bar
;
pub
struct
FooStruct
{
bar
:
Bar
}
}
pub
enum
Bar
{
Bar0
=
0
as
int
}
pub
fn
main
()
{}
src/test/run-pass/issue-9942.rs
0 → 100644
浏览文件 @
9b1865a7
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub
fn
main
()
{
static
S
:
uint
=
23
as
uint
;
[
0
,
..
S
];
()
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录