Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e970db37
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,发现更多精彩内容 >>
提交
e970db37
编写于
1月 03, 2015
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove old slicing hacks and make new slicing work
上级
f7ff37e4
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
137 addition
and
403 deletion
+137
-403
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/expr_use_visitor.rs
+6
-22
src/librustc/middle/lang_items.rs
src/librustc/middle/lang_items.rs
+0
-2
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+13
-21
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+2
-3
src/librustc_trans/trans/cleanup.rs
src/librustc_trans/trans/cleanup.rs
+3
-5
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+1
-34
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+43
-172
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+20
-95
src/libsyntax/parse/token.rs
src/libsyntax/parse/token.rs
+49
-49
未找到文件。
src/librustc/middle/expr_use_visitor.rs
浏览文件 @
e970db37
...
...
@@ -441,28 +441,12 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
}
ast
::
ExprIndex
(
ref
lhs
,
ref
rhs
)
=>
{
// lhs[rhs]
match
rhs
.node
{
ast
::
ExprRange
(
ref
start
,
ref
end
)
=>
{
// Hacked slicing syntax (KILLME).
let
args
=
match
(
start
,
end
)
{
(
&
Some
(
ref
e1
),
&
Some
(
ref
e2
))
=>
vec!
[
&**
e1
,
&**
e2
],
(
&
Some
(
ref
e
),
&
None
)
=>
vec!
[
&**
e
],
(
&
None
,
&
Some
(
ref
e
))
=>
vec!
[
&**
e
],
(
&
None
,
&
None
)
=>
Vec
::
new
()
};
let
overloaded
=
self
.walk_overloaded_operator
(
expr
,
&**
lhs
,
args
,
PassArgs
::
ByRef
);
assert
!
(
overloaded
);
}
_
=>
{
if
!
self
.walk_overloaded_operator
(
expr
,
&**
lhs
,
vec!
[
&**
rhs
],
PassArgs
::
ByRef
)
{
self
.select_from_expr
(
&**
lhs
);
self
.consume_expr
(
&**
rhs
);
}
}
if
!
self
.walk_overloaded_operator
(
expr
,
&**
lhs
,
vec!
[
&**
rhs
],
PassArgs
::
ByRef
)
{
self
.select_from_expr
(
&**
lhs
);
self
.consume_expr
(
&**
rhs
);
}
}
...
...
src/librustc/middle/lang_items.rs
浏览文件 @
e970db37
...
...
@@ -266,8 +266,6 @@ pub fn collect_language_items(krate: &ast::Crate,
ShrTraitLangItem
,
"shr"
,
shr_trait
;
IndexTraitLangItem
,
"index"
,
index_trait
;
IndexMutTraitLangItem
,
"index_mut"
,
index_mut_trait
;
SliceTraitLangItem
,
"slice"
,
slice_trait
;
SliceMutTraitLangItem
,
"slice_mut"
,
slice_mut_trait
;
RangeStructLangItem
,
"range"
,
range_struct
;
RangeFromStructLangItem
,
"range_from"
,
range_from_struct
;
RangeToStructLangItem
,
"range_to"
,
range_to_struct
;
...
...
src/librustc/middle/mem_categorization.rs
浏览文件 @
e970db37
...
...
@@ -482,28 +482,20 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
Ok
(
self
.cat_tup_field
(
expr
,
base_cmt
,
idx
.node
,
expr_ty
))
}
ast
::
ExprIndex
(
ref
base
,
ref
idx
)
=>
{
match
idx
.node
{
ast
::
ExprRange
(
..
)
=>
{
// Slicing syntax special case (KILLME).
Ok
(
self
.cat_rvalue_node
(
expr
.id
(),
expr
.span
(),
expr_ty
))
ast
::
ExprIndex
(
ref
base
,
_
)
=>
{
let
method_call
=
ty
::
MethodCall
::
expr
(
expr
.id
());
match
self
.typer
.node_method_ty
(
method_call
)
{
Some
(
method_ty
)
=>
{
// If this is an index implemented by a method call, then it will
// include an implicit deref of the result.
let
ret_ty
=
ty
::
ty_fn_ret
(
method_ty
)
.unwrap
();
self
.cat_deref
(
expr
,
self
.cat_rvalue_node
(
expr
.id
(),
expr
.span
(),
ret_ty
),
1
,
true
)
}
_
=>
{
let
method_call
=
ty
::
MethodCall
::
expr
(
expr
.id
());
match
self
.typer
.node_method_ty
(
method_call
)
{
Some
(
method_ty
)
=>
{
// If this is an index implemented by a method call, then it will
// include an implicit deref of the result.
let
ret_ty
=
ty
::
ty_fn_ret
(
method_ty
)
.unwrap
();
self
.cat_deref
(
expr
,
self
.cat_rvalue_node
(
expr
.id
(),
expr
.span
(),
ret_ty
),
1
,
true
)
}
None
=>
{
self
.cat_index
(
expr
,
try!
(
self
.cat_expr
(
&**
base
)))
}
}
None
=>
{
self
.cat_index
(
expr
,
self
.cat_expr
(
&**
base
))
}
}
}
...
...
src/librustc/middle/ty.rs
浏览文件 @
e970db37
...
...
@@ -1047,7 +1047,7 @@ pub struct ClosureTy<'tcx> {
pub
abi
:
abi
::
Abi
,
}
#[derive(Clone,
Copy,
PartialEq,
Eq,
Hash)]
#[derive(Clone,
Copy,
PartialEq,
Eq,
Hash
,
Show
)]
pub
enum
FnOutput
<
'tcx
>
{
FnConverging
(
Ty
<
'tcx
>
),
FnDiverging
...
...
@@ -1699,8 +1699,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl
<
'tcx
>
fmt
::
Show
for
FnSig
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
// grr, without tcx not much we can do.
write!
(
f
,
"(...)"
)
write!
(
f
,
"({}; variadic: {})->{}"
,
self
.inputs
,
self
.variadic
,
self
.output
)
}
}
...
...
src/librustc_trans/trans/cleanup.rs
浏览文件 @
e970db37
...
...
@@ -24,8 +24,7 @@
use
trans
::
common
::{
Block
,
FunctionContext
,
ExprId
,
NodeInfo
};
use
trans
::
debuginfo
;
use
trans
::
glue
;
// Temporary due to slicing syntax hacks (KILLME)
//use middle::region;
use
middle
::
region
;
use
trans
::
type_
::
Type
;
use
middle
::
ty
::{
self
,
Ty
};
use
std
::
fmt
;
...
...
@@ -129,8 +128,7 @@ fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) {
// excluding id's that correspond to closure bodies only). For
// now we just say that if there is already an AST scope on the stack,
// this new AST scope had better be its immediate child.
// Temporarily removed due to slicing syntax hacks (KILLME).
/*let top_scope = self.top_ast_scope();
let
top_scope
=
self
.top_ast_scope
();
if
top_scope
.is_some
()
{
assert_eq!
(
self
.ccx
.tcx
()
...
...
@@ -138,7 +136,7 @@ fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) {
.opt_encl_scope
(
region
::
CodeExtent
::
from_node_id
(
debug_loc
.id
))
.map
(|
s
|
s
.node_id
()),
top_scope
);
}
*/
}
self
.push_scope
(
CleanupScope
::
new
(
AstScopeKind
(
debug_loc
.id
),
Some
(
debug_loc
)));
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
e970db37
...
...
@@ -573,40 +573,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
trans_rec_tup_field
(
bcx
,
&**
base
,
idx
.node
)
}
ast
::
ExprIndex
(
ref
base
,
ref
idx
)
=>
{
match
idx
.node
{
ast
::
ExprRange
(
ref
start
,
ref
end
)
=>
{
// Special case for slicing syntax (KILLME).
let
_
icx
=
push_ctxt
(
"trans_slice"
);
let
ccx
=
bcx
.ccx
();
let
method_call
=
MethodCall
::
expr
(
expr
.id
);
let
method_ty
=
ccx
.tcx
()
.method_map
.borrow
()
.get
(
&
method_call
)
.map
(|
method
|
method
.ty
);
let
base_datum
=
unpack_datum!
(
bcx
,
trans
(
bcx
,
&**
base
));
let
mut
args
=
vec!
[];
start
.as_ref
()
.map
(|
e
|
args
.push
((
unpack_datum!
(
bcx
,
trans
(
bcx
,
&**
e
)),
e
.id
)));
end
.as_ref
()
.map
(|
e
|
args
.push
((
unpack_datum!
(
bcx
,
trans
(
bcx
,
&**
e
)),
e
.id
)));
let
result_ty
=
ty
::
ty_fn_ret
(
monomorphize_type
(
bcx
,
method_ty
.unwrap
()))
.unwrap
();
let
scratch
=
rvalue_scratch_datum
(
bcx
,
result_ty
,
"trans_slice"
);
unpack_result!
(
bcx
,
trans_overloaded_op
(
bcx
,
expr
,
method_call
,
base_datum
,
args
,
Some
(
SaveIn
(
scratch
.val
)),
true
));
DatumBlock
::
new
(
bcx
,
scratch
.to_expr_datum
())
}
_
=>
trans_index
(
bcx
,
expr
,
&**
base
,
&**
idx
,
MethodCall
::
expr
(
expr
.id
))
}
trans_index
(
bcx
,
expr
,
&**
base
,
&**
idx
,
MethodCall
::
expr
(
expr
.id
))
}
ast
::
ExprBox
(
_
,
ref
contents
)
=>
{
// Special case for `Box<T>`
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
e970db37
...
...
@@ -2377,90 +2377,6 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
}
}
/// Checks for a `Slice` (or `SliceMut`) impl at the relevant level of autoderef. If it finds one,
/// installs method info and returns type of method (else None).
fn
try_overloaded_slice_step
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
method_call
:
MethodCall
,
expr
:
&
ast
::
Expr
,
base_expr
:
&
ast
::
Expr
,
base_ty
:
Ty
<
'tcx
>
,
// autoderef'd type
autoderefref
:
ty
::
AutoDerefRef
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
,
start_expr
:
&
Option
<
P
<
ast
::
Expr
>>
,
end_expr
:
&
Option
<
P
<
ast
::
Expr
>>
)
->
Option
<
(
Ty
<
'tcx
>
,
/* index type */
Ty
<
'tcx
>
)
>
/* return type */
{
let
input_ty
=
fcx
.infcx
()
.next_ty_var
();
let
return_ty
=
fcx
.infcx
()
.next_ty_var
();
let
method
=
match
lvalue_pref
{
PreferMutLvalue
=>
{
// Try `SliceMut` first, if preferred.
match
fcx
.tcx
()
.lang_items
.slice_mut_trait
()
{
Some
(
trait_did
)
=>
{
let
method_name
=
match
(
start_expr
,
end_expr
)
{
(
&
Some
(
_
),
&
Some
(
_
))
=>
"slice_or_fail_mut"
,
(
&
Some
(
_
),
&
None
)
=>
"slice_from_or_fail_mut"
,
(
&
None
,
&
Some
(
_
))
=>
"slice_to_or_fail_mut"
,
(
&
None
,
&
None
)
=>
"as_mut_slice_"
,
};
method
::
lookup_in_trait_adjusted
(
fcx
,
expr
.span
,
Some
(
&*
base_expr
),
token
::
intern
(
method_name
),
trait_did
,
autoderefref
,
base_ty
,
Some
(
vec!
[
input_ty
,
return_ty
]))
}
_
=>
None
,
}
}
NoPreference
=>
{
// Otherwise, fall back to `Slice`.
match
fcx
.tcx
()
.lang_items
.slice_trait
()
{
Some
(
trait_did
)
=>
{
let
method_name
=
match
(
start_expr
,
end_expr
)
{
(
&
Some
(
_
),
&
Some
(
_
))
=>
"slice_or_fail"
,
(
&
Some
(
_
),
&
None
)
=>
"slice_from_or_fail"
,
(
&
None
,
&
Some
(
_
))
=>
"slice_to_or_fail"
,
(
&
None
,
&
None
)
=>
"as_slice_"
,
};
method
::
lookup_in_trait_adjusted
(
fcx
,
expr
.span
,
Some
(
&*
base_expr
),
token
::
intern
(
method_name
),
trait_did
,
autoderefref
,
base_ty
,
Some
(
vec!
[
input_ty
,
return_ty
]))
}
_
=>
None
,
}
}
};
// If some lookup succeeded, install method in table
method
.map
(|
method
|
{
let
method_ty
=
method
.ty
;
make_overloaded_lvalue_return_type
(
fcx
,
Some
(
method_call
),
Some
(
method
));
let
result_ty
=
ty
::
ty_fn_ret
(
method_ty
);
let
result_ty
=
match
result_ty
{
ty
::
FnConverging
(
result_ty
)
=>
result_ty
,
ty
::
FnDiverging
=>
{
fcx
.tcx
()
.sess
.span_bug
(
expr
.span
,
"slice trait does not define a `!` return"
)
}
};
(
input_ty
,
result_ty
)
})
}
/// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
/// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
/// This loop implements one step in that search; the autoderef loop is implemented by
...
...
@@ -2474,26 +2390,17 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
lvalue_pref
:
LvaluePreference
)
->
Option
<
(
/*index type*/
Ty
<
'tcx
>
,
/*element type*/
Ty
<
'tcx
>
)
>
{
let
tcx
=
fcx
.tcx
();
debug!
(
"try_index_step(expr={}, base_expr.id={}, adjusted_ty={}, adjustment={})"
,
expr
.repr
(
fcx
.tcx
()
),
base_expr
.repr
(
fcx
.tcx
()
),
adjusted_ty
.repr
(
fcx
.tcx
()
),
expr
.repr
(
tcx
),
base_expr
.repr
(
tcx
),
adjusted_ty
.repr
(
tcx
),
adjustment
);
// Try built-in indexing first.
match
ty
::
index
(
adjusted_ty
)
{
Some
(
ty
)
=>
{
fcx
.write_adjustment
(
base_expr
.id
,
base_expr
.span
,
ty
::
AdjustDerefRef
(
adjustment
));
return
Some
((
fcx
.tcx
()
.types.uint
,
ty
));
}
None
=>
{
}
}
let
input_ty
=
fcx
.infcx
()
.next_ty_var
();
// Try `IndexMut` first, if preferred.
let
method
=
match
(
lvalue_pref
,
fcx
.tcx
()
.lang_items
.index_mut_trait
())
{
let
method
=
match
(
lvalue_pref
,
tcx
.lang_items
.index_mut_trait
())
{
(
PreferMutLvalue
,
Some
(
trait_did
))
=>
{
method
::
lookup_in_trait_adjusted
(
fcx
,
expr
.span
,
...
...
@@ -2508,24 +2415,37 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
};
// Otherwise, fall back to `Index`.
let
method
=
match
(
method
,
fcx
.tcx
()
.lang_items
.index_trait
())
{
let
method
=
match
(
method
,
tcx
.lang_items
.index_trait
())
{
(
None
,
Some
(
trait_did
))
=>
{
method
::
lookup_in_trait_adjusted
(
fcx
,
expr
.span
,
Some
(
&*
base_expr
),
token
::
intern
(
"index"
),
trait_did
,
adjustment
,
adjustment
.clone
()
,
adjusted_ty
,
Some
(
vec!
[
input_ty
]))
}
(
method
,
_
)
=>
method
,
};
if
method
.is_none
()
{
// If there are no overridden index impls, use built-in indexing.
match
ty
::
index
(
adjusted_ty
)
{
Some
(
ty
)
=>
{
debug!
(
"try_index_step: success, using built-in indexing"
);
fcx
.write_adjustment
(
base_expr
.id
,
base_expr
.span
,
ty
::
AdjustDerefRef
(
adjustment
));
return
Some
((
tcx
.types.uint
,
ty
));
}
None
=>
{}
}
}
// If some lookup succeeds, write callee into table and extract index/element
// type from the method signature.
// If some lookup succeeded, install method in table
method
.and_then
(|
method
|
{
debug!
(
"try_index_step: success, using overloaded indexing"
);
make_overloaded_lvalue_return_type
(
fcx
,
Some
(
method_call
),
Some
(
method
))
.
map
(|
ret
|
(
input_ty
,
ret
.ty
))
})
...
...
@@ -4270,91 +4190,42 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
if
ty
::
type_is_error
(
base_t
)
{
fcx
.write_ty
(
id
,
base_t
);
}
else
{
match
idx
.node
{
ast
::
ExprRange
(
ref
start
,
ref
end
)
=>
{
// A slice, rather than an index. Special cased for now (KILLME).
check_expr
(
fcx
,
&**
idx
);
let
idx_t
=
fcx
.expr_ty
(
&**
idx
);
if
ty
::
type_is_error
(
idx_t
)
{
fcx
.write_ty
(
id
,
idx_t
);
}
else
{
let
base_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
base_t
);
let
result
=
autoderef_for_index
(
fcx
,
&**
base
,
base_t
,
lvalue_pref
,
|
adj_ty
,
adj
|
{
try_overloaded_slice_step
(
fcx
,
MethodCall
::
expr
(
expr
.id
),
expr
,
&**
base
,
adj_ty
,
adj
,
lvalue_pref
,
start
,
end
)
try_index_step
(
fcx
,
MethodCall
::
expr
(
expr
.id
),
expr
,
&**
base
,
adj_ty
,
adj
,
lvalue_pref
)
});
let
mut
args
=
vec!
[];
start
.as_ref
()
.map
(|
x
|
args
.push
(
x
));
end
.as_ref
()
.map
(|
x
|
args
.push
(
x
));
match
result
{
Some
((
index_ty
,
element_ty
))
=>
{
for
a
in
args
.iter
()
{
check_expr_has_type
(
fcx
,
&***
a
,
index_ty
);
}
fcx
.write_ty
(
idx
.id
,
element_ty
);
fcx
.write_ty
(
id
,
element_ty
)
check_expr_has_type
(
fcx
,
&**
idx
,
index_ty
);
fcx
.write_ty
(
id
,
element_ty
);
}
_
=>
{
for
a
in
args
.iter
()
{
check_expr
(
fcx
,
&***
a
);
}
fcx
.type_error_message
(
expr
.span
,
|
actual
|
{
format!
(
"cannot take a slice of a value with type `{}`"
,
check_expr_has_type
(
fcx
,
&**
idx
,
fcx
.tcx
()
.types.err
);
fcx
.type_error_message
(
expr
.span
,
|
actual
|
{
format!
(
"cannot index a value of type `{}`"
,
actual
)
},
base_t
,
None
);
fcx
.write_ty
(
idx
.id
,
fcx
.tcx
()
.types.err
);
},
base_t
,
None
);
fcx
.write_ty
(
id
,
fcx
.tcx
()
.types.err
);
}
}
}
_
=>
{
check_expr
(
fcx
,
&**
idx
);
let
idx_t
=
fcx
.expr_ty
(
&**
idx
);
if
ty
::
type_is_error
(
idx_t
)
{
fcx
.write_ty
(
id
,
idx_t
);
}
else
{
let
base_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
base_t
);
let
result
=
autoderef_for_index
(
fcx
,
&**
base
,
base_t
,
lvalue_pref
,
|
adj_ty
,
adj
|
{
try_index_step
(
fcx
,
MethodCall
::
expr
(
expr
.id
),
expr
,
&**
base
,
adj_ty
,
adj
,
lvalue_pref
)
});
match
result
{
Some
((
index_ty
,
element_ty
))
=>
{
check_expr_has_type
(
fcx
,
&**
idx
,
index_ty
);
fcx
.write_ty
(
id
,
element_ty
);
}
_
=>
{
check_expr_has_type
(
fcx
,
&**
idx
,
fcx
.tcx
()
.types.err
);
fcx
.type_error_message
(
expr
.span
,
|
actual
|
{
format!
(
"cannot index a value of type `{}`"
,
actual
)
},
base_t
,
None
);
fcx
.write_ty
(
id
,
fcx
.tcx
()
.types.err
);
}
}
}
}
}
}
}
...
...
@@ -4387,7 +4258,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
};
// Note that we don't check the type of start/end satisfy any
// bounds because right the range structs do not have any. If we add
// bounds because right
now
the range structs do not have any. If we add
// some bounds, then we'll need to check `t_start` against them here.
let
range_type
=
match
idx_type
{
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
e970db37
...
...
@@ -63,7 +63,7 @@
use
ast
::{
Visibility
,
WhereClause
};
use
ast
;
use
ast_util
::{
self
,
as_prec
,
ident_to_path
,
operator_prec
};
use
codemap
::{
self
,
Span
,
BytePos
,
Spanned
,
spanned
,
mk_sp
,
DUMMY_SP
};
use
codemap
::{
self
,
Span
,
BytePos
,
Spanned
,
spanned
,
mk_sp
};
use
diagnostic
;
use
ext
::
tt
::
macro_parser
;
use
parse
;
...
...
@@ -2103,22 +2103,6 @@ pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::Expr_ {
ExprIndex
(
expr
,
idx
)
}
pub
fn
mk_slice
(
&
mut
self
,
expr
:
P
<
Expr
>
,
start
:
Option
<
P
<
Expr
>>
,
end
:
Option
<
P
<
Expr
>>
,
_
mutbl
:
Mutability
)
->
ast
::
Expr_
{
// FIXME: we could give more accurate span info here.
let
(
lo
,
hi
)
=
match
(
&
start
,
&
end
)
{
(
&
Some
(
ref
s
),
&
Some
(
ref
e
))
=>
(
s
.span.lo
,
e
.span.hi
),
(
&
Some
(
ref
s
),
&
None
)
=>
(
s
.span.lo
,
s
.span.hi
),
(
&
None
,
&
Some
(
ref
e
))
=>
(
e
.span.lo
,
e
.span.hi
),
(
&
None
,
&
None
)
=>
(
DUMMY_SP
.lo
,
DUMMY_SP
.hi
),
};
ExprIndex
(
expr
,
self
.mk_expr
(
lo
,
hi
,
ExprRange
(
start
,
end
)))
}
pub
fn
mk_range
(
&
mut
self
,
start
:
Option
<
P
<
Expr
>>
,
end
:
Option
<
P
<
Expr
>>
)
...
...
@@ -2550,87 +2534,28 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
}
// expr[...]
// Could be either an index expression or a slicing expression.
// Any slicing non-terminal can have a mutable version with `mut`
// after the opening square bracket.
// An index expression.
token
::
OpenDelim
(
token
::
Bracket
)
=>
{
let
bracket_pos
=
self
.span.lo
;
self
.bump
();
let
mutbl
=
if
self
.eat_keyword
(
keywords
::
Mut
)
{
MutMutable
if
self
.eat
(
&
token
::
CloseDelim
(
token
::
Bracket
))
{
// No expression, expand to a FullRange
let
ix
=
{
hi
=
self
.last_span.hi
;
let
range
=
ExprStruct
(
ident_to_path
(
mk_sp
(
lo
,
hi
),
token
::
special_idents
::
FullRange
),
vec!
[],
None
);
self
.mk_expr
(
bracket_pos
,
hi
,
range
)
};
let
index
=
self
.mk_index
(
e
,
ix
);
e
=
self
.mk_expr
(
lo
,
hi
,
index
)
}
else
{
MutImmutable
};
match
self
.token
{
// e.index(&FullRange)
token
::
CloseDelim
(
token
::
Bracket
)
=>
{
self
.bump
();
hi
=
self
.span.hi
;
let
slice
=
self
.mk_slice
(
e
,
None
,
None
,
mutbl
);
e
=
self
.mk_expr
(
lo
,
hi
,
slice
)
}
// e.index(&(0..e))
token
::
DotDot
=>
{
self
.bump
();
match
self
.token
{
// e.index(&(..))
token
::
CloseDelim
(
token
::
Bracket
)
=>
{
self
.bump
();
hi
=
self
.span.hi
;
let
slice
=
self
.mk_slice
(
e
,
None
,
None
,
mutbl
);
e
=
self
.mk_expr
(
lo
,
hi
,
slice
);
self
.span_err
(
e
.span
,
"incorrect slicing expression: `[..]`"
);
self
.span_note
(
e
.span
,
"use `expr.index(&FullRange)` to construct a slice of the whole of expr"
);
}
// e.index(&(0..e))
_
=>
{
hi
=
self
.span.hi
;
let
e2
=
self
.parse_expr
();
self
.commit_expr_expecting
(
&*
e2
,
token
::
CloseDelim
(
token
::
Bracket
));
let
slice
=
self
.mk_slice
(
e
,
None
,
Some
(
e2
),
mutbl
);
e
=
self
.mk_expr
(
lo
,
hi
,
slice
)
}
}
}
// e[e] | e.index(&(e..)) | e.index(&(e..e))
_
=>
{
let
ix
=
self
.parse_expr_res
(
RESTRICTION_NO_DOTS
);
match
self
.token
{
// e.index(&(e..)) | e.index(&(e..e))
token
::
DotDot
=>
{
self
.bump
();
let
e2
=
match
self
.token
{
// e.index(&(e..))
token
::
CloseDelim
(
token
::
Bracket
)
=>
{
self
.bump
();
None
}
// e.index(&(e..e))
_
=>
{
let
e2
=
self
.parse_expr_res
(
RESTRICTION_NO_DOTS
);
self
.commit_expr_expecting
(
&*
e2
,
token
::
CloseDelim
(
token
::
Bracket
));
Some
(
e2
)
}
};
hi
=
self
.span.hi
;
let
slice
=
self
.mk_slice
(
e
,
Some
(
ix
),
e2
,
mutbl
);
e
=
self
.mk_expr
(
lo
,
hi
,
slice
)
}
// e[e]
_
=>
{
if
mutbl
==
ast
::
MutMutable
{
self
.span_err
(
e
.span
,
"`mut` keyword is invalid in index expressions"
);
}
hi
=
self
.span.hi
;
self
.commit_expr_expecting
(
&*
ix
,
token
::
CloseDelim
(
token
::
Bracket
));
let
index
=
self
.mk_index
(
e
,
ix
);
e
=
self
.mk_expr
(
lo
,
hi
,
index
)
}
}
}
let
ix
=
self
.parse_expr
();
hi
=
self
.span.hi
;
self
.commit_expr_expecting
(
&*
ix
,
token
::
CloseDelim
(
token
::
Bracket
));
let
index
=
self
.mk_index
(
e
,
ix
);
e
=
self
.mk_expr
(
lo
,
hi
,
index
)
}
}
...
...
src/libsyntax/parse/token.rs
浏览文件 @
e970db37
...
...
@@ -515,66 +515,66 @@ pub mod special_idents {
(
9
,
unnamed_field
,
"<unnamed_field>"
);
(
10
,
type_self
,
"Self"
);
(
11
,
prelude_import
,
"prelude_import"
);
(
12
,
FullRange
,
"FullRange"
);
}
pub
mod
keywords
{
// These ones are variants of the Keyword enum
'strict
:
(
1
2
,
As
,
"as"
);
(
1
3
,
Break
,
"break"
);
(
1
4
,
Crate
,
"crate"
);
(
1
5
,
Else
,
"else"
);
(
1
6
,
Enum
,
"enum"
);
(
1
7
,
Extern
,
"extern"
);
(
1
8
,
False
,
"false"
);
(
19
,
Fn
,
"fn"
);
(
2
0
,
For
,
"for"
);
(
2
1
,
If
,
"if"
);
(
2
2
,
Impl
,
"impl"
);
(
2
3
,
In
,
"in"
);
(
2
4
,
Let
,
"let"
);
(
2
5
,
Loop
,
"loop"
);
(
2
6
,
Match
,
"match"
);
(
2
7
,
Mod
,
"mod"
);
(
2
8
,
Move
,
"move"
);
(
29
,
Mut
,
"mut"
);
(
3
0
,
Pub
,
"pub"
);
(
3
1
,
Ref
,
"ref"
);
(
3
2
,
Return
,
"return"
);
(
1
3
,
As
,
"as"
);
(
1
4
,
Break
,
"break"
);
(
1
5
,
Crate
,
"crate"
);
(
1
6
,
Else
,
"else"
);
(
1
7
,
Enum
,
"enum"
);
(
1
8
,
Extern
,
"extern"
);
(
1
9
,
False
,
"false"
);
(
20
,
Fn
,
"fn"
);
(
2
1
,
For
,
"for"
);
(
2
2
,
If
,
"if"
);
(
2
3
,
Impl
,
"impl"
);
(
2
4
,
In
,
"in"
);
(
2
5
,
Let
,
"let"
);
(
2
6
,
Loop
,
"loop"
);
(
2
7
,
Match
,
"match"
);
(
2
8
,
Mod
,
"mod"
);
(
2
9
,
Move
,
"move"
);
(
30
,
Mut
,
"mut"
);
(
3
1
,
Pub
,
"pub"
);
(
3
2
,
Ref
,
"ref"
);
(
3
3
,
Return
,
"return"
);
// Static and Self are also special idents (prefill de-dupes)
(
super
::
STATIC_KEYWORD_NAME_NUM
,
Static
,
"static"
);
(
super
::
SELF_KEYWORD_NAME_NUM
,
Self
,
"self"
);
(
3
3
,
Struct
,
"struct"
);
(
3
4
,
Struct
,
"struct"
);
(
super
::
SUPER_KEYWORD_NAME_NUM
,
Super
,
"super"
);
(
34
,
True
,
"true"
);
(
35
,
Trait
,
"trait"
);
(
36
,
Type
,
"type"
);
(
37
,
Unsafe
,
"unsafe"
);
(
38
,
Use
,
"use"
);
(
39
,
Virtual
,
"virtual"
);
(
40
,
While
,
"while"
);
(
41
,
Continue
,
"continue"
);
(
42
,
Proc
,
"proc"
);
(
43
,
Box
,
"box"
);
(
44
,
Const
,
"const"
);
(
45
,
Where
,
"where"
);
(
35
,
True
,
"true"
);
(
36
,
Trait
,
"trait"
);
(
37
,
Type
,
"type"
);
(
38
,
Unsafe
,
"unsafe"
);
(
39
,
Use
,
"use"
);
(
40
,
Virtual
,
"virtual"
);
(
41
,
While
,
"while"
);
(
42
,
Continue
,
"continue"
);
(
43
,
Proc
,
"proc"
);
(
44
,
Box
,
"box"
);
(
45
,
Const
,
"const"
);
(
46
,
Where
,
"where"
);
'reserved
:
(
4
6
,
Alignof
,
"alignof"
);
(
4
7
,
Be
,
"be"
);
(
4
8
,
Offsetof
,
"offsetof"
);
(
49
,
Priv
,
"priv"
);
(
5
0
,
Pure
,
"pure"
);
(
5
1
,
Sizeof
,
"sizeof"
);
(
5
2
,
Typeof
,
"typeof"
);
(
5
3
,
Unsized
,
"unsized"
);
(
5
4
,
Yield
,
"yield"
);
(
5
5
,
Do
,
"do"
);
(
5
6
,
Abstract
,
"abstract"
);
(
5
7
,
Final
,
"final"
);
(
5
8
,
Override
,
"override"
);
(
59
,
Macro
,
"macro"
);
(
4
7
,
Alignof
,
"alignof"
);
(
4
8
,
Be
,
"be"
);
(
4
9
,
Offsetof
,
"offsetof"
);
(
50
,
Priv
,
"priv"
);
(
5
1
,
Pure
,
"pure"
);
(
5
2
,
Sizeof
,
"sizeof"
);
(
5
3
,
Typeof
,
"typeof"
);
(
5
4
,
Unsized
,
"unsized"
);
(
5
5
,
Yield
,
"yield"
);
(
5
6
,
Do
,
"do"
);
(
5
7
,
Abstract
,
"abstract"
);
(
5
8
,
Final
,
"final"
);
(
5
9
,
Override
,
"override"
);
(
60
,
Macro
,
"macro"
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录