Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
287de259
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,发现更多精彩内容 >>
提交
287de259
编写于
7月 07, 2017
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Store all generic arguments for method calls in AST
上级
8b1271fc
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
82 addition
and
69 deletion
+82
-69
src/librustc/hir/lowering.rs
src/librustc/hir/lowering.rs
+9
-2
src/librustc_passes/ast_validation.rs
src/librustc_passes/ast_validation.rs
+17
-0
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+6
-8
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+4
-7
src/libsyntax/ext/build.rs
src/libsyntax/ext/build.rs
+1
-2
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+8
-3
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+15
-33
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+6
-10
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+2
-3
src/test/compile-fail/method-call-type-binding.rs
src/test/compile-fail/method-call-type-binding.rs
+13
-0
src/test/parse-fail/type-parameters-in-field-exprs.rs
src/test/parse-fail/type-parameters-in-field-exprs.rs
+1
-1
未找到文件。
src/librustc/hir/lowering.rs
浏览文件 @
287de259
...
...
@@ -1844,10 +1844,17 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
let
f
=
P
(
self
.lower_expr
(
f
));
hir
::
ExprCall
(
f
,
args
.iter
()
.map
(|
x
|
self
.lower_expr
(
x
))
.collect
())
}
ExprKind
::
MethodCall
(
i
,
ref
tps
,
ref
args
)
=>
{
ExprKind
::
MethodCall
(
ref
seg
,
ref
args
)
=>
{
let
tps
=
match
seg
.parameters
{
Some
(
ref
params
)
=>
match
**
params
{
PathParameters
::
AngleBracketed
(
ref
param_data
)
=>
&
param_data
.types
[
..
],
_
=>
&
[],
},
_
=>
&
[],
};
let
tps
=
tps
.iter
()
.map
(|
x
|
self
.lower_ty
(
x
))
.collect
();
let
args
=
args
.iter
()
.map
(|
x
|
self
.lower_expr
(
x
))
.collect
();
hir
::
ExprMethodCall
(
respan
(
i
.span
,
self
.lower_ident
(
i
.node
)),
tps
,
args
)
hir
::
ExprMethodCall
(
respan
(
seg
.span
,
self
.lower_ident
(
seg
.identifier
)),
tps
,
args
)
}
ExprKind
::
Binary
(
binop
,
ref
lhs
,
ref
rhs
)
=>
{
let
binop
=
self
.lower_binop
(
binop
);
...
...
src/librustc_passes/ast_validation.rs
浏览文件 @
287de259
...
...
@@ -125,6 +125,23 @@ fn visit_expr(&mut self, expr: &'a Expr) {
ExprKind
::
Continue
(
Some
(
ident
))
=>
{
self
.check_label
(
ident
.node
,
ident
.span
);
}
ExprKind
::
MethodCall
(
ref
segment
,
..
)
=>
{
if
let
Some
(
ref
params
)
=
segment
.parameters
{
match
**
params
{
PathParameters
::
AngleBracketed
(
ref
param_data
)
=>
{
if
!
param_data
.bindings
.is_empty
()
{
let
binding_span
=
param_data
.bindings
[
0
]
.span
;
self
.err_handler
()
.span_err
(
binding_span
,
"type bindings cannot be used in method calls"
);
}
}
PathParameters
::
Parenthesized
(
..
)
=>
{
self
.err_handler
()
.span_err
(
expr
.span
,
"parenthesized parameters cannot be used on method calls"
);
}
}
}
}
_
=>
{}
}
...
...
src/librustc_resolve/lib.rs
浏览文件 @
287de259
...
...
@@ -2467,9 +2467,9 @@ fn smart_resolve_path_fragment(&mut self,
path_str
,
ident
.node
));
return
err
;
}
ExprKind
::
MethodCall
(
id
ent
,
..
)
=>
{
ExprKind
::
MethodCall
(
ref
segm
ent
,
..
)
=>
{
err
.span_label
(
parent
.span
,
format!
(
"did you mean `{}::{}(...)`?"
,
path_str
,
ident
.node
));
path_str
,
segment
.identifier
));
return
err
;
}
_
=>
{}
...
...
@@ -3145,15 +3145,13 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
ExprKind
::
Field
(
ref
subexpression
,
_
)
=>
{
self
.resolve_expr
(
subexpression
,
Some
(
expr
));
}
ExprKind
::
MethodCall
(
_
,
ref
types
,
ref
arguments
)
=>
{
ExprKind
::
MethodCall
(
ref
segment
,
ref
arguments
)
=>
{
let
mut
arguments
=
arguments
.iter
();
self
.resolve_expr
(
arguments
.next
()
.unwrap
(),
Some
(
expr
));
for
argument
in
arguments
{
self
.resolve_expr
(
argument
,
None
);
}
for
ty
in
types
.iter
()
{
self
.visit_ty
(
ty
);
}
self
.visit_path_segment
(
expr
.span
,
segment
);
}
ExprKind
::
Repeat
(
ref
element
,
ref
count
)
=>
{
...
...
@@ -3185,10 +3183,10 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
let
traits
=
self
.get_traits_containing_item
(
name
.node
,
ValueNS
);
self
.trait_map
.insert
(
expr
.id
,
traits
);
}
ExprKind
::
MethodCall
(
name
,
..
)
=>
{
ExprKind
::
MethodCall
(
ref
segment
,
..
)
=>
{
debug!
(
"(recording candidate traits for expr) recording traits for {}"
,
expr
.id
);
let
traits
=
self
.get_traits_containing_item
(
name
.node
,
ValueNS
);
let
traits
=
self
.get_traits_containing_item
(
segment
.identifier
,
ValueNS
);
self
.trait_map
.insert
(
expr
.id
,
traits
);
}
_
=>
{
...
...
src/libsyntax/ast.rs
浏览文件 @
287de259
...
...
@@ -848,19 +848,16 @@ pub enum ExprKind {
/// The first field resolves to the function itself,
/// and the second field is the list of arguments
Call
(
P
<
Expr
>
,
Vec
<
P
<
Expr
>>
),
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
/// A method call (`x.foo::<
'static,
Bar, Baz>(a, b, c, d)`)
///
/// The `SpannedIdent` is the identifier for the method name.
/// The vector of `Ty`s are the ascripted type parameters for the method
/// The `PathSegment` represents the method name and its generic arguments
/// (within the angle brackets).
///
/// The first element of the vector of `Expr`s is the expression that evaluates
/// to the object on which the method is being called on (the receiver),
/// and the remaining elements are the rest of the arguments.
///
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(
foo, [Bar, Baz]
, [x, a, b, c, d])`.
MethodCall
(
SpannedIdent
,
Vec
<
P
<
Ty
>>
,
Vec
<
P
<
Expr
>>
),
/// `ExprKind::MethodCall(
PathSegment { foo, [Bar, Baz] }
, [x, a, b, c, d])`.
MethodCall
(
PathSegment
,
Vec
<
P
<
Expr
>>
),
/// A tuple (`(a, b, c ,d)`)
Tup
(
Vec
<
P
<
Expr
>>
),
/// A binary operation (For example: `a + b`, `a * b`)
...
...
src/libsyntax/ext/build.rs
浏览文件 @
287de259
...
...
@@ -673,9 +673,8 @@ fn expr_method_call(&self, span: Span,
expr
:
P
<
ast
::
Expr
>
,
ident
:
ast
::
Ident
,
mut
args
:
Vec
<
P
<
ast
::
Expr
>>
)
->
P
<
ast
::
Expr
>
{
let
id
=
Spanned
{
node
:
ident
,
span
:
span
};
args
.insert
(
0
,
expr
);
self
.expr
(
span
,
ast
::
ExprKind
::
MethodCall
(
id
,
Vec
::
new
(
),
args
))
self
.expr
(
span
,
ast
::
ExprKind
::
MethodCall
(
ast
::
PathSegment
::
from_ident
(
ident
,
span
),
args
))
}
fn
expr_block
(
&
self
,
b
:
P
<
ast
::
Block
>
)
->
P
<
ast
::
Expr
>
{
self
.expr
(
b
.span
,
ast
::
ExprKind
::
Block
(
b
))
...
...
src/libsyntax/fold.rs
浏览文件 @
287de259
...
...
@@ -1151,10 +1151,15 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
ExprKind
::
Call
(
folder
.fold_expr
(
f
),
folder
.fold_exprs
(
args
))
}
ExprKind
::
MethodCall
(
i
,
tps
,
args
)
=>
{
ExprKind
::
MethodCall
(
seg
,
args
)
=>
{
ExprKind
::
MethodCall
(
respan
(
folder
.new_span
(
i
.span
),
folder
.fold_ident
(
i
.node
)),
tps
.move_map
(|
x
|
folder
.fold_ty
(
x
)),
PathSegment
{
identifier
:
folder
.fold_ident
(
seg
.identifier
),
span
:
folder
.new_span
(
seg
.span
),
parameters
:
seg
.parameters
.map
(|
ps
|
{
ps
.map
(|
ps
|
folder
.fold_path_parameters
(
ps
))
}),
},
folder
.fold_exprs
(
args
))
}
ExprKind
::
Binary
(
binop
,
lhs
,
rhs
)
=>
{
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
287de259
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
use
abi
::{
self
,
Abi
};
use
ast
::{
AttrStyle
,
BareFnTy
};
use
ast
::{
A
ngleBracketedParameterData
,
A
ttrStyle
,
BareFnTy
};
use
ast
::{
RegionTyParamBound
,
TraitTyParamBound
,
TraitBoundModifier
};
use
ast
::
Unsafety
;
use
ast
::{
Mod
,
Arg
,
Arm
,
Attribute
,
BindingMode
,
TraitItemKind
};
...
...
@@ -1831,11 +1831,7 @@ pub fn parse_path_segments_without_colons(&mut self, parse_generics: bool)
let
parameters
=
if
parse_generics
&&
self
.eat_lt
()
{
let
(
lifetimes
,
types
,
bindings
)
=
self
.parse_generic_args
()
?
;
self
.expect_gt
()
?
;
ast
::
AngleBracketedParameterData
{
lifetimes
:
lifetimes
,
types
:
types
,
bindings
:
bindings
,
}
.into
()
AngleBracketedParameterData
{
lifetimes
,
types
,
bindings
}
.into
()
}
else
if
self
.eat
(
&
token
::
OpenDelim
(
token
::
Paren
))
{
let
lo
=
self
.prev_span
;
...
...
@@ -1898,11 +1894,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<PathSegment
segments
.push
(
PathSegment
{
identifier
:
identifier
,
span
:
ident_span
,
parameters
:
ast
::
AngleBracketedParameterData
{
lifetimes
:
lifetimes
,
types
:
types
,
bindings
:
bindings
,
}
.into
(),
parameters
:
AngleBracketedParameterData
{
lifetimes
,
types
,
bindings
}
.into
(),
});
// Consumed `a::b::<T,U>`, check for `::` before proceeding
...
...
@@ -2023,14 +2015,6 @@ pub fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
ExprKind
::
Call
(
f
,
args
)
}
fn
mk_method_call
(
&
mut
self
,
ident
:
ast
::
SpannedIdent
,
tps
:
Vec
<
P
<
Ty
>>
,
args
:
Vec
<
P
<
Expr
>>
)
->
ast
::
ExprKind
{
ExprKind
::
MethodCall
(
ident
,
tps
,
args
)
}
pub
fn
mk_index
(
&
mut
self
,
expr
:
P
<
Expr
>
,
idx
:
P
<
Expr
>
)
->
ast
::
ExprKind
{
ExprKind
::
Index
(
expr
,
idx
)
}
...
...
@@ -2460,7 +2444,7 @@ pub fn parse_dot_or_call_expr_with(&mut self,
// parsing into an expression.
fn
parse_dot_suffix
(
&
mut
self
,
ident
:
Ident
,
ident_span
:
Span
,
self_value
:
P
<
Expr
>
,
lo
:
Span
)
->
PResult
<
'a
,
P
<
Expr
>>
{
let
(
_
,
ty
s
,
bindings
)
=
if
self
.eat
(
&
token
::
ModSep
)
{
let
(
lifetimes
,
type
s
,
bindings
)
=
if
self
.eat
(
&
token
::
ModSep
)
{
self
.expect_lt
()
?
;
let
args
=
self
.parse_generic_args
()
?
;
self
.expect_gt
()
?
;
...
...
@@ -2469,11 +2453,6 @@ fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, self_value: P<Exp
(
Vec
::
new
(),
Vec
::
new
(),
Vec
::
new
())
};
if
!
bindings
.is_empty
()
{
let
prev_span
=
self
.prev_span
;
self
.span_err
(
prev_span
,
"type bindings are only permitted on trait paths"
);
}
Ok
(
match
self
.token
{
// expr.f() method call.
token
::
OpenDelim
(
token
::
Paren
)
=>
{
...
...
@@ -2486,17 +2465,20 @@ fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, self_value: P<Exp
let
hi
=
self
.prev_span
;
es
.insert
(
0
,
self_value
);
let
id
=
respan
(
ident_span
.to
(
ident_span
),
ident
);
let
nd
=
self
.mk_method_call
(
id
,
tys
,
es
);
self
.mk_expr
(
lo
.to
(
hi
),
nd
,
ThinVec
::
new
())
let
seg
=
PathSegment
{
identifier
:
ident
,
span
:
ident_span
.to
(
ident_span
),
parameters
:
AngleBracketedParameterData
{
lifetimes
,
types
,
bindings
}
.into
(),
};
self
.mk_expr
(
lo
.to
(
hi
),
ExprKind
::
MethodCall
(
seg
,
es
),
ThinVec
::
new
())
}
// Field access.
_
=>
{
if
!
tys
.is_empty
()
{
let
prev_span
=
self
.prev_span
;
self
.span_err
(
prev_span
,
"field expressions may not
\
have type parameter
s"
);
if
let
Some
(
generic_arg_span
)
=
lifetimes
.get
(
0
)
.map
(|
x
|
x
.span
)
.or_else
(||
types
.get
(
0
)
.map
(|
x
|
x
.span
))
.or_else
(||
bindings
.get
(
0
)
.map
(|
x
|
x
.span
))
{
self
.span_err
(
generic_arg_span
,
"field expressions may not have generic argument
s"
);
}
let
id
=
respan
(
ident_span
.to
(
ident_span
),
ident
);
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
287de259
...
...
@@ -1951,18 +1951,14 @@ fn print_expr_call(&mut self,
}
fn
print_expr_method_call
(
&
mut
self
,
ident
:
ast
::
SpannedIdent
,
tys
:
&
[
P
<
ast
::
Ty
>
],
segment
:
&
ast
::
PathSegment
,
args
:
&
[
P
<
ast
::
Expr
>
])
->
io
::
Result
<
()
>
{
let
base_args
=
&
args
[
1
..
];
self
.print_expr
(
&
args
[
0
])
?
;
word
(
&
mut
self
.s
,
"."
)
?
;
self
.print_ident
(
ident
.node
)
?
;
if
!
tys
.is_empty
()
{
word
(
&
mut
self
.s
,
"::<"
)
?
;
self
.commasep
(
Inconsistent
,
tys
,
|
s
,
ty
|
s
.print_type
(
ty
))
?
;
word
(
&
mut
self
.s
,
">"
)
?
;
self
.print_ident
(
segment
.identifier
)
?
;
if
let
Some
(
ref
parameters
)
=
segment
.parameters
{
self
.print_path_parameters
(
parameters
,
true
)
?
;
}
self
.print_call_post
(
base_args
)
}
...
...
@@ -2041,8 +2037,8 @@ fn print_expr_outer_attr_style(&mut self,
ast
::
ExprKind
::
Call
(
ref
func
,
ref
args
)
=>
{
self
.print_expr_call
(
func
,
&
args
[
..
])
?
;
}
ast
::
ExprKind
::
MethodCall
(
ident
,
ref
tys
,
ref
args
)
=>
{
self
.print_expr_method_call
(
ident
,
&
tys
[
..
]
,
&
args
[
..
])
?
;
ast
::
ExprKind
::
MethodCall
(
ref
segment
,
ref
args
)
=>
{
self
.print_expr_method_call
(
segment
,
&
args
[
..
])
?
;
}
ast
::
ExprKind
::
Binary
(
op
,
ref
lhs
,
ref
rhs
)
=>
{
self
.print_expr_binary
(
op
,
lhs
,
rhs
)
?
;
...
...
src/libsyntax/visit.rs
浏览文件 @
287de259
...
...
@@ -674,9 +674,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor
.visit_expr
(
callee_expression
);
walk_list!
(
visitor
,
visit_expr
,
arguments
);
}
ExprKind
::
MethodCall
(
ref
ident
,
ref
types
,
ref
arguments
)
=>
{
visitor
.visit_ident
(
ident
.span
,
ident
.node
);
walk_list!
(
visitor
,
visit_ty
,
types
);
ExprKind
::
MethodCall
(
ref
segment
,
ref
arguments
)
=>
{
visitor
.visit_path_segment
(
expression
.span
,
segment
);
walk_list!
(
visitor
,
visit_expr
,
arguments
);
}
ExprKind
::
Binary
(
_
,
ref
left_expression
,
ref
right_expression
)
=>
{
...
...
src/test/compile-fail/method-call-type-binding.rs
0 → 100644
浏览文件 @
287de259
// Copyright 2017 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.
fn
main
()
{
0
.clone
::
<
T
=
u8
>
();
//~ ERROR type bindings cannot be used in method calls
}
src/test/parse-fail/type-parameters-in-field-exprs.rs
浏览文件 @
287de259
...
...
@@ -21,5 +21,5 @@ fn main() {
y
:
2
,
};
f
.x
::
<
isize
>
;
//~^ ERROR field expressions may not have
type parameter
s
//~^ ERROR field expressions may not have
generic argument
s
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录