Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b64c7b83
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,发现更多精彩内容 >>
提交
b64c7b83
编写于
11月 08, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor QPath to take an ast::TraitRef
上级
cf7df1e6
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
122 addition
and
190 deletion
+122
-190
src/librustc/middle/resolve.rs
src/librustc/middle/resolve.rs
+4
-59
src/librustc/middle/subst.rs
src/librustc/middle/subst.rs
+4
-0
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/mod.rs
+1
-4
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+1
-1
src/librustc/middle/traits/util.rs
src/librustc/middle/traits/util.rs
+2
-1
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/astconv.rs
+38
-90
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/collect.rs
+18
-13
src/librustc/util/common.rs
src/librustc/util/common.rs
+4
-0
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+3
-3
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+16
-6
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+5
-5
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+2
-2
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+2
-2
src/test/compile-fail/associated-types-in-ambiguous-context.rs
...est/compile-fail/associated-types-in-ambiguous-context.rs
+2
-2
src/test/compile-fail/associated-types-in-wrong-context.rs
src/test/compile-fail/associated-types-in-wrong-context.rs
+2
-2
src/test/run-pass/associated-types-qualified-path-with-trait-with-type-parameters.rs
...d-types-qualified-path-with-trait-with-type-parameters.rs
+18
-0
未找到文件。
src/librustc/middle/resolve.rs
浏览文件 @
b64c7b83
...
...
@@ -633,6 +633,7 @@ enum TraitReferenceType {
TraitDerivation
,
// trait T : SomeTrait { ... }
TraitBoundingTypeParameter
,
// fn f<T:SomeTrait>() { ... }
TraitObject
,
// Box<for<'a> SomeTrait>
TraitQPath
,
// <T as SomeTrait>::
}
impl
NameBindings
{
...
...
@@ -4532,6 +4533,7 @@ fn resolve_trait_reference(&mut self,
TraitImplementation
=>
"implement"
,
TraitDerivation
=>
"derive"
,
TraitObject
=>
"reference"
,
TraitQPath
=>
"extract an associated type from"
,
};
let
msg
=
format!
(
"attempt to {} a nonexistent trait `{}`"
,
usage_str
,
path_str
);
...
...
@@ -4969,65 +4971,8 @@ fn resolve_type(&mut self, ty: &Ty) {
}
TyQPath
(
ref
qpath
)
=>
{
self
.resolve_type
(
&*
qpath
.for_type
);
let
current_module
=
self
.current_module
.clone
();
let
module_path
:
Vec
<
_
>
=
qpath
.trait_name
.segments
.iter
()
.map
(|
ps
|
ps
.identifier.name
)
.collect
();
match
self
.resolve_module_path
(
current_module
,
module_path
.as_slice
(),
UseLexicalScope
,
qpath
.trait_name.span
,
PathSearch
)
{
Success
((
ref
module
,
_
))
if
module
.kind
.get
()
==
TraitModuleKind
=>
{
match
self
.resolve_definition_of_name_in_module
(
(
*
module
)
.clone
(),
qpath
.item_name.name
,
TypeNS
)
{
ChildNameDefinition
(
def
,
lp
)
|
ImportNameDefinition
(
def
,
lp
)
=>
{
match
def
{
DefAssociatedTy
(
trait_type_id
)
=>
{
let
def
=
DefAssociatedTy
(
trait_type_id
);
self
.record_def
(
ty
.id
,
(
def
,
lp
));
}
_
=>
{
self
.resolve_error
(
ty
.span
,
"not an associated type"
);
}
}
}
NoNameDefinition
=>
{
self
.resolve_error
(
ty
.span
,
"unresolved associated
\
type"
);
}
}
}
Success
(
..
)
=>
self
.resolve_error
(
ty
.span
,
"not a trait"
),
Indeterminate
=>
{
self
.session
.span_bug
(
ty
.span
,
"indeterminate result when
\
resolving associated type"
)
}
Failed
(
error
)
=>
{
let
(
span
,
help
)
=
match
error
{
Some
((
span
,
msg
))
=>
(
span
,
format!
(
"; {}"
,
msg
)),
None
=>
(
ty
.span
,
String
::
new
()),
};
self
.resolve_error
(
span
,
format!
(
"unresolved trait: {}"
,
help
)
.as_slice
())
}
}
self
.resolve_type
(
&*
qpath
.self_type
);
self
.resolve_trait_reference
(
ty
.id
,
&*
qpath
.trait_ref
,
TraitQPath
);
}
TyClosure
(
ref
c
)
|
TyProc
(
ref
c
)
=>
{
...
...
src/librustc/middle/subst.rs
浏览文件 @
b64c7b83
...
...
@@ -100,6 +100,10 @@ pub fn is_noop(&self) -> bool {
regions_is_noop
&&
self
.types
.is_empty
()
}
pub
fn
type_for_def
(
&
self
,
ty_param_def
:
&
ty
::
TypeParameterDef
)
->
Ty
<
'tcx
>
{
*
self
.types
.get
(
ty_param_def
.space
,
ty_param_def
.index
)
}
pub
fn
has_regions_escaping_depth
(
&
self
,
depth
:
uint
)
->
bool
{
self
.types
.iter
()
.any
(|
&
t
|
ty
::
type_escapes_depth
(
t
,
depth
))
||
{
match
self
.regions
{
...
...
src/librustc/middle/traits/mod.rs
浏览文件 @
b64c7b83
...
...
@@ -25,6 +25,7 @@
use
std
::
slice
::
Items
;
use
syntax
::
ast
;
use
syntax
::
codemap
::{
Span
,
DUMMY_SP
};
use
util
::
common
::
ErrorReported
;
pub
use
self
::
fulfill
::
FulfillmentContext
;
pub
use
self
::
select
::
SelectionContext
;
...
...
@@ -95,10 +96,6 @@ pub enum ObligationCauseCode<'tcx> {
FieldSized
,
}
// An error has already been reported to the user, so no need to continue checking.
#[deriving(Clone,Show)]
pub
struct
ErrorReported
;
pub
type
Obligations
<
'tcx
>
=
subst
::
VecPerParamSpace
<
Obligation
<
'tcx
>>
;
pub
type
Selection
<
'tcx
>
=
Vtable
<
'tcx
,
Obligation
<
'tcx
>>
;
...
...
src/librustc/middle/traits/select.rs
浏览文件 @
b64c7b83
...
...
@@ -17,7 +17,6 @@
use
self
::
BuiltinBoundConditions
::
*
;
use
self
::
EvaluationResult
::
*
;
use
super
::{
ErrorReported
};
use
super
::{
Obligation
,
ObligationCause
};
use
super
::{
SelectionError
,
Unimplemented
,
Overflow
,
OutputTypeParameterMismatch
};
...
...
@@ -38,6 +37,7 @@
use
std
::
collections
::
hash_map
::
HashMap
;
use
std
::
rc
::
Rc
;
use
syntax
::
ast
;
use
util
::
common
::
ErrorReported
;
use
util
::
ppaux
::
Repr
;
pub
struct
SelectionContext
<
'cx
,
'tcx
:
'cx
>
{
...
...
src/librustc/middle/traits/util.rs
浏览文件 @
b64c7b83
...
...
@@ -18,9 +18,10 @@
use
std
::
rc
::
Rc
;
use
syntax
::
ast
;
use
syntax
::
codemap
::
Span
;
use
util
::
common
::
ErrorReported
;
use
util
::
ppaux
::
Repr
;
use
super
::{
ErrorReported
,
Obligation
,
ObligationCause
,
VtableImpl
,
use
super
::{
Obligation
,
ObligationCause
,
VtableImpl
,
VtableParam
,
VtableParamData
,
VtableImplData
};
///////////////////////////////////////////////////////////////////////////
...
...
src/librustc/middle/typeck/astconv.rs
浏览文件 @
b64c7b83
...
...
@@ -207,7 +207,6 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
decl_def_id
:
ast
::
DefId
,
decl_generics
:
&
ty
::
Generics
<
'tcx
>
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
associated_ty
:
Option
<
Ty
<
'tcx
>>
,
path
:
&
ast
::
Path
)
->
Substs
<
'tcx
>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
...
...
@@ -243,7 +242,7 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
};
create_substs_for_ast_path
(
this
,
rscope
,
path
.span
,
decl_def_id
,
decl_generics
,
self_ty
,
types
,
regions
,
associated_ty
)
decl_generics
,
self_ty
,
types
,
regions
)
}
fn
create_substs_for_ast_path
<
'tcx
,
AC
,
RS
>
(
...
...
@@ -254,8 +253,7 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
decl_generics
:
&
ty
::
Generics
<
'tcx
>
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
types
:
Vec
<
Ty
<
'tcx
>>
,
regions
:
Vec
<
ty
::
Region
>
,
associated_ty
:
Option
<
Ty
<
'tcx
>>
)
regions
:
Vec
<
ty
::
Region
>
)
->
Substs
<
'tcx
>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
{
...
...
@@ -366,9 +364,9 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
substs
.types
.push
(
AssocSpace
,
this
.associated_type_binding
(
span
,
associated
_ty
,
self
_ty
,
decl_def_id
,
param
.def_id
))
param
.def_id
))
;
}
return
substs
;
...
...
@@ -417,19 +415,17 @@ pub fn instantiate_poly_trait_ref<'tcx,AC,RS>(
this
:
&
AC
,
rscope
:
&
RS
,
ast_trait_ref
:
&
ast
::
PolyTraitRef
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
associated_type
:
Option
<
Ty
<
'tcx
>>
)
self_ty
:
Option
<
Ty
<
'tcx
>>
)
->
Rc
<
ty
::
TraitRef
<
'tcx
>>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
{
instantiate_trait_ref
(
this
,
rscope
,
&
ast_trait_ref
.trait_ref
,
self_ty
,
associated_type
)
instantiate_trait_ref
(
this
,
rscope
,
&
ast_trait_ref
.trait_ref
,
self_ty
)
}
pub
fn
instantiate_trait_ref
<
'tcx
,
AC
,
RS
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ast_trait_ref
:
&
ast
::
TraitRef
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
associated_type
:
Option
<
Ty
<
'tcx
>>
)
self_ty
:
Option
<
Ty
<
'tcx
>>
)
->
Rc
<
ty
::
TraitRef
<
'tcx
>>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
...
...
@@ -444,8 +440,8 @@ pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
ast_trait_ref
.path.span
,
ast_trait_ref
.ref_id
)
{
def
::
DefTrait
(
trait_def_id
)
=>
{
let
trait_ref
=
Rc
::
new
(
ast_path_to_trait_ref
(
this
,
rscope
,
trait_def_id
,
self_ty
,
associated_type
,
&
ast_trait_ref
.path
));
let
trait_ref
=
Rc
::
new
(
ast_path_to_trait_ref
(
this
,
rscope
,
trait_def_id
,
self_ty
,
&
ast_trait_ref
.path
));
this
.tcx
()
.trait_refs
.borrow_mut
()
.insert
(
ast_trait_ref
.ref_id
,
trait_ref
.clone
());
trait_ref
...
...
@@ -463,7 +459,6 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
rscope
:
&
RS
,
trait_def_id
:
ast
::
DefId
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
associated_type
:
Option
<
Ty
<
'tcx
>>
,
path
:
&
ast
::
Path
)
->
ty
::
TraitRef
<
'tcx
>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
...
...
@@ -493,8 +488,7 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
&
trait_def
.generics
,
self_ty
,
types
,
regions
,
associated_type
);
regions
);
ty
::
TraitRef
::
new
(
trait_def_id
,
substs
)
}
...
...
@@ -517,7 +511,6 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
did
,
&
generics
,
None
,
None
,
path
);
let
ty
=
decl_ty
.subst
(
tcx
,
&
substs
);
TypeAndSubsts
{
substs
:
substs
,
ty
:
ty
}
...
...
@@ -558,7 +551,7 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
Substs
::
new
(
VecPerParamSpace
::
params_from_type
(
type_params
),
VecPerParamSpace
::
params_from_type
(
region_params
))
}
else
{
ast_path_substs_for_ty
(
this
,
rscope
,
did
,
&
generics
,
None
,
None
,
path
)
ast_path_substs_for_ty
(
this
,
rscope
,
did
,
&
generics
,
None
,
path
)
};
let
ty
=
decl_ty
.subst
(
tcx
,
&
substs
);
...
...
@@ -726,7 +719,6 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
rscope
,
trait_def_id
,
None
,
None
,
path
);
let
empty_vec
=
[];
let
bounds
=
match
*
opt_bounds
{
None
=>
empty_vec
.as_slice
(),
...
...
@@ -750,61 +742,37 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
constr
(
ast_ty_to_ty
(
this
,
rscope
,
a_seq_ty
))
}
fn
associated_ty_to_ty
<
'tcx
,
AC
,
RS
>
(
this
:
&
AC
,
rscope
:
&
RS
,
trait_path
:
&
ast
::
Path
,
for_ast_type
:
&
ast
::
Ty
,
trait_type_id
:
ast
::
DefId
,
span
:
Span
)
->
Ty
<
'tcx
>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
fn
qpath_to_ty
<
'tcx
,
AC
,
RS
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ast_ty
:
&
ast
::
Ty
,
// the TyQPath
qpath
:
&
ast
::
QPath
)
->
Ty
<
'tcx
>
where
AC
:
AstConv
<
'tcx
>
,
RS
:
RegionScope
{
debug!
(
"associated_ty_to_ty(trait_path={}, for_ast_type={}, trait_type_id={})"
,
trait_path
.repr
(
this
.tcx
()),
for_ast_type
.repr
(
this
.tcx
()),
trait_type_id
.repr
(
this
.tcx
()));
// Find the trait that this associated type belongs to.
let
trait_did
=
match
ty
::
impl_or_trait_item
(
this
.tcx
(),
trait_type_id
)
.container
()
{
ty
::
ImplContainer
(
_
)
=>
{
this
.tcx
()
.sess
.span_bug
(
span
,
"associated_ty_to_ty(): impl associated
\
types shouldn't go through this
\
function"
)
}
ty
::
TraitContainer
(
trait_id
)
=>
trait_id
,
};
debug!
(
"qpath_to_ty(ast_ty={})"
,
ast_ty
.repr
(
this
.tcx
()));
let
for_type
=
ast_ty_to_ty
(
this
,
rscope
,
for_ast_type
);
if
!
this
.associated_types_of_trait_are_valid
(
for_type
,
trait_did
)
{
this
.tcx
()
.sess
.span_err
(
span
,
"this associated type is not
\
allowed in this context"
);
return
ty
::
mk_err
()
}
let
self_type
=
ast_ty_to_ty
(
this
,
rscope
,
&*
qpath
.self_type
);
debug!
(
"qpath_to_ty: self_type={}"
,
self_type
.repr
(
this
.tcx
()));
let
trait_ref
=
ast_path_to
_trait_ref
(
this
,
let
trait_ref
=
instantiate
_trait_ref
(
this
,
rscope
,
trait_did
,
None
,
Some
(
for_type
),
trait_path
);
debug!
(
"associated_ty_to_ty(trait_ref={})"
,
trait_ref
.repr
(
this
.tcx
()));
let
trait_def
=
this
.get_trait_def
(
trait_did
);
for
type_parameter
in
trait_def
.generics.types
.iter
()
{
if
type_parameter
.def_id
==
trait_type_id
{
debug!
(
"associated_ty_to_ty(type_parameter={} substs={})"
,
type_parameter
.repr
(
this
.tcx
()),
trait_ref
.substs
.repr
(
this
.tcx
()));
return
*
trait_ref
.substs.types
.get
(
type_parameter
.space
,
type_parameter
.index
)
&*
qpath
.trait_ref
,
Some
(
self_type
));
debug!
(
"qpath_to_ty: trait_ref={}"
,
trait_ref
.repr
(
this
.tcx
()));
let
trait_def
=
this
.get_trait_def
(
trait_ref
.def_id
);
for
ty_param_def
in
trait_def
.generics.types
.get_slice
(
AssocSpace
)
.iter
()
{
if
ty_param_def
.name
==
qpath
.item_name.name
{
debug!
(
"qpath_to_ty: corresponding ty_param_def={}"
,
ty_param_def
);
return
trait_ref
.substs
.type_for_def
(
ty_param_def
);
}
}
this
.tcx
()
.sess
.span_bug
(
span
,
this
.tcx
()
.sess
.span_bug
(
ast_ty
.span
,
"this associated type didn't get added
\
as a parameter for some reason"
)
}
...
...
@@ -931,7 +899,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
rscope
,
trait_def_id
,
None
,
None
,
path
);
let
empty_bounds
:
&
[
ast
::
TyParamBound
]
=
&
[];
let
ast_bounds
=
match
*
bounds
{
...
...
@@ -996,26 +963,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
}
}
ast
::
TyQPath
(
ref
qpath
)
=>
{
match
tcx
.def_map
.borrow
()
.get
(
&
ast_ty
.id
)
{
None
=>
{
tcx
.sess
.span_bug
(
ast_ty
.span
,
"unbound qualified path"
)
}
Some
(
&
def
::
DefAssociatedTy
(
trait_type_id
))
=>
{
associated_ty_to_ty
(
this
,
rscope
,
&
qpath
.trait_name
,
&*
qpath
.for_type
,
trait_type_id
,
ast_ty
.span
)
}
Some
(
_
)
=>
{
tcx
.sess
.span_err
(
ast_ty
.span
,
"this qualified path does not name
\
an associated type"
);
ty
::
mk_err
()
}
}
qpath_to_ty
(
this
,
rscope
,
ast_ty
,
&**
qpath
)
}
ast
::
TyFixedLengthVec
(
ref
ty
,
ref
e
)
=>
{
match
const_eval
::
eval_const_expr_partial
(
tcx
,
&**
e
)
{
...
...
@@ -1411,7 +1359,7 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
let
main_trait_bound
=
match
partitioned_bounds
.trait_bounds
.remove
(
0
)
{
Some
(
trait_bound
)
=>
{
Some
(
instantiate_poly_trait_ref
(
this
,
rscope
,
trait_bound
,
None
,
None
))
Some
(
instantiate_poly_trait_ref
(
this
,
rscope
,
trait_bound
,
None
))
}
None
=>
{
this
.tcx
()
.sess
.span_err
(
...
...
src/librustc/middle/typeck/collect.rs
浏览文件 @
b64c7b83
...
...
@@ -684,7 +684,11 @@ fn find_associated_type_in_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
ty
:
Option
<
Ty
<
'tcx
>>
,
associated_type_id
:
ast
::
DefId
,
generics
:
&
ty
::
Generics
<
'tcx
>
)
->
Ty
<
'tcx
>
{
->
Ty
<
'tcx
>
{
debug!
(
"find_associated_type_in_generics(ty={}, associated_type_id={}, generics={}"
,
ty
.repr
(
tcx
),
associated_type_id
.repr
(
tcx
),
generics
.repr
(
tcx
));
let
ty
=
match
ty
{
None
=>
{
tcx
.sess
.span_bug
(
span
,
...
...
@@ -703,20 +707,22 @@ fn find_associated_type_in_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
for
type_parameter
in
generics
.types
.iter
()
{
if
type_parameter
.def_id
==
associated_type_id
&&
type_parameter
.associated_with
==
Some
(
param_id
)
{
return
ty
::
mk_param_from_def
(
tcx
,
type_parameter
)
return
ty
::
mk_param_from_def
(
tcx
,
type_parameter
)
;
}
}
tcx
.sess
.span_bug
(
span
,
"find_associated_type_in_generics(): didn't
\
find associated type anywhere in the generics
\
list"
)
tcx
.sess
.span_err
(
span
,
format!
(
"no suitable bound on `{}`"
,
ty
.user_string
(
tcx
))[]);
ty
::
mk_err
()
}
_
=>
{
tcx
.sess
.span_bug
(
span
,
"find_associated_type_in_generics(): self type
\
is not a parameter"
)
tcx
.sess
.span_err
(
span
,
"it is currently unsupported to access associated types except
\
through a type parameter; this restriction will be lifted in time"
);
ty
::
mk_err
()
}
}
}
...
...
@@ -1155,7 +1161,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
for
trait_ref
in
opt_trait_ref
.iter
()
{
astconv
::
instantiate_trait_ref
(
&
icx
,
&
ExplicitRscope
,
trait_ref
,
Some
(
selfty
)
,
None
);
Some
(
selfty
));
}
},
ast
::
ItemTrait
(
_
,
_
,
_
,
ref
trait_methods
)
=>
{
...
...
@@ -1627,7 +1633,7 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ccx
,
subst
::
AssocSpace
,
&
associated_type
.ty_param
,
generics
.types
.len
(
subst
::
Type
Space
),
generics
.types
.len
(
subst
::
Assoc
Space
),
&
ast_generics
.where_clause
,
Some
(
local_def
(
trait_id
)));
ccx
.tcx.ty_param_defs
.borrow_mut
()
.insert
(
associated_type
.ty_param.id
,
...
...
@@ -2019,7 +2025,6 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
astconv
::
instantiate_poly_trait_ref
(
this
,
&
ExplicitRscope
,
bound
,
Some
(
param_ty
.to_ty
(
this
.tcx
())),
Some
(
param_ty
.to_ty
(
this
.tcx
())))
})
.collect
();
...
...
src/librustc/util/common.rs
浏览文件 @
b64c7b83
...
...
@@ -20,6 +20,10 @@
use
syntax
::
visit
;
use
syntax
::
visit
::
Visitor
;
// An error has already been reported to the user, so no need to continue checking.
#[deriving(Clone,Show)]
pub
struct
ErrorReported
;
pub
fn
time
<
T
,
U
>
(
do_it
:
bool
,
what
:
&
str
,
u
:
U
,
f
:
|
U
|
->
T
)
->
T
{
local_data_key!
(
depth
:
uint
);
if
!
do_it
{
return
f
(
u
);
}
...
...
src/libsyntax/ast.rs
浏览文件 @
b64c7b83
...
...
@@ -706,11 +706,11 @@ pub enum Expr_ {
///
/// <Vec<T> as SomeTrait>::SomeAssociatedItem
/// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~
///
for
_type trait_name item_name
///
self
_type trait_name item_name
#[deriving(Clone,
PartialEq,
Eq,
Encodable,
Decodable,
Hash,
Show)]
pub
struct
QPath
{
pub
for
_type
:
P
<
Ty
>
,
pub
trait_
name
:
Path
,
pub
self
_type
:
P
<
Ty
>
,
pub
trait_
ref
:
P
<
TraitRef
>
,
pub
item_name
:
Ident
,
}
...
...
src/libsyntax/fold.rs
浏览文件 @
b64c7b83
...
...
@@ -142,6 +142,10 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
noop_fold_ty
(
t
,
self
)
}
fn
fold_qpath
(
&
mut
self
,
t
:
P
<
QPath
>
)
->
P
<
QPath
>
{
noop_fold_qpath
(
t
,
self
)
}
fn
fold_mod
(
&
mut
self
,
m
:
Mod
)
->
Mod
{
noop_fold_mod
(
m
,
self
)
}
...
...
@@ -435,12 +439,8 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
fld
.fold_opt_bounds
(
bounds
),
id
)
}
TyQPath
(
ref
qpath
)
=>
{
TyQPath
(
P
(
QPath
{
for_type
:
fld
.fold_ty
(
qpath
.for_type
.clone
()),
trait_name
:
fld
.fold_path
(
qpath
.trait_name
.clone
()),
item_name
:
fld
.fold_ident
(
qpath
.item_name
.clone
()),
}))
TyQPath
(
qpath
)
=>
{
TyQPath
(
fld
.fold_qpath
(
qpath
))
}
TyFixedLengthVec
(
ty
,
e
)
=>
{
TyFixedLengthVec
(
fld
.fold_ty
(
ty
),
fld
.fold_expr
(
e
))
...
...
@@ -456,6 +456,16 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
})
}
pub
fn
noop_fold_qpath
<
T
:
Folder
>
(
qpath
:
P
<
QPath
>
,
fld
:
&
mut
T
)
->
P
<
QPath
>
{
qpath
.map
(|
qpath
|
{
QPath
{
self_type
:
fld
.fold_ty
(
qpath
.self_type
),
trait_ref
:
qpath
.trait_ref
.map
(|
tr
|
fld
.fold_trait_ref
(
tr
)),
item_name
:
fld
.fold_ident
(
qpath
.item_name
),
}
})
}
pub
fn
noop_fold_foreign_mod
<
T
:
Folder
>
(
ForeignMod
{
abi
,
view_items
,
items
}:
ForeignMod
,
fld
:
&
mut
T
)
->
ForeignMod
{
ForeignMod
{
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
b64c7b83
...
...
@@ -1502,17 +1502,17 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
}
else
if
self
.eat_keyword
(
keywords
::
Proc
)
{
self
.parse_proc_type
(
Vec
::
new
())
}
else
if
self
.token
==
token
::
Lt
{
// QUALIFIED PATH
// QUALIFIED PATH
`<TYPE as TRAIT_REF>::item`
self
.bump
();
let
for
_type
=
self
.parse_ty
(
true
);
let
self
_type
=
self
.parse_ty
(
true
);
self
.expect_keyword
(
keywords
::
As
);
let
trait_
name
=
self
.parse_path
(
LifetimeAndTypesWithoutColons
);
let
trait_
ref
=
self
.parse_trait_ref
(
);
self
.expect
(
&
token
::
Gt
);
self
.expect
(
&
token
::
ModSep
);
let
item_name
=
self
.parse_ident
();
TyQPath
(
P
(
QPath
{
for_type
:
for
_type
,
trait_
name
:
trait_name
.path
,
self_type
:
self
_type
,
trait_
ref
:
P
(
trait_ref
)
,
item_name
:
item_name
,
}))
}
else
if
self
.token
==
token
::
ModSep
||
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
b64c7b83
...
...
@@ -744,10 +744,10 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
}
ast
::
TyQPath
(
ref
qpath
)
=>
{
try!
(
word
(
&
mut
self
.s
,
"<"
));
try!
(
self
.print_type
(
&*
qpath
.
for
_type
));
try!
(
self
.print_type
(
&*
qpath
.
self
_type
));
try!
(
space
(
&
mut
self
.s
));
try!
(
self
.word_space
(
"as"
));
try!
(
self
.print_
path
(
&
qpath
.trait_name
,
false
));
try!
(
self
.print_
trait_ref
(
&*
qpath
.trait_ref
));
try!
(
word
(
&
mut
self
.s
,
">"
));
try!
(
word
(
&
mut
self
.s
,
"::"
));
try!
(
self
.print_ident
(
qpath
.item_name
));
...
...
src/libsyntax/visit.rs
浏览文件 @
b64c7b83
...
...
@@ -403,8 +403,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
}
}
TyQPath
(
ref
qpath
)
=>
{
visitor
.visit_ty
(
&*
qpath
.
for
_type
);
visitor
.visit_
path
(
&
qpath
.trait_name
,
typ
.id
);
visitor
.visit_ty
(
&*
qpath
.
self
_type
);
visitor
.visit_
trait_ref
(
&*
qpath
.trait_ref
);
visitor
.visit_ident
(
typ
.span
,
qpath
.item_name
);
}
TyFixedLengthVec
(
ref
ty
,
ref
expression
)
=>
{
...
...
src/test/compile-fail/associated-types-in-ambiguous-context.rs
浏览文件 @
b64c7b83
...
...
@@ -20,12 +20,12 @@ fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
trait
Other
{
fn
uhoh
<
U
:
Get
>
(
&
self
,
foo
:
U
,
bar
:
<
Self
as
Get
>
::
Value
)
{}
//~^ ERROR
this associated type is not allowed in this context
//~^ ERROR
no suitable bound on `Self`
}
impl
<
T
:
Get
>
Other
for
T
{
fn
uhoh
<
U
:
Get
>
(
&
self
,
foo
:
U
,
bar
:
<
(
T
,
U
)
as
Get
>
::
Value
)
{}
//~^ ERROR
this associated type is not allowed in this context
//~^ ERROR
currently unsupported
}
trait
Grab
{
...
...
src/test/compile-fail/associated-types-in-wrong-context.rs
浏览文件 @
b64c7b83
...
...
@@ -16,7 +16,7 @@ trait Get {
}
fn
get
(
x
:
int
)
->
<
int
as
Get
>
::
Value
{}
//~^ ERROR
this associated type is not allowed in this context
//~^ ERROR
unsupported
struct
Struct
{
x
:
int
,
...
...
@@ -24,7 +24,7 @@ struct Struct {
impl
Struct
{
fn
uhoh
<
T
>
(
foo
:
<
T
as
Get
>
::
Value
)
{}
//~^ ERROR
this associated type is not allowed in this context
//~^ ERROR
no suitable bound on `T`
}
fn
main
()
{
...
...
src/test/run-pass/associated-types-qualified-path-with-trait-with-type-parameters.rs
0 → 100644
浏览文件 @
b64c7b83
// 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.
#![feature(associated_types)]
trait
Foo
<
T
>
{
type
Bar
;
fn
get_bar
()
->
<
Self
as
Foo
<
T
>>
::
Bar
;
}
fn
main
()
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录