Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
9783947c
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,发现更多精彩内容 >>
提交
9783947c
编写于
1月 13, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_typeck: move impl Trait checks out of RegionScope.
上级
ba1849da
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
65 addition
and
143 deletion
+65
-143
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+53
-41
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+10
-22
src/librustc_typeck/lib.rs
src/librustc_typeck/lib.rs
+1
-0
src/librustc_typeck/rscope.rs
src/librustc_typeck/rscope.rs
+0
-79
src/test/compile-fail/impl-trait/disallowed.rs
src/test/compile-fail/impl-trait/disallowed.rs
+1
-1
未找到文件。
src/librustc_typeck/astconv.rs
浏览文件 @
9783947c
...
...
@@ -62,7 +62,7 @@
use
rustc_back
::
slice
;
use
require_c_abi_if_variadic
;
use
rscope
::{
RegionScope
,
ObjectLifetimeDefaultRscope
,
ShiftedRscope
};
use
rscope
::
{
AnonTypeScope
,
MaybeWithAnonTypes
,
ExplicitRscope
}
;
use
rscope
::
ExplicitRscope
;
use
util
::
common
::{
ErrorReported
,
FN_OUTPUT_NAME
};
use
util
::
nodemap
::{
NodeMap
,
FxHashSet
};
...
...
@@ -361,8 +361,7 @@ fn create_substs_for_ast_path(&self,
}
hir
::
ParenthesizedParameters
(
ref
data
)
=>
{
assert_eq!
(
i
,
0
);
let
(
ty
,
assoc
)
=
self
.convert_parenthesized_parameters
(
rscope
,
substs
,
data
);
let
(
ty
,
assoc
)
=
self
.convert_parenthesized_parameters
(
substs
,
data
);
output_assoc_binding
=
Some
(
assoc
);
ty
}
...
...
@@ -416,7 +415,7 @@ fn create_substs_for_ast_path(&self,
vec!
[
output_assoc_binding
.unwrap_or_else
(||
{
// This is an error condition, but we should
// get the associated type binding anyway.
self
.convert_parenthesized_parameters
(
rscope
,
substs
,
data
)
.1
self
.convert_parenthesized_parameters
(
substs
,
data
)
.1
})]
}
};
...
...
@@ -428,20 +427,17 @@ fn create_substs_for_ast_path(&self,
}
fn
convert_parenthesized_parameters
(
&
self
,
rscope
:
&
RegionScope
,
region_substs
:
&
[
Kind
<
'tcx
>
],
data
:
&
hir
::
ParenthesizedParameterData
)
->
(
Ty
<
'tcx
>
,
ConvertedBinding
<
'tcx
>
)
{
let
anon_scope
=
rscope
.anon_type_scope
();
let
rscope
=
MaybeWithAnonTypes
::
new
(
ExplicitRscope
,
anon_scope
);
let
inputs
=
self
.tcx
()
.mk_type_list
(
data
.inputs
.iter
()
.map
(|
a_t
|
{
self
.ast_ty_arg_to_ty
(
&
r
scope
,
None
,
region_substs
,
a_t
)
self
.ast_ty_arg_to_ty
(
&
ExplicitR
scope
,
None
,
region_substs
,
a_t
)
}));
let
(
output
,
output_span
)
=
match
data
.output
{
Some
(
ref
output_ty
)
=>
{
(
self
.ast_ty_to_ty
(
&
r
scope
,
output_ty
),
output_ty
.span
)
(
self
.ast_ty_to_ty
(
&
ExplicitR
scope
,
output_ty
),
output_ty
.span
)
}
None
=>
{
(
self
.tcx
()
.mk_nil
(),
data
.span
)
...
...
@@ -1309,12 +1305,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
}
hir
::
TyBareFn
(
ref
bf
)
=>
{
require_c_abi_if_variadic
(
tcx
,
&
bf
.decl
,
bf
.abi
,
ast_ty
.span
);
let
anon_scope
=
rscope
.anon_type_scope
();
let
bare_fn_ty
=
self
.ty_of_method_or_bare_fn
(
bf
.unsafety
,
bf
.abi
,
&
bf
.decl
,
anon_scope
,
anon_scope
);
let
bare_fn_ty
=
self
.ty_of_fn
(
bf
.unsafety
,
bf
.abi
,
&
bf
.decl
);
// Find any late-bound regions declared in return type that do
// not appear in the arguments. These are not wellformed.
...
...
@@ -1361,16 +1352,54 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
hir
::
TyImplTrait
(
ref
bounds
)
=>
{
use
collect
::{
compute_bounds
,
SizedByDefault
};
// Figure out if we can allow an `impl Trait` here, by walking up
// to a `fn` or inherent `impl` method, going only through `Ty`
// or `TraitRef` nodes (as nothing else should be in types) and
// ensuring that we reach the `fn`/method signature's return type.
let
mut
node_id
=
ast_ty
.id
;
let
fn_decl
=
loop
{
let
parent
=
tcx
.hir
.get_parent_node
(
node_id
);
match
tcx
.hir
.get
(
parent
)
{
hir
::
map
::
NodeItem
(
&
hir
::
Item
{
node
:
hir
::
ItemFn
(
ref
fn_decl
,
..
),
..
})
=>
break
Some
(
fn_decl
),
hir
::
map
::
NodeImplItem
(
&
hir
::
ImplItem
{
node
:
hir
::
ImplItemKind
::
Method
(
ref
sig
,
_
),
..
})
=>
{
match
tcx
.hir
.expect_item
(
tcx
.hir
.get_parent
(
parent
))
.node
{
hir
::
ItemImpl
(
..
,
None
,
_
,
_
)
=>
{
break
Some
(
&
sig
.decl
)
}
_
=>
break
None
}
}
hir
::
map
::
NodeTy
(
_
)
|
hir
::
map
::
NodeTraitRef
(
_
)
=>
{}
_
=>
break
None
}
node_id
=
parent
;
};
let
allow
=
fn_decl
.map_or
(
false
,
|
fd
|
{
match
fd
.output
{
hir
::
DefaultReturn
(
_
)
=>
false
,
hir
::
Return
(
ref
ty
)
=>
ty
.id
==
node_id
}
});
// Create the anonymized type.
let
def_id
=
tcx
.hir
.local_def_id
(
ast_ty
.id
);
if
let
Some
(
anon_scope
)
=
rscope
.anon_type_scope
()
{
let
substs
=
anon_scope
.fresh_substs
(
self
,
ast_ty
.span
);
if
allow
{
let
def_id
=
tcx
.hir
.local_def_id
(
ast_ty
.id
);
if
let
Err
(
ErrorReported
)
=
self
.get_generics
(
ast_ty
.span
,
def_id
)
{
return
tcx
.types.err
;
}
let
substs
=
Substs
::
identity_for_item
(
tcx
,
def_id
);
let
ty
=
tcx
.mk_anon
(
tcx
.hir
.local_def_id
(
ast_ty
.id
),
substs
);
// Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
let
bounds
=
compute_bounds
(
self
,
ty
,
bounds
,
SizedByDefault
::
Yes
,
Some
(
anon_scope
),
ast_ty
.span
);
let
predicates
=
bounds
.predicates
(
tcx
,
ty
);
let
predicates
=
tcx
.lift_to_global
(
&
predicates
)
.unwrap
();
...
...
@@ -1450,36 +1479,19 @@ pub fn ty_of_arg(&self,
pub
fn
ty_of_fn
(
&
self
,
unsafety
:
hir
::
Unsafety
,
abi
:
abi
::
Abi
,
decl
:
&
hir
::
FnDecl
,
anon_scope
:
Option
<
AnonTypeScope
>
)
decl
:
&
hir
::
FnDecl
)
->
&
'tcx
ty
::
BareFnTy
<
'tcx
>
{
self
.ty_of_method_or_bare_fn
(
unsafety
,
abi
,
decl
,
None
,
anon_scope
)
}
fn
ty_of_method_or_bare_fn
(
&
self
,
unsafety
:
hir
::
Unsafety
,
abi
:
abi
::
Abi
,
decl
:
&
hir
::
FnDecl
,
arg_anon_scope
:
Option
<
AnonTypeScope
>
,
ret_anon_scope
:
Option
<
AnonTypeScope
>
)
->
&
'tcx
ty
::
BareFnTy
<
'tcx
>
{
debug!
(
"ty_of_method_or_bare_fn"
);
// New region names that appear inside of the arguments of the function
// declaration are bound to that function type.
let
rb
=
MaybeWithAnonTypes
::
new
(
ExplicitRscope
,
arg_anon_scope
);
debug!
(
"ty_of_fn"
);
let
input_tys
:
Vec
<
Ty
>
=
decl
.inputs
.iter
()
.map
(|
a
|
self
.ty_of_arg
(
&
rb
,
a
,
None
))
.collect
();
decl
.inputs
.iter
()
.map
(|
a
|
self
.ty_of_arg
(
&
ExplicitRscope
,
a
,
None
))
.collect
();
let
output_ty
=
match
decl
.output
{
hir
::
Return
(
ref
output
)
=>
self
.ast_ty_to_ty
(
&
MaybeWithAnonTypes
::
new
(
ExplicitRscope
,
ret_anon_scope
),
output
),
hir
::
Return
(
ref
output
)
=>
self
.ast_ty_to_ty
(
&
ExplicitRscope
,
output
),
hir
::
DefaultReturn
(
..
)
=>
self
.tcx
()
.mk_nil
(),
};
debug!
(
"ty_of_
method_or_bare_
fn: output_ty={:?}"
,
output_ty
);
debug!
(
"ty_of_fn: output_ty={:?}"
,
output_ty
);
self
.tcx
()
.mk_bare_fn
(
ty
::
BareFnTy
{
unsafety
:
unsafety
,
...
...
src/librustc_typeck/collect.rs
浏览文件 @
9783947c
...
...
@@ -641,7 +641,6 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
fn
convert_method
<
'a
,
'tcx
>
(
ccx
:
&
CrateCtxt
<
'a
,
'tcx
>
,
container
:
AssociatedItemContainer
,
id
:
ast
::
NodeId
,
sig
:
&
hir
::
MethodSig
,
rcvr_ty_predicates
:
&
ty
::
GenericPredicates
<
'tcx
>
,)
{
...
...
@@ -651,12 +650,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let
ty_generic_predicates
=
ty_generic_predicates
(
ccx
,
&
sig
.generics
,
ty_generics
.parent
,
vec!
[],
false
);
let
anon_scope
=
match
container
{
ImplContainer
(
_
)
=>
Some
(
AnonTypeScope
::
new
(
def_id
)),
TraitContainer
(
_
)
=>
None
};
let
fty
=
AstConv
::
ty_of_fn
(
&
ccx
.icx
(
&
(
rcvr_ty_predicates
,
&
sig
.generics
)),
sig
.unsafety
,
sig
.abi
,
&
sig
.decl
,
anon_scope
);
sig
.unsafety
,
sig
.abi
,
&
sig
.decl
);
let
substs
=
mk_item_substs
(
&
ccx
.icx
(
&
(
rcvr_ty_predicates
,
&
sig
.generics
)),
ccx
.tcx.hir
.span
(
id
),
def_id
);
...
...
@@ -874,8 +869,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) {
}
hir
::
TraitItemKind
::
Method
(
ref
sig
,
_
)
=>
{
convert_method
(
ccx
,
TraitContainer
(
trait_def_id
),
trait_item
.id
,
sig
,
&
trait_predicates
);
convert_method
(
ccx
,
trait_item
.id
,
sig
,
&
trait_predicates
);
}
}
}
...
...
@@ -915,7 +909,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
}
hir
::
ImplItemKind
::
Method
(
ref
sig
,
_
)
=>
{
convert_method
(
ccx
,
ImplContainer
(
impl_def_id
),
impl_item
.id
,
sig
,
&
impl_predicates
);
convert_method
(
ccx
,
impl_item
.id
,
sig
,
&
impl_predicates
);
}
}
}
...
...
@@ -1186,7 +1180,6 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
self_param_ty
,
bounds
,
SizedByDefault
::
No
,
None
,
item
.span
);
let
superbounds1
=
superbounds1
.predicates
(
tcx
,
self_param_ty
);
...
...
@@ -1323,7 +1316,6 @@ fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
assoc_ty
,
bounds
,
SizedByDefault
::
Yes
,
None
,
trait_item
.span
);
bounds
.predicates
(
ccx
.tcx
,
assoc_ty
)
.into_iter
()
...
...
@@ -1537,8 +1529,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ccx
.icx
(
&
())
.to_ty
(
&
ExplicitRscope
,
&
t
)
}
ItemFn
(
ref
decl
,
unsafety
,
_
,
abi
,
ref
generics
,
_
)
=>
{
let
tofd
=
AstConv
::
ty_of_fn
(
&
ccx
.icx
(
generics
),
unsafety
,
abi
,
&
decl
,
Some
(
AnonTypeScope
::
new
(
def_id
)));
let
tofd
=
AstConv
::
ty_of_fn
(
&
ccx
.icx
(
generics
),
unsafety
,
abi
,
&
decl
);
let
substs
=
mk_item_substs
(
&
ccx
.icx
(
generics
),
item
.span
,
def_id
);
ccx
.tcx
.mk_fn_def
(
def_id
,
substs
,
tofd
)
}
...
...
@@ -1770,7 +1761,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
param_ty
,
&
param
.bounds
,
SizedByDefault
::
Yes
,
None
,
param
.span
);
predicates
.extend
(
bounds
.predicates
(
ccx
.tcx
,
param_ty
));
}
...
...
@@ -1968,7 +1958,6 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
param_ty
:
ty
::
Ty
<
'tcx
>
,
ast_bounds
:
&
[
hir
::
TyParamBound
],
sized_by_default
:
SizedByDefault
,
anon_scope
:
Option
<
AnonTypeScope
>
,
span
:
Span
)
->
Bounds
<
'tcx
>
{
...
...
@@ -1979,9 +1968,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
let
mut
projection_bounds
=
vec!
[];
let
rscope
=
MaybeWithAnonTypes
::
new
(
ExplicitRscope
,
anon_scope
);
let
mut
trait_bounds
:
Vec
<
_
>
=
trait_bounds
.iter
()
.map
(|
&
bound
|
{
astconv
.instantiate_poly_trait_ref
(
&
r
scope
,
astconv
.instantiate_poly_trait_ref
(
&
ExplicitR
scope
,
bound
,
param_ty
,
&
mut
projection_bounds
)
...
...
@@ -2048,7 +2036,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
abi
:
abi
::
Abi
)
->
Ty
<
'tcx
>
{
let
fty
=
AstConv
::
ty_of_fn
(
&
ccx
.icx
(
ast_generics
),
hir
::
Unsafety
::
Unsafe
,
abi
,
decl
,
None
);
let
fty
=
AstConv
::
ty_of_fn
(
&
ccx
.icx
(
ast_generics
),
hir
::
Unsafety
::
Unsafe
,
abi
,
decl
);
// feature gate SIMD types in FFI, since I (huonw) am not sure the
// ABIs are handled at all correctly.
...
...
@@ -2077,10 +2065,10 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
ccx
.tcx
.mk_fn_def
(
def_id
,
substs
,
fty
)
}
pub
fn
mk_item_substs
<
'gcx
:
'tcx
,
'tcx
>
(
astconv
:
&
AstConv
<
'g
cx
,
'tcx
>
,
span
:
Span
,
def_id
:
DefId
)
->
&
'tcx
Substs
<
'tcx
>
{
fn
mk_item_substs
<
'tcx
>
(
astconv
:
&
AstConv
<
't
cx
,
'tcx
>
,
span
:
Span
,
def_id
:
DefId
)
->
&
'tcx
Substs
<
'tcx
>
{
let
tcx
=
astconv
.tcx
();
// FIXME(eddyb) Do this request from Substs::for_item in librustc.
if
let
Err
(
ErrorReported
)
=
astconv
.get_generics
(
span
,
def_id
)
{
...
...
src/librustc_typeck/lib.rs
浏览文件 @
9783947c
...
...
@@ -77,6 +77,7 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![feature(loop_break_value)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
...
...
src/librustc_typeck/rscope.rs
浏览文件 @
9783947c
...
...
@@ -8,11 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
ty
;
use
rustc
::
ty
::
subst
::
Substs
;
use
astconv
::
AstConv
;
use
syntax_pos
::
Span
;
...
...
@@ -38,73 +34,6 @@ pub trait RegionScope {
/// computing `object_lifetime_default` (in particular, in legacy
/// modes, it may not be relevant).
fn
base_object_lifetime_default
(
&
self
,
span
:
Span
)
->
ty
::
Region
;
/// If this scope allows anonymized types, return the generics in
/// scope, that anonymized types will close over. For example,
/// if you have a function like:
///
/// fn foo<'a, T>() -> impl Trait { ... }
///
/// then, for the rscope that is used when handling the return type,
/// `anon_type_scope()` would return a `Some(AnonTypeScope {...})`,
/// on which `.fresh_substs(...)` can be used to obtain identity
/// Substs for `'a` and `T`, to track them in `TyAnon`. This property
/// is controlled by the region scope because it's fine-grained enough
/// to allow restriction of anonymized types to the syntactical extent
/// of a function's return type.
fn
anon_type_scope
(
&
self
)
->
Option
<
AnonTypeScope
>
{
None
}
}
#[derive(Copy,
Clone)]
pub
struct
AnonTypeScope
{
enclosing_item
:
DefId
}
impl
<
'gcx
:
'tcx
,
'tcx
>
AnonTypeScope
{
pub
fn
new
(
enclosing_item
:
DefId
)
->
AnonTypeScope
{
AnonTypeScope
{
enclosing_item
:
enclosing_item
}
}
pub
fn
fresh_substs
(
&
self
,
astconv
:
&
AstConv
<
'gcx
,
'tcx
>
,
span
:
Span
)
->
&
'tcx
Substs
<
'tcx
>
{
use
collect
::
mk_item_substs
;
mk_item_substs
(
astconv
,
span
,
self
.enclosing_item
)
}
}
/// A scope wrapper which optionally allows anonymized types.
#[derive(Copy,
Clone)]
pub
struct
MaybeWithAnonTypes
<
R
>
{
base_scope
:
R
,
anon_scope
:
Option
<
AnonTypeScope
>
}
impl
<
R
:
RegionScope
>
MaybeWithAnonTypes
<
R
>
{
pub
fn
new
(
base_scope
:
R
,
anon_scope
:
Option
<
AnonTypeScope
>
)
->
Self
{
MaybeWithAnonTypes
{
base_scope
:
base_scope
,
anon_scope
:
anon_scope
}
}
}
impl
<
R
:
RegionScope
>
RegionScope
for
MaybeWithAnonTypes
<
R
>
{
fn
object_lifetime_default
(
&
self
,
span
:
Span
)
->
Option
<
ty
::
Region
>
{
self
.base_scope
.object_lifetime_default
(
span
)
}
fn
base_object_lifetime_default
(
&
self
,
span
:
Span
)
->
ty
::
Region
{
self
.base_scope
.base_object_lifetime_default
(
span
)
}
fn
anon_type_scope
(
&
self
)
->
Option
<
AnonTypeScope
>
{
self
.anon_scope
}
}
// A scope in which all regions must be explicitly named. This is used
...
...
@@ -158,10 +87,6 @@ fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
fn
base_object_lifetime_default
(
&
self
,
span
:
Span
)
->
ty
::
Region
{
self
.base_scope
.base_object_lifetime_default
(
span
)
}
fn
anon_type_scope
(
&
self
)
->
Option
<
AnonTypeScope
>
{
self
.base_scope
.anon_type_scope
()
}
}
/// A scope which simply shifts the Debruijn index of other scopes
...
...
@@ -185,8 +110,4 @@ fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
fn
base_object_lifetime_default
(
&
self
,
span
:
Span
)
->
ty
::
Region
{
ty
::
fold
::
shift_region
(
self
.base_scope
.base_object_lifetime_default
(
span
),
1
)
}
fn
anon_type_scope
(
&
self
)
->
Option
<
AnonTypeScope
>
{
self
.base_scope
.anon_type_scope
()
}
}
src/test/compile-fail/impl-trait/disallowed.rs
浏览文件 @
9783947c
...
...
@@ -26,9 +26,9 @@ trait LazyToString {
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}
// Note that the following impl doesn't error, because the trait is invalid.
impl
LazyToString
for
String
{
fn
lazy_to_string
<
'a
>
(
&
'a
self
)
->
impl
Fn
()
->
String
{
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
||
self
.clone
()
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录