Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
004df413
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,发现更多精彩内容 >>
提交
004df413
编写于
1月 30, 2015
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
syntax: don't use TraitRef in QPath.
上级
a817c692
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
143 addition
and
146 deletion
+143
-146
src/librustc/lint/context.rs
src/librustc/lint/context.rs
+5
-0
src/librustc/lint/mod.rs
src/librustc/lint/mod.rs
+1
-0
src/librustc/metadata/encoder.rs
src/librustc/metadata/encoder.rs
+2
-3
src/librustc/middle/dead.rs
src/librustc/middle/dead.rs
+5
-0
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+14
-20
src/librustc_back/svh.rs
src/librustc_back/svh.rs
+5
-0
src/librustc_privacy/lib.rs
src/librustc_privacy/lib.rs
+5
-0
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+31
-43
src/librustc_trans/save/mod.rs
src/librustc_trans/save/mod.rs
+2
-2
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+17
-11
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+6
-8
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/wf.rs
+2
-2
src/librustc_typeck/coherence/impls.rs
src/librustc_typeck/coherence/impls.rs
+2
-2
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+12
-26
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+3
-1
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+1
-1
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+4
-4
src/libsyntax/ast_util.rs
src/libsyntax/ast_util.rs
+7
-2
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+4
-4
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+4
-4
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+1
-1
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+9
-11
src/test/compile-fail/ufcs-qpath-missing-params.rs
src/test/compile-fail/ufcs-qpath-missing-params.rs
+1
-1
未找到文件。
src/librustc/lint/context.rs
浏览文件 @
004df413
...
...
@@ -717,6 +717,11 @@ fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
visit
::
walk_path
(
self
,
p
);
}
fn
visit_qpath
(
&
mut
self
,
p
:
&
ast
::
QPath
,
id
:
ast
::
NodeId
)
{
run_lints!
(
self
,
check_qpath
,
p
,
id
);
visit
::
walk_qpath
(
self
,
p
);
}
fn
visit_attribute
(
&
mut
self
,
attr
:
&
ast
::
Attribute
)
{
run_lints!
(
self
,
check_attribute
,
attr
);
}
...
...
src/librustc/lint/mod.rs
浏览文件 @
004df413
...
...
@@ -157,6 +157,7 @@ fn check_lifetime_def(&mut self, _: &Context, _: &ast::LifetimeDef) { }
fn
check_explicit_self
(
&
mut
self
,
_
:
&
Context
,
_
:
&
ast
::
ExplicitSelf
)
{
}
fn
check_mac
(
&
mut
self
,
_
:
&
Context
,
_
:
&
ast
::
Mac
)
{
}
fn
check_path
(
&
mut
self
,
_
:
&
Context
,
_
:
&
ast
::
Path
,
_
:
ast
::
NodeId
)
{
}
fn
check_qpath
(
&
mut
self
,
_
:
&
Context
,
_
:
&
ast
::
QPath
,
_
:
ast
::
NodeId
)
{
}
fn
check_attribute
(
&
mut
self
,
_
:
&
Context
,
_
:
&
ast
::
Attribute
)
{
}
/// Called when entering a syntax node that can have lint attributes such
...
...
src/librustc/metadata/encoder.rs
浏览文件 @
004df413
...
...
@@ -1241,9 +1241,8 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
}
rbml_w
.end_tag
();
}
if
let
Some
(
ref
ast_trait_ref
)
=
*
opt_trait
{
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
tcx
,
ast_trait_ref
.ref_id
);
if
opt_trait
.is_some
()
{
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
tcx
,
item
.id
);
encode_trait_ref
(
rbml_w
,
ecx
,
&*
trait_ref
,
tag_item_trait_ref
);
}
encode_path
(
rbml_w
,
path
.clone
());
...
...
src/librustc/middle/dead.rs
浏览文件 @
004df413
...
...
@@ -306,6 +306,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
visit
::
walk_path
(
self
,
path
);
}
fn
visit_qpath
(
&
mut
self
,
qpath
:
&
ast
::
QPath
,
id
:
ast
::
NodeId
)
{
self
.lookup_and_handle_definition
(
&
id
);
visit
::
walk_qpath
(
self
,
qpath
);
}
fn
visit_item
(
&
mut
self
,
_
:
&
ast
::
Item
)
{
// Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary.
...
...
src/librustc/middle/ty.rs
浏览文件 @
004df413
...
...
@@ -709,7 +709,7 @@ pub struct ctxt<'tcx> {
pub
impl_trait_cache
:
RefCell
<
DefIdMap
<
Option
<
Rc
<
ty
::
TraitRef
<
'tcx
>>>>>
,
pub
trait_refs
:
RefCell
<
NodeMap
<
Rc
<
TraitRef
<
'tcx
>>>>
,
pub
impl_
trait_refs
:
RefCell
<
NodeMap
<
Rc
<
TraitRef
<
'tcx
>>>>
,
pub
trait_defs
:
RefCell
<
DefIdMap
<
Rc
<
TraitDef
<
'tcx
>>>>
,
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
...
...
@@ -2449,7 +2449,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
region_maps
:
region_maps
,
node_types
:
RefCell
::
new
(
FnvHashMap
()),
item_substs
:
RefCell
::
new
(
NodeMap
()),
trait_refs
:
RefCell
::
new
(
NodeMap
()),
impl_
trait_refs
:
RefCell
::
new
(
NodeMap
()),
trait_defs
:
RefCell
::
new
(
DefIdMap
()),
predicates
:
RefCell
::
new
(
DefIdMap
()),
object_cast_map
:
RefCell
::
new
(
NodeMap
()),
...
...
@@ -4174,12 +4174,12 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
}
}
pub
fn
node
_id_to_trait_ref
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
id
:
ast
::
NodeId
)
pub
fn
impl
_id_to_trait_ref
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
id
:
ast
::
NodeId
)
->
Rc
<
ty
::
TraitRef
<
'tcx
>>
{
match
cx
.trait_refs
.borrow
()
.get
(
&
id
)
{
match
cx
.
impl_
trait_refs
.borrow
()
.get
(
&
id
)
{
Some
(
ty
)
=>
ty
.clone
(),
None
=>
cx
.sess
.bug
(
&
format!
(
"
node_id_to_trait_ref: no trait ref for node
`{}`"
,
&
format!
(
"
impl_id_to_trait_ref: no trait ref for impl
`{}`"
,
cx
.map
.node_to_string
(
id
)))
}
}
...
...
@@ -5116,25 +5116,19 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
memoized
(
&
cx
.impl_trait_cache
,
id
,
|
id
:
ast
::
DefId
|
{
if
id
.krate
==
ast
::
LOCAL_CRATE
{
debug!
(
"(impl_trait_ref) searching for trait impl {:?}"
,
id
);
match
cx
.map
.find
(
id
.node
)
{
Some
(
ast_map
::
NodeItem
(
item
))
=>
{
match
item
.node
{
ast
::
ItemImpl
(
_
,
_
,
_
,
ref
opt_trait
,
_
,
_
)
=>
{
match
opt_trait
{
&
Some
(
ref
t
)
=>
{
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
cx
,
t
.ref_id
);
Some
(
trait_ref
)
}
&
None
=>
None
}
}
if
let
Some
(
ast_map
::
NodeItem
(
item
))
=
cx
.map
.find
(
id
.node
)
{
if
let
ast
::
ItemImpl
(
_
,
_
,
_
,
ref
opt_trait
,
_
,
_
)
=
item
.node
{
opt_trait
.as_ref
()
.map
(|
_
|
{
ty
::
impl_id_to_trait_ref
(
cx
,
id
.node
)
})
}
else
{
None
ast
::
ItemDefaultImpl
(
_
,
ref
ast_trait_ref
)
=>
{
Some
(
ty
::
node_id_to_trait_ref
(
cx
,
ast_trait_ref
.ref_id
))
}
_
=>
None
}
}
_
=>
None
}
else
{
None
}
}
else
{
csearch
::
get_impl_trait
(
cx
,
id
)
...
...
src/librustc_back/svh.rs
浏览文件 @
004df413
...
...
@@ -194,6 +194,7 @@ enum SawAbiComponent<'a> {
SawVariant
,
SawExplicitSelf
,
SawPath
,
SawQPath
,
SawOptLifetimeRef
,
SawBlock
,
SawPat
,
...
...
@@ -485,6 +486,10 @@ fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
SawPath
.hash
(
self
.st
);
visit
::
walk_path
(
self
,
path
)
}
fn
visit_qpath
(
&
mut
self
,
qpath
:
&
QPath
,
_
:
ast
::
NodeId
)
{
SawQPath
.hash
(
self
.st
);
visit
::
walk_qpath
(
self
,
qpath
)
}
fn
visit_block
(
&
mut
self
,
b
:
&
Block
)
{
SawBlock
.hash
(
self
.st
);
visit
::
walk_block
(
self
,
b
)
}
...
...
src/librustc_privacy/lib.rs
浏览文件 @
004df413
...
...
@@ -1021,6 +1021,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
self
.check_path
(
path
.span
,
id
,
path
.segments
.last
()
.unwrap
()
.identifier
);
visit
::
walk_path
(
self
,
path
);
}
fn
visit_qpath
(
&
mut
self
,
qpath
:
&
ast
::
QPath
,
id
:
ast
::
NodeId
)
{
self
.check_path
(
qpath
.trait_path.span
,
id
,
qpath
.item_path.identifier
);
visit
::
walk_qpath
(
self
,
qpath
);
}
}
////////////////////////////////////////////////////////////////////////////////
...
...
src/librustc_resolve/lib.rs
浏览文件 @
004df413
...
...
@@ -2875,8 +2875,7 @@ fn resolve_item(&mut self, item: &Item) {
this
.resolve_type_parameters
(
&
generics
.ty_params
);
this
.resolve_where_clause
(
&
generics
.where_clause
);
this
.resolve_type_parameter_bounds
(
item
.id
,
bounds
,
TraitDerivation
);
this
.resolve_type_parameter_bounds
(
bounds
,
TraitDerivation
);
for
trait_item
in
&
(
*
trait_items
)
{
// Create a new rib for the trait_item-specific type
...
...
@@ -3141,8 +3140,7 @@ fn resolve_type_parameter(&mut self,
type_parameter
:
&
TyParam
)
{
self
.check_if_primitive_type_name
(
type_parameter
.ident.name
,
type_parameter
.span
);
for
bound
in
&*
type_parameter
.bounds
{
self
.resolve_type_parameter_bound
(
type_parameter
.id
,
bound
,
TraitBoundingTypeParameter
);
self
.resolve_type_parameter_bound
(
bound
,
TraitBoundingTypeParameter
);
}
match
type_parameter
.default
{
Some
(
ref
ty
)
=>
self
.resolve_type
(
&**
ty
),
...
...
@@ -3151,41 +3149,33 @@ fn resolve_type_parameter(&mut self,
}
fn
resolve_type_parameter_bounds
(
&
mut
self
,
id
:
NodeId
,
type_parameter_bounds
:
&
OwnedSlice
<
TyParamBound
>
,
reference_type
:
TraitReferenceType
)
{
for
type_parameter_bound
in
&**
type_parameter_bounds
{
self
.resolve_type_parameter_bound
(
id
,
type_parameter_bound
,
reference_type
);
self
.resolve_type_parameter_bound
(
type_parameter_bound
,
reference_type
);
}
}
fn
resolve_type_parameter_bound
(
&
mut
self
,
id
:
NodeId
,
type_parameter_bound
:
&
TyParamBound
,
reference_type
:
TraitReferenceType
)
{
match
*
type_parameter_bound
{
TraitTyParamBound
(
ref
tref
,
_
)
=>
{
self
.resolve_poly_trait_reference
(
id
,
tref
,
reference_type
)
self
.resolve_trait_reference
(
tref
.trait_ref.ref_id
,
&
tref
.trait_ref.path
,
reference_type
)
}
RegionTyParamBound
(
..
)
=>
{}
}
}
fn
resolve_poly_trait_reference
(
&
mut
self
,
id
:
NodeId
,
poly_trait_reference
:
&
PolyTraitRef
,
reference_type
:
TraitReferenceType
)
{
self
.resolve_trait_reference
(
id
,
&
poly_trait_reference
.trait_ref
,
reference_type
)
}
fn
resolve_trait_reference
(
&
mut
self
,
id
:
NodeId
,
trait_
reference
:
&
TraitRef
,
trait_
path
:
&
Path
,
reference_type
:
TraitReferenceType
)
{
match
self
.resolve_path
(
id
,
&
trait_reference
.
path
,
TypeNS
,
true
)
{
match
self
.resolve_path
(
id
,
trait_
path
,
TypeNS
,
true
)
{
None
=>
{
let
path_str
=
self
.path_names_to_string
(
&
trait_reference
.
path
);
let
path_str
=
self
.path_names_to_string
(
trait_
path
);
let
usage_str
=
match
reference_type
{
TraitBoundingTypeParameter
=>
"bound type parameter with"
,
TraitImplementation
=>
"implement"
,
...
...
@@ -3195,26 +3185,23 @@ fn resolve_trait_reference(&mut self,
};
let
msg
=
format!
(
"attempt to {} a nonexistent trait `{}`"
,
usage_str
,
path_str
);
self
.resolve_error
(
trait_
reference
.
path.span
,
&
msg
[
..
]);
self
.resolve_error
(
trait_path
.span
,
&
msg
[
..
]);
}
Some
(
def
)
=>
{
match
def
{
(
DefTrait
(
_
),
_
)
=>
{
debug!
(
"(resolving trait) found trait def: {:?}"
,
def
);
self
.record_def
(
trait_reference
.ref_
id
,
def
);
self
.record_def
(
id
,
def
);
}
(
def
,
_
)
=>
{
self
.resolve_error
(
trait_reference
.path.span
,
&
format!
(
"`{}` is not a trait"
,
self
.path_names_to_string
(
&
trait_reference
.path
)));
self
.resolve_error
(
trait_path
.span
,
&
format!
(
"`{}` is not a trait"
,
self
.path_names_to_string
(
trait_path
)));
// If it's a typedef, give a note
if
let
DefTy
(
..
)
=
def
{
self
.session
.span_note
(
trait_reference
.path.span
,
&
format!
(
"`type` aliases cannot be used for traits"
)
);
self
.session
.span_note
(
trait_path
.span
,
&
format!
(
"`type` aliases cannot be used for traits"
));
}
}
}
...
...
@@ -3229,8 +3216,7 @@ fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
self
.resolve_type
(
&*
bound_pred
.bounded_ty
);
for
bound
in
&*
bound_pred
.bounds
{
self
.resolve_type_parameter_bound
(
bound_pred
.bounded_ty.id
,
bound
,
TraitBoundingTypeParameter
);
self
.resolve_type_parameter_bound
(
bound
,
TraitBoundingTypeParameter
);
}
}
&
ast
::
WherePredicate
::
RegionPredicate
(
_
)
=>
{}
...
...
@@ -3303,14 +3289,16 @@ fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
result
}
fn
with_optional_trait_ref
<
T
,
F
>
(
&
mut
self
,
id
:
NodeId
,
fn
with_optional_trait_ref
<
T
,
F
>
(
&
mut
self
,
opt_trait_ref
:
&
Option
<
TraitRef
>
,
f
:
F
)
->
T
where
F
:
FnOnce
(
&
mut
Resolver
)
->
T
,
{
let
new_val
=
match
*
opt_trait_ref
{
Some
(
ref
trait_ref
)
=>
{
self
.resolve_trait_reference
(
id
,
trait_ref
,
TraitImplementation
);
self
.resolve_trait_reference
(
trait_ref
.ref_id
,
&
trait_ref
.path
,
TraitImplementation
);
match
self
.def_map
.borrow
()
.get
(
&
trait_ref
.ref_id
)
{
Some
(
def
)
=>
{
...
...
@@ -3345,7 +3333,7 @@ fn resolve_implementation(&mut self,
this
.resolve_where_clause
(
&
generics
.where_clause
);
// Resolve the trait reference, if necessary.
this
.with_optional_trait_ref
(
id
,
opt_trait_reference
,
|
this
|
{
this
.with_optional_trait_ref
(
opt_trait_reference
,
|
this
|
{
// Resolve the self type.
this
.resolve_type
(
self_type
);
...
...
@@ -3630,13 +3618,12 @@ fn resolve_type(&mut self, ty: &Ty) {
TyObjectSum
(
ref
ty
,
ref
bound_vec
)
=>
{
self
.resolve_type
(
&**
ty
);
self
.resolve_type_parameter_bounds
(
ty
.id
,
bound_vec
,
TraitBoundingTypeParameter
);
self
.resolve_type_parameter_bounds
(
bound_vec
,
TraitBoundingTypeParameter
);
}
TyQPath
(
ref
qpath
)
=>
{
self
.resolve_type
(
&*
qpath
.self_type
);
self
.resolve_trait_reference
(
ty
.id
,
&
*
qpath
.trait_ref
,
TraitQPath
);
self
.resolve_trait_reference
(
ty
.id
,
&
qpath
.trait_path
,
TraitQPath
);
for
ty
in
qpath
.item_path.parameters
.types
()
{
self
.resolve_type
(
&**
ty
);
}
...
...
@@ -3646,10 +3633,7 @@ fn resolve_type(&mut self, ty: &Ty) {
}
TyPolyTraitRef
(
ref
bounds
)
=>
{
self
.resolve_type_parameter_bounds
(
ty
.id
,
bounds
,
TraitObject
);
self
.resolve_type_parameter_bounds
(
bounds
,
TraitObject
);
visit
::
walk_ty
(
self
,
ty
);
}
_
=>
{
...
...
@@ -4439,8 +4423,12 @@ fn resolve_expr(&mut self, expr: &Expr) {
ExprPath
(
ref
path
)
=>
path
,
ExprQPath
(
ref
qpath
)
=>
{
self
.resolve_type
(
&*
qpath
.self_type
);
self
.resolve_trait_reference
(
expr
.id
,
&*
qpath
.trait_ref
,
TraitQPath
);
path_from_qpath
=
qpath
.trait_ref.path
.clone
();
// Just make sure the trait is valid, don't record a def.
self
.resolve_trait_reference
(
expr
.id
,
&
qpath
.trait_path
,
TraitQPath
);
self
.def_map
.borrow_mut
()
.remove
(
&
expr
.id
);
path_from_qpath
=
qpath
.trait_path
.clone
();
path_from_qpath
.segments
.push
(
qpath
.item_path
.clone
());
&
path_from_qpath
}
...
...
src/librustc_trans/save/mod.rs
浏览文件 @
004df413
...
...
@@ -1340,10 +1340,10 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
visit
::
walk_path
(
self
,
path
);
}
ast
::
ExprQPath
(
ref
qpath
)
=>
{
let
mut
path
=
qpath
.trait_
ref.
path
.clone
();
let
mut
path
=
qpath
.trait_path
.clone
();
path
.segments
.push
(
qpath
.item_path
.clone
());
self
.process_path
(
ex
.id
,
ex
.span
,
&
path
,
None
);
visit
::
walk_qpath
(
self
,
ex
.span
,
&**
qpath
);
visit
::
walk_qpath
(
self
,
&**
qpath
);
}
ast
::
ExprStruct
(
ref
path
,
ref
fields
,
ref
base
)
=>
self
.process_struct_lit
(
ex
,
path
,
fields
,
base
),
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
004df413
...
...
@@ -574,9 +574,10 @@ pub fn instantiate_poly_trait_ref<'tcx>(
// lifetimes. Oh well, not there yet.
let
shifted_rscope
=
ShiftedRscope
::
new
(
rscope
);
let
trait_ref
=
instantiate_trait_ref
(
this
,
&
shifted_rscope
,
&
ast_trait_ref
.trait_ref
,
self_ty
,
Some
(
&
mut
projections
));
let
trait_ref
=
instantiate_trait_ref
(
this
,
&
shifted_rscope
,
&
ast_trait_ref
.trait_ref.path
,
ast_trait_ref
.trait_ref.ref_id
,
None
,
self_ty
,
Some
(
&
mut
projections
));
for
projection
in
projections
{
poly_projections
.push
(
ty
::
Binder
(
projection
));
...
...
@@ -594,26 +595,29 @@ pub fn instantiate_poly_trait_ref<'tcx>(
pub
fn
instantiate_trait_ref
<
'tcx
>
(
this
:
&
AstConv
<
'tcx
>
,
rscope
:
&
RegionScope
,
ast_trait_ref
:
&
ast
::
TraitRef
,
path
:
&
ast
::
Path
,
path_id
:
ast
::
NodeId
,
impl_id
:
Option
<
ast
::
NodeId
>
,
self_ty
:
Option
<
Ty
<
'tcx
>>
,
projections
:
Option
<&
mut
Vec
<
ty
::
ProjectionPredicate
<
'tcx
>>>
)
->
Rc
<
ty
::
TraitRef
<
'tcx
>>
{
match
::
lookup_def_tcx
(
this
.tcx
(),
ast_trait_ref
.path.span
,
ast_trait_ref
.ref
_id
)
{
match
::
lookup_def_tcx
(
this
.tcx
(),
path
.span
,
path
_id
)
{
def
::
DefTrait
(
trait_def_id
)
=>
{
let
trait_ref
=
ast_path_to_trait_ref
(
this
,
rscope
,
trait_def_id
,
self_ty
,
&
ast_trait_ref
.
path
,
path
,
projections
);
this
.tcx
()
.trait_refs
.borrow_mut
()
.insert
(
ast_trait_ref
.ref_id
,
trait_ref
.clone
());
if
let
Some
(
id
)
=
impl_id
{
this
.tcx
()
.impl_trait_refs
.borrow_mut
()
.insert
(
id
,
trait_ref
.clone
());
}
trait_ref
}
_
=>
{
span_fatal!
(
this
.tcx
()
.sess
,
ast_trait_ref
.path.span
,
E0245
,
"`{}` is not a trait"
,
ast_trait_ref
.path
.user_string
(
this
.tcx
()));
span_fatal!
(
this
.tcx
()
.sess
,
path
.span
,
E0245
,
"`{}` is not a trait"
,
path
.user_string
(
this
.tcx
()));
}
}
}
...
...
@@ -1056,7 +1060,9 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
let
trait_ref
=
instantiate_trait_ref
(
this
,
rscope
,
&*
qpath
.trait_ref
,
&
qpath
.trait_path
,
ast_ty
.id
,
None
,
Some
(
self_type
),
None
);
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
004df413
...
...
@@ -3611,13 +3611,10 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
constrain_path_type_parameters
(
fcx
,
expr
);
}
ast
::
ExprQPath
(
ref
qpath
)
=>
{
// Require explicit type params for the trait.
let
self_ty
=
fcx
.to_ty
(
&*
qpath
.self_type
);
astconv
::
instantiate_trait_ref
(
fcx
,
fcx
,
&*
qpath
.trait_ref
,
Some
(
self_ty
),
None
);
let
defn
=
lookup_def
(
fcx
,
expr
.span
,
id
);
let
(
scheme
,
predicates
)
=
type_scheme_and_predicates_for_def
(
fcx
,
expr
.span
,
defn
);
let
mut
path
=
qpath
.trait_
ref.
path
.clone
();
let
mut
path
=
qpath
.trait_path
.clone
();
path
.segments
.push
(
qpath
.item_path
.clone
());
instantiate_path
(
fcx
,
&
path
,
scheme
,
&
predicates
,
Some
(
self_ty
),
defn
,
expr
.span
,
expr
.id
);
...
...
@@ -4829,7 +4826,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// to add defaults. If the user provided *too many* types, that's
// a problem.
for
&
space
in
&
ParamSpace
::
all
()
{
adjust_type_parameters
(
fcx
,
span
,
space
,
type_defs
,
&
mut
substs
);
adjust_type_parameters
(
fcx
,
span
,
space
,
type_defs
,
opt_self_ty
.is_some
(),
&
mut
substs
);
assert_eq!
(
substs
.types
.len
(
space
),
type_defs
.len
(
space
));
adjust_region_parameters
(
fcx
,
span
,
space
,
region_defs
,
&
mut
substs
);
...
...
@@ -5007,6 +5005,7 @@ fn adjust_type_parameters<'a, 'tcx>(
span
:
Span
,
space
:
ParamSpace
,
defs
:
&
VecPerParamSpace
<
ty
::
TypeParameterDef
<
'tcx
>>
,
require_type_space
:
bool
,
substs
:
&
mut
Substs
<
'tcx
>
)
{
let
provided_len
=
substs
.types
.len
(
space
);
...
...
@@ -5029,9 +5028,8 @@ fn adjust_type_parameters<'a, 'tcx>(
// Nothing specified at all: supply inference variables for
// everything.
if
provided_len
==
0
{
substs
.types
.replace
(
space
,
fcx
.infcx
()
.next_ty_vars
(
desired
.len
()));
if
provided_len
==
0
&&
!
(
require_type_space
&&
space
==
subst
::
TypeSpace
)
{
substs
.types
.replace
(
space
,
fcx
.infcx
()
.next_ty_vars
(
desired
.len
()));
return
;
}
...
...
src/librustc_typeck/check/wf.rs
浏览文件 @
004df413
...
...
@@ -81,8 +81,8 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
ast
::
ItemImpl
(
_
,
ast
::
ImplPolarity
::
Positive
,
_
,
_
,
_
,
_
)
=>
{
self
.check_impl
(
item
);
}
ast
::
ItemImpl
(
_
,
ast
::
ImplPolarity
::
Negative
,
_
,
Some
(
ref
tref
),
_
,
_
)
=>
{
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
ccx
.tcx
,
tref
.ref_
id
);
ast
::
ItemImpl
(
_
,
ast
::
ImplPolarity
::
Negative
,
_
,
Some
(
_
),
_
,
_
)
=>
{
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
ccx
.tcx
,
item
.
id
);
ty
::
populate_implementations_for_trait_if_necessary
(
ccx
.tcx
,
trait_ref
.def_id
);
match
ccx
.tcx.lang_items
.to_builtin_kind
(
trait_ref
.def_id
)
{
Some
(
ty
::
BoundSend
)
|
Some
(
ty
::
BoundSync
)
=>
{}
...
...
src/librustc_typeck/coherence/impls.rs
浏览文件 @
004df413
...
...
@@ -28,8 +28,8 @@ struct ImplsChecker<'cx, 'tcx:'cx> {
impl
<
'cx
,
'tcx
,
'v
>
visit
::
Visitor
<
'v
>
for
ImplsChecker
<
'cx
,
'tcx
>
{
fn
visit_item
(
&
mut
self
,
item
:
&
'v
ast
::
Item
)
{
match
item
.node
{
ast
::
ItemImpl
(
_
,
_
,
_
,
Some
(
ref
opt_trait
),
_
,
_
)
=>
{
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
self
.tcx
,
opt_trait
.ref_
id
);
ast
::
ItemImpl
(
_
,
_
,
_
,
Some
(
_
),
_
,
_
)
=>
{
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
self
.tcx
,
item
.
id
);
if
let
Some
(
_
)
=
self
.tcx.lang_items
.to_builtin_kind
(
trait_ref
.def_id
)
{
match
trait_ref
.self_ty
()
.sty
{
ty
::
ty_struct
(
..
)
|
ty
::
ty_enum
(
..
)
=>
{}
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
004df413
...
...
@@ -106,19 +106,9 @@ fn visit_item(&mut self, item: &Item) {
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
match
item
.node
{
ItemImpl
(
_
,
_
,
_
,
ref
opt_trait
,
_
,
_
)
=>
{
match
opt_trait
.clone
()
{
Some
(
opt_trait
)
=>
{
self
.cc
.check_implementation
(
item
,
&
[
opt_trait
]);
}
None
=>
self
.cc
.check_implementation
(
item
,
&
[])
}
}
_
=>
{
// Nothing to do.
}
};
if
let
ItemImpl
(
_
,
_
,
_
,
ref
opt_trait
,
_
,
_
)
=
item
.node
{
self
.cc
.check_implementation
(
item
,
opt_trait
.as_ref
())
}
visit
::
walk_item
(
self
,
item
);
}
...
...
@@ -155,9 +145,7 @@ fn check(&self, krate: &Crate) {
self
.check_implementations_of_copy
();
}
fn
check_implementation
(
&
self
,
item
:
&
Item
,
associated_traits
:
&
[
TraitRef
])
{
fn
check_implementation
(
&
self
,
item
:
&
Item
,
opt_trait
:
Option
<&
TraitRef
>
)
{
let
tcx
=
self
.crate_context.tcx
;
let
impl_did
=
local_def
(
item
.id
);
let
self_type
=
ty
::
lookup_item_type
(
tcx
,
impl_did
);
...
...
@@ -167,9 +155,8 @@ fn check_implementation(&self,
let
impl_items
=
self
.create_impl_from_item
(
item
);
for
associated_trait
in
associated_traits
{
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
self
.crate_context.tcx
,
associated_trait
.ref_id
);
if
opt_trait
.is_some
()
{
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
self
.crate_context.tcx
,
item
.id
);
debug!
(
"(checking implementation) adding impl for trait '{}', item '{}'"
,
trait_ref
.repr
(
self
.crate_context.tcx
),
token
::
get_ident
(
item
.ident
));
...
...
@@ -191,7 +178,7 @@ fn check_implementation(&self,
}
Some
(
base_type_def_id
)
=>
{
// FIXME: Gather up default methods?
if
associated_traits
.len
()
==
0
{
if
opt_trait
.is_none
()
{
self
.add_inherent_impl
(
base_type_def_id
,
impl_did
);
}
}
...
...
@@ -289,7 +276,7 @@ fn get_self_type_for_implementation(&self, impl_did: DefId)
// Converts an implementation in the AST to a vector of items.
fn
create_impl_from_item
(
&
self
,
item
:
&
Item
)
->
Vec
<
ImplOrTraitItemId
>
{
match
item
.node
{
ItemImpl
(
_
,
_
,
_
,
ref
trait_refs
,
_
,
ref
ast_items
)
=>
{
ItemImpl
(
_
,
_
,
_
,
ref
opt_trait
,
_
,
ref
ast_items
)
=>
{
let
mut
items
:
Vec
<
ImplOrTraitItemId
>
=
ast_items
.iter
()
.map
(|
ast_item
|
{
...
...
@@ -304,13 +291,12 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
}
})
.collect
();
if
let
Some
(
ref
trait_ref
)
=
*
trait_refs
{
let
ty_trait_ref
=
ty
::
node_id_to_trait_ref
(
self
.crate_context.tcx
,
trait_ref
.ref_id
);
if
opt_trait
.is_some
()
{
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
self
.crate_context.tcx
,
item
.id
);
self
.instantiate_default_methods
(
local_def
(
item
.id
),
&*
t
y_t
rait_ref
,
&*
trait_ref
,
&
mut
items
);
}
...
...
src/librustc_typeck/collect.rs
浏览文件 @
004df413
...
...
@@ -740,7 +740,9 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
if
let
Some
(
ref
trait_ref
)
=
*
opt_trait_ref
{
astconv
::
instantiate_trait_ref
(
ccx
,
&
ExplicitRscope
,
trait_ref
,
&
trait_ref
.path
,
trait_ref
.ref_id
,
Some
(
it
.id
),
Some
(
selfty
),
None
);
}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
004df413
...
...
@@ -1629,7 +1629,7 @@ fn clean(&self, cx: &DocContext) -> Type {
Type
::
QPath
{
name
:
self
.item_path.identifier
.clean
(
cx
),
self_type
:
box
self
.self_type
.clean
(
cx
),
trait_
:
box
self
.trait_ref
.clean
(
cx
)
trait_
:
box
resolve_type
(
cx
,
self
.trait_path
.clean
(
cx
),
0
)
}
}
}
...
...
src/libsyntax/ast.rs
浏览文件 @
004df413
...
...
@@ -782,11 +782,11 @@ pub enum Expr_ {
///
/// <Vec<T> as SomeTrait>::SomeAssociatedItem
/// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~
/// self_type trait_
name
item_path
/// self_type trait_
path
item_path
#[derive(Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Debug)]
pub
struct
QPath
{
pub
self_type
:
P
<
Ty
>
,
pub
trait_
ref
:
P
<
TraitRef
>
,
pub
trait_
path
:
Path
,
pub
item_path
:
PathSegment
,
}
...
...
@@ -1258,12 +1258,12 @@ pub enum Ty_ {
///
/// Type parameters are stored in the Path itself
TyPath
(
Path
),
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
TyQPath
(
P
<
QPath
>
),
/// Something like `A+B`. Note that `B` must always be a path.
TyObjectSum
(
P
<
Ty
>
,
TyParamBounds
),
/// A type like `for<'a> Foo<&'a Bar>`
TyPolyTraitRef
(
TyParamBounds
),
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
TyQPath
(
P
<
QPath
>
),
/// No-op; kept solely so that we can pretty-print faithfully
TyParen
(
P
<
Ty
>
),
/// Unused for now
...
...
src/libsyntax/ast_util.rs
浏览文件 @
004df413
...
...
@@ -561,13 +561,18 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
visit
::
walk_trait_item
(
self
,
tm
);
}
fn
visit_lifetime_ref
(
&
mut
self
,
lifetime
:
&
'v
Lifetime
)
{
fn
visit_lifetime_ref
(
&
mut
self
,
lifetime
:
&
Lifetime
)
{
self
.operation
.visit_id
(
lifetime
.id
);
}
fn
visit_lifetime_def
(
&
mut
self
,
def
:
&
'v
LifetimeDef
)
{
fn
visit_lifetime_def
(
&
mut
self
,
def
:
&
LifetimeDef
)
{
self
.visit_lifetime_ref
(
&
def
.lifetime
);
}
fn
visit_trait_ref
(
&
mut
self
,
trait_ref
:
&
TraitRef
)
{
self
.operation
.visit_id
(
trait_ref
.ref_id
);
visit
::
walk_trait_ref
(
self
,
trait_ref
);
}
}
pub
fn
visit_ids_for_inlined_item
<
O
:
IdVisitingOperation
>
(
item
:
&
InlinedItem
,
...
...
src/libsyntax/fold.rs
浏览文件 @
004df413
...
...
@@ -429,13 +429,13 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyTup
(
tys
)
=>
TyTup
(
tys
.move_map
(|
ty
|
fld
.fold_ty
(
ty
))),
TyParen
(
ty
)
=>
TyParen
(
fld
.fold_ty
(
ty
)),
TyPath
(
path
)
=>
TyPath
(
fld
.fold_path
(
path
)),
TyQPath
(
qpath
)
=>
{
TyQPath
(
fld
.fold_qpath
(
qpath
))
}
TyObjectSum
(
ty
,
bounds
)
=>
{
TyObjectSum
(
fld
.fold_ty
(
ty
),
fld
.fold_bounds
(
bounds
))
}
TyQPath
(
qpath
)
=>
{
TyQPath
(
fld
.fold_qpath
(
qpath
))
}
TyFixedLengthVec
(
ty
,
e
)
=>
{
TyFixedLengthVec
(
fld
.fold_ty
(
ty
),
fld
.fold_expr
(
e
))
}
...
...
@@ -454,7 +454,7 @@ 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
)
),
trait_
path
:
fld
.fold_path
(
qpath
.trait_path
),
item_path
:
PathSegment
{
identifier
:
fld
.fold_ident
(
qpath
.item_path.identifier
),
parameters
:
fld
.fold_path_parameters
(
qpath
.item_path.parameters
),
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
004df413
...
...
@@ -1525,13 +1525,13 @@ pub fn parse_ty(&mut self) -> P<Ty> {
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
let
self_type
=
self
.parse_ty_sum
();
self
.expect_keyword
(
keywords
::
As
);
let
trait_
ref
=
self
.parse_trait_ref
(
);
let
trait_
path
=
self
.parse_path
(
LifetimeAndTypesWithoutColons
);
self
.expect
(
&
token
::
Gt
);
self
.expect
(
&
token
::
ModSep
);
let
item_name
=
self
.parse_ident
();
TyQPath
(
P
(
QPath
{
self_type
:
self_type
,
trait_
ref
:
P
(
trait_ref
)
,
trait_
path
:
trait_path
,
item_path
:
ast
::
PathSegment
{
identifier
:
item_name
,
parameters
:
ast
::
PathParameters
::
none
()
...
...
@@ -2220,7 +2220,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
let
self_type
=
self
.parse_ty_sum
();
self
.expect_keyword
(
keywords
::
As
);
let
trait_
ref
=
self
.parse_trait_ref
(
);
let
trait_
path
=
self
.parse_path
(
LifetimeAndTypesWithoutColons
);
self
.expect
(
&
token
::
Gt
);
self
.expect
(
&
token
::
ModSep
);
let
item_name
=
self
.parse_ident
();
...
...
@@ -2240,7 +2240,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
let
hi
=
self
.span.hi
;
return
self
.mk_expr
(
lo
,
hi
,
ExprQPath
(
P
(
QPath
{
self_type
:
self_type
,
trait_
ref
:
P
(
trait_ref
)
,
trait_
path
:
trait_path
,
item_path
:
ast
::
PathSegment
{
identifier
:
item_name
,
parameters
:
parameters
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
004df413
...
...
@@ -2047,7 +2047,7 @@ fn print_qpath(&mut self,
try!
(
self
.print_type
(
&*
qpath
.self_type
));
try!
(
space
(
&
mut
self
.s
));
try!
(
self
.word_space
(
"as"
));
try!
(
self
.print_
trait_ref
(
&*
qpath
.trait_ref
));
try!
(
self
.print_
path
(
&
qpath
.trait_path
,
false
));
try!
(
word
(
&
mut
self
.s
,
">"
));
try!
(
word
(
&
mut
self
.s
,
"::"
));
try!
(
self
.print_ident
(
qpath
.item_path.identifier
));
...
...
src/libsyntax/visit.rs
浏览文件 @
004df413
...
...
@@ -125,8 +125,8 @@ fn visit_mac(&mut self, _mac: &'v Mac) {
fn
visit_path
(
&
mut
self
,
path
:
&
'v
Path
,
_
id
:
ast
::
NodeId
)
{
walk_path
(
self
,
path
)
}
fn
visit_qpath
(
&
mut
self
,
qpath
_span
:
Span
,
qpath
:
&
'v
QPath
)
{
walk_qpath
(
self
,
qpath
_span
,
qpath
)
fn
visit_qpath
(
&
mut
self
,
qpath
:
&
'v
QPath
,
_
id
:
ast
::
NodeId
)
{
walk_qpath
(
self
,
qpath
)
}
fn
visit_path_segment
(
&
mut
self
,
path_span
:
Span
,
path_segment
:
&
'v
PathSegment
)
{
walk_path_segment
(
self
,
path_span
,
path_segment
)
...
...
@@ -402,13 +402,13 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyPath
(
ref
path
)
=>
{
visitor
.visit_path
(
path
,
typ
.id
);
}
TyQPath
(
ref
qpath
)
=>
{
visitor
.visit_qpath
(
&**
qpath
,
typ
.id
);
}
TyObjectSum
(
ref
ty
,
ref
bounds
)
=>
{
visitor
.visit_ty
(
&**
ty
);
walk_ty_param_bounds_helper
(
visitor
,
bounds
);
}
TyQPath
(
ref
qpath
)
=>
{
visitor
.visit_qpath
(
typ
.span
,
&**
qpath
);
}
TyFixedLengthVec
(
ref
ty
,
ref
expression
)
=>
{
visitor
.visit_ty
(
&**
ty
);
visitor
.visit_expr
(
&**
expression
)
...
...
@@ -436,12 +436,10 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
}
}
pub
fn
walk_qpath
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
qpath_span
:
Span
,
qpath
:
&
'v
QPath
)
{
pub
fn
walk_qpath
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
qpath
:
&
'v
QPath
)
{
visitor
.visit_ty
(
&*
qpath
.self_type
);
visitor
.visit_trait_ref
(
&*
qpath
.trait_ref
);
visitor
.visit_path_segment
(
qpath
_
span
,
&
qpath
.item_path
);
walk_path
(
visitor
,
&
qpath
.trait_path
);
visitor
.visit_path_segment
(
qpath
.trait_path.
span
,
&
qpath
.item_path
);
}
pub
fn
walk_path_segment
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
...
...
@@ -873,7 +871,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor
.visit_path
(
path
,
expression
.id
)
}
ExprQPath
(
ref
qpath
)
=>
{
visitor
.visit_qpath
(
expression
.span
,
&**
qpath
)
visitor
.visit_qpath
(
&**
qpath
,
expression
.id
)
}
ExprBreak
(
_
)
|
ExprAgain
(
_
)
=>
{}
ExprRet
(
ref
optional_expression
)
=>
{
...
...
src/test/compile-fail/ufcs-qpath-missing-params.rs
浏览文件 @
004df413
...
...
@@ -12,5 +12,5 @@
fn
main
()
{
<
String
as
IntoCow
>
::
into_cow
(
"foo"
.to_string
());
//~^ ERROR
wrong number of type arguments: expected 1, found 0
//~^ ERROR
too few type parameters provided: expected 1 parameter(s)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录