Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
406fe7e3
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,发现更多精彩内容 >>
提交
406fe7e3
编写于
9月 30, 2016
作者:
M
Manish Goregaokar
浏览文件
操作
浏览文件
下载
差异文件
Rollup merge of #34764 - pnkfelix:attrs-on-generic-formals, r=eddyb
First step for #34761
上级
259d1fcd
3a9b7be1
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
389 addition
and
14 deletion
+389
-14
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+2
-0
src/libsyntax/ext/build.rs
src/libsyntax/ext/build.rs
+6
-0
src/libsyntax/feature_gate.rs
src/libsyntax/feature_gate.rs
+21
-0
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+11
-1
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+53
-9
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+2
-0
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/mod.rs
+1
-1
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/deriving/generic/ty.rs
+4
-3
src/test/compile-fail/attr-on-generic-formals-are-visited.rs
src/test/compile-fail/attr-on-generic-formals-are-visited.rs
+75
-0
src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs
...t/compile-fail/attr-on-generic-formals-wo-feature-gate.rs
+76
-0
src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs
src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs
+26
-0
src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs
src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs
+26
-0
src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs
src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs
+26
-0
src/test/run-pass/attr-on-generic-formals.rs
src/test/run-pass/attr-on-generic-formals.rs
+60
-0
未找到文件。
src/libsyntax/ast.rs
浏览文件 @
406fe7e3
...
...
@@ -121,6 +121,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// A lifetime definition, e.g. `'a: 'b+'c+'d`
#[derive(Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Debug)]
pub
struct
LifetimeDef
{
pub
attrs
:
ThinVec
<
Attribute
>
,
pub
lifetime
:
Lifetime
,
pub
bounds
:
Vec
<
Lifetime
>
}
...
...
@@ -370,6 +371,7 @@ pub enum TraitBoundModifier {
#[derive(Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Debug)]
pub
struct
TyParam
{
pub
attrs
:
ThinVec
<
Attribute
>
,
pub
ident
:
Ident
,
pub
id
:
NodeId
,
pub
bounds
:
TyParamBounds
,
...
...
src/libsyntax/ext/build.rs
浏览文件 @
406fe7e3
...
...
@@ -73,6 +73,7 @@ fn ty_ptr(&self, span: Span,
fn
typaram
(
&
self
,
span
:
Span
,
id
:
ast
::
Ident
,
attrs
:
Vec
<
ast
::
Attribute
>
,
bounds
:
ast
::
TyParamBounds
,
default
:
Option
<
P
<
ast
::
Ty
>>
)
->
ast
::
TyParam
;
...
...
@@ -83,6 +84,7 @@ fn typaram(&self,
fn
lifetime_def
(
&
self
,
span
:
Span
,
name
:
ast
::
Name
,
attrs
:
Vec
<
ast
::
Attribute
>
,
bounds
:
Vec
<
ast
::
Lifetime
>
)
->
ast
::
LifetimeDef
;
...
...
@@ -452,11 +454,13 @@ fn ty_infer(&self, span: Span) -> P<ast::Ty> {
fn
typaram
(
&
self
,
span
:
Span
,
id
:
ast
::
Ident
,
attrs
:
Vec
<
ast
::
Attribute
>
,
bounds
:
ast
::
TyParamBounds
,
default
:
Option
<
P
<
ast
::
Ty
>>
)
->
ast
::
TyParam
{
ast
::
TyParam
{
ident
:
id
,
id
:
ast
::
DUMMY_NODE_ID
,
attrs
:
attrs
.into
(),
bounds
:
bounds
,
default
:
default
,
span
:
span
...
...
@@ -503,9 +507,11 @@ fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
fn
lifetime_def
(
&
self
,
span
:
Span
,
name
:
ast
::
Name
,
attrs
:
Vec
<
ast
::
Attribute
>
,
bounds
:
Vec
<
ast
::
Lifetime
>
)
->
ast
::
LifetimeDef
{
ast
::
LifetimeDef
{
attrs
:
attrs
.into
(),
lifetime
:
self
.lifetime
(
span
,
name
),
bounds
:
bounds
}
...
...
src/libsyntax/feature_gate.rs
浏览文件 @
406fe7e3
...
...
@@ -303,6 +303,9 @@ pub fn new() -> Features {
// Used to identify the `compiler_builtins` crate
// rustc internal
(
active
,
compiler_builtins
,
"1.13.0"
,
None
),
// Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
(
active
,
generic_param_attrs
,
"1.11.0"
,
Some
(
34761
)),
);
declare_features!
(
...
...
@@ -1220,6 +1223,24 @@ fn visit_vis(&mut self, vis: &ast::Visibility) {
visit
::
walk_vis
(
self
,
vis
)
}
fn
visit_generics
(
&
mut
self
,
g
:
&
ast
::
Generics
)
{
for
t
in
&
g
.ty_params
{
if
!
t
.attrs
.is_empty
()
{
gate_feature_post!
(
&
self
,
generic_param_attrs
,
t
.attrs
[
0
]
.span
,
"attributes on type parameter bindings are experimental"
);
}
}
visit
::
walk_generics
(
self
,
g
)
}
fn
visit_lifetime_def
(
&
mut
self
,
lifetime_def
:
&
ast
::
LifetimeDef
)
{
if
!
lifetime_def
.attrs
.is_empty
()
{
gate_feature_post!
(
&
self
,
generic_param_attrs
,
lifetime_def
.attrs
[
0
]
.span
,
"attributes on lifetime bindings are experimental"
);
}
visit
::
walk_lifetime_def
(
self
,
lifetime_def
)
}
}
pub
fn
get_features
(
span_handler
:
&
Handler
,
krate_attrs
:
&
[
ast
::
Attribute
])
->
Features
{
...
...
src/libsyntax/fold.rs
浏览文件 @
406fe7e3
...
...
@@ -662,8 +662,13 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
}
pub
fn
noop_fold_ty_param
<
T
:
Folder
>
(
tp
:
TyParam
,
fld
:
&
mut
T
)
->
TyParam
{
let
TyParam
{
id
,
ident
,
bounds
,
default
,
span
}
=
tp
;
let
TyParam
{
attrs
,
id
,
ident
,
bounds
,
default
,
span
}
=
tp
;
let
attrs
:
Vec
<
_
>
=
attrs
.into
();
TyParam
{
attrs
:
attrs
.into_iter
()
.flat_map
(|
x
|
fld
.fold_attribute
(
x
)
.into_iter
())
.collect
::
<
Vec
<
_
>>
()
.into
(),
id
:
fld
.new_id
(
id
),
ident
:
ident
,
bounds
:
fld
.fold_bounds
(
bounds
),
...
...
@@ -687,7 +692,12 @@ pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
pub
fn
noop_fold_lifetime_def
<
T
:
Folder
>
(
l
:
LifetimeDef
,
fld
:
&
mut
T
)
->
LifetimeDef
{
let
attrs
:
Vec
<
_
>
=
l
.attrs
.into
();
LifetimeDef
{
attrs
:
attrs
.into_iter
()
.flat_map
(|
x
|
fld
.fold_attribute
(
x
)
.into_iter
())
.collect
::
<
Vec
<
_
>>
()
.into
(),
lifetime
:
fld
.fold_lifetime
(
l
.lifetime
),
bounds
:
fld
.fold_lifetimes
(
l
.bounds
),
}
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
406fe7e3
...
...
@@ -1179,7 +1179,7 @@ pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
let
lo
=
self
.span.lo
;
let
(
name
,
node
)
=
if
self
.eat_keyword
(
keywords
::
Type
)
{
let
TyParam
{
ident
,
bounds
,
default
,
..
}
=
self
.parse_ty_param
()
?
;
let
TyParam
{
ident
,
bounds
,
default
,
..
}
=
self
.parse_ty_param
(
vec!
[]
)
?
;
self
.expect
(
&
token
::
Semi
)
?
;
(
ident
,
TraitItemKind
::
Type
(
bounds
,
default
))
}
else
if
self
.is_const_item
()
{
...
...
@@ -1910,10 +1910,22 @@ pub fn parse_lifetime(&mut self) -> PResult<'a, ast::Lifetime> {
/// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def =
/// lifetime [':' lifetimes]`
pub
fn
parse_lifetime_defs
(
&
mut
self
)
->
PResult
<
'a
,
Vec
<
ast
::
LifetimeDef
>>
{
///
/// If `followed_by_ty_params` is None, then we are in a context
/// where only lifetime parameters are allowed, and thus we should
/// error if we encounter attributes after the bound lifetimes.
///
/// If `followed_by_ty_params` is Some(r), then there may be type
/// parameter bindings after the lifetimes, so we should pass
/// along the parsed attributes to be attached to the first such
/// type parmeter.
pub
fn
parse_lifetime_defs
(
&
mut
self
,
followed_by_ty_params
:
Option
<&
mut
Vec
<
ast
::
Attribute
>>
)
->
PResult
<
'a
,
Vec
<
ast
::
LifetimeDef
>>
{
let
mut
res
=
Vec
::
new
();
loop
{
let
attrs
=
self
.parse_outer_attributes
()
?
;
match
self
.token
{
token
::
Lifetime
(
_
)
=>
{
let
lifetime
=
self
.parse_lifetime
()
?
;
...
...
@@ -1923,11 +1935,20 @@ pub fn parse_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
}
else
{
Vec
::
new
()
};
res
.push
(
ast
::
LifetimeDef
{
lifetime
:
lifetime
,
res
.push
(
ast
::
LifetimeDef
{
attrs
:
attrs
.into
(),
lifetime
:
lifetime
,
bounds
:
bounds
});
}
_
=>
{
if
let
Some
(
recv
)
=
followed_by_ty_params
{
assert
!
(
recv
.is_empty
());
*
recv
=
attrs
;
}
else
{
let
msg
=
"trailing attribute after lifetime parameters"
;
return
Err
(
self
.fatal
(
msg
));
}
debug!
(
"parse_lifetime_defs ret {:?}"
,
res
);
return
Ok
(
res
);
}
}
...
...
@@ -4228,7 +4249,7 @@ fn parse_ty_param_bounds(&mut self,
}
/// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
fn
parse_ty_param
(
&
mut
self
)
->
PResult
<
'a
,
TyParam
>
{
fn
parse_ty_param
(
&
mut
self
,
preceding_attrs
:
Vec
<
ast
::
Attribute
>
)
->
PResult
<
'a
,
TyParam
>
{
let
span
=
self
.span
;
let
ident
=
self
.parse_ident
()
?
;
...
...
@@ -4242,6 +4263,7 @@ fn parse_ty_param(&mut self) -> PResult<'a, TyParam> {
};
Ok
(
TyParam
{
attrs
:
preceding_attrs
.into
(),
ident
:
ident
,
id
:
ast
::
DUMMY_NODE_ID
,
bounds
:
bounds
,
...
...
@@ -4262,11 +4284,27 @@ pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
let
span_lo
=
self
.span.lo
;
if
self
.eat
(
&
token
::
Lt
)
{
let
lifetime_defs
=
self
.parse_lifetime_defs
()
?
;
// Upon encountering attribute in generics list, we do not
// know if it is attached to lifetime or to type param.
//
// Solution: 1. eagerly parse attributes in tandem with
// lifetime defs, 2. store last set of parsed (and unused)
// attributes in `attrs`, and 3. pass in those attributes
// when parsing formal type param after lifetime defs.
let
mut
attrs
=
vec!
[];
let
lifetime_defs
=
self
.parse_lifetime_defs
(
Some
(
&
mut
attrs
))
?
;
let
mut
seen_default
=
false
;
let
mut
post_lifetime_attrs
=
Some
(
attrs
);
let
ty_params
=
self
.parse_seq_to_gt
(
Some
(
token
::
Comma
),
|
p
|
{
p
.forbid_lifetime
()
?
;
let
ty_param
=
p
.parse_ty_param
()
?
;
// Move out of `post_lifetime_attrs` if present. O/w
// not first type param: parse attributes anew.
let
attrs
=
match
post_lifetime_attrs
.as_mut
()
{
None
=>
p
.parse_outer_attributes
()
?
,
Some
(
attrs
)
=>
mem
::
replace
(
attrs
,
vec!
[]),
};
post_lifetime_attrs
=
None
;
let
ty_param
=
p
.parse_ty_param
(
attrs
)
?
;
if
ty_param
.default
.is_some
()
{
seen_default
=
true
;
}
else
if
seen_default
{
...
...
@@ -4276,6 +4314,12 @@ pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
}
Ok
(
ty_param
)
})
?
;
if
let
Some
(
attrs
)
=
post_lifetime_attrs
{
if
!
attrs
.is_empty
()
{
self
.span_err
(
attrs
[
0
]
.span
,
"trailing attribute after lifetime parameters"
);
}
}
Ok
(
ast
::
Generics
{
lifetimes
:
lifetime_defs
,
ty_params
:
ty_params
,
...
...
@@ -4423,7 +4467,7 @@ pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> {
let
bound_lifetimes
=
if
self
.eat_keyword
(
keywords
::
For
)
{
// Higher ranked constraint.
self
.expect
(
&
token
::
Lt
)
?
;
let
lifetime_defs
=
self
.parse_lifetime_defs
()
?
;
let
lifetime_defs
=
self
.parse_lifetime_defs
(
None
)
?
;
self
.expect_gt
()
?
;
lifetime_defs
}
else
{
...
...
@@ -4991,7 +5035,7 @@ fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> {
fn
parse_late_bound_lifetime_defs
(
&
mut
self
)
->
PResult
<
'a
,
Vec
<
ast
::
LifetimeDef
>>
{
if
self
.eat_keyword
(
keywords
::
For
)
{
self
.expect
(
&
token
::
Lt
)
?
;
let
lifetime_defs
=
self
.parse_lifetime_defs
()
?
;
let
lifetime_defs
=
self
.parse_lifetime_defs
(
None
)
?
;
self
.expect_gt
()
?
;
Ok
(
lifetime_defs
)
}
else
{
...
...
src/libsyntax/visit.rs
浏览文件 @
406fe7e3
...
...
@@ -201,6 +201,7 @@ pub fn walk_lifetime<V: Visitor>(visitor: &mut V, lifetime: &Lifetime) {
pub
fn
walk_lifetime_def
<
V
:
Visitor
>
(
visitor
:
&
mut
V
,
lifetime_def
:
&
LifetimeDef
)
{
visitor
.visit_lifetime
(
&
lifetime_def
.lifetime
);
walk_list!
(
visitor
,
visit_lifetime
,
&
lifetime_def
.bounds
);
walk_list!
(
visitor
,
visit_attribute
,
&*
lifetime_def
.attrs
);
}
pub
fn
walk_poly_trait_ref
<
V
>
(
visitor
:
&
mut
V
,
trait_ref
:
&
PolyTraitRef
,
_
:
&
TraitBoundModifier
)
...
...
@@ -474,6 +475,7 @@ pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
visitor
.visit_ident
(
param
.span
,
param
.ident
);
walk_list!
(
visitor
,
visit_ty_param_bound
,
&
param
.bounds
);
walk_list!
(
visitor
,
visit_ty
,
&
param
.default
);
walk_list!
(
visitor
,
visit_attribute
,
&*
param
.attrs
);
}
walk_list!
(
visitor
,
visit_lifetime_def
,
&
generics
.lifetimes
);
for
predicate
in
&
generics
.where_clause.predicates
{
...
...
src/libsyntax_ext/deriving/generic/mod.rs
浏览文件 @
406fe7e3
...
...
@@ -536,7 +536,7 @@ fn create_derived_impl(&self,
bounds
.push
((
*
declared_bound
)
.clone
());
}
cx
.typaram
(
self
.span
,
ty_param
.ident
,
P
::
from_vec
(
bounds
),
None
)
cx
.typaram
(
self
.span
,
ty_param
.ident
,
vec!
[],
P
::
from_vec
(
bounds
),
None
)
}));
// and similarly for where clauses
...
...
src/libsyntax_ext/deriving/generic/ty.rs
浏览文件 @
406fe7e3
...
...
@@ -194,6 +194,7 @@ pub fn to_path(&self,
fn
mk_ty_param
(
cx
:
&
ExtCtxt
,
span
:
Span
,
name
:
&
str
,
attrs
:
&
[
ast
::
Attribute
],
bounds
:
&
[
Path
],
self_ident
:
Ident
,
self_generics
:
&
Generics
)
...
...
@@ -204,7 +205,7 @@ fn mk_ty_param(cx: &ExtCtxt,
cx
.typarambound
(
path
)
})
.collect
();
cx
.typaram
(
span
,
cx
.ident_of
(
name
),
bounds
,
None
)
cx
.typaram
(
span
,
cx
.ident_of
(
name
),
attrs
.to_owned
(),
bounds
,
None
)
}
fn
mk_generics
(
lifetimes
:
Vec
<
ast
::
LifetimeDef
>
,
ty_params
:
Vec
<
ast
::
TyParam
>
,
span
:
Span
)
...
...
@@ -246,7 +247,7 @@ pub fn to_generics(&self,
let
bounds
=
bounds
.iter
()
.map
(|
b
|
cx
.lifetime
(
span
,
cx
.ident_of
(
*
b
)
.name
))
.collect
();
cx
.lifetime_def
(
span
,
cx
.ident_of
(
*
lt
)
.name
,
bounds
)
cx
.lifetime_def
(
span
,
cx
.ident_of
(
*
lt
)
.name
,
vec!
[],
bounds
)
})
.collect
();
let
ty_params
=
self
.bounds
...
...
@@ -254,7 +255,7 @@ pub fn to_generics(&self,
.map
(|
t
|
{
match
*
t
{
(
ref
name
,
ref
bounds
)
=>
{
mk_ty_param
(
cx
,
span
,
*
name
,
bounds
,
self_ty
,
self_generics
)
mk_ty_param
(
cx
,
span
,
*
name
,
&
[],
bounds
,
self_ty
,
self_generics
)
}
}
})
...
...
src/test/compile-fail/attr-on-generic-formals-are-visited.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test ensures that attributes on formals in generic parameter
// lists are included when we are checking for unstable attributes.
//
// Note that feature(generic_param_attrs) *is* enabled here. We are
// checking feature-gating of the attributes themselves, not the
// capability to parse such attributes in that context.
#![feature(generic_param_attrs)]
#![allow(dead_code)]
struct
StLt
<
#[lt_struct]
'a
>
(
&
'a
u32
);
//~^ ERROR The attribute `lt_struct` is currently unknown to the compiler
struct
StTy
<
#[ty_struct]
I
>
(
I
);
//~^ ERROR The attribute `ty_struct` is currently unknown to the compiler
enum
EnLt
<
#[lt_enum]
'b
>
{
A
(
&
'b
u32
),
B
}
//~^ ERROR The attribute `lt_enum` is currently unknown to the compiler
enum
EnTy
<
#[ty_enum]
J
>
{
A
(
J
),
B
}
//~^ ERROR The attribute `ty_enum` is currently unknown to the compiler
trait
TrLt
<
#[lt_trait]
'c
>
{
fn
foo
(
&
self
,
_
:
&
'c
[
u32
])
->
&
'c
u32
;
}
//~^ ERROR The attribute `lt_trait` is currently unknown to the compiler
trait
TrTy
<
#[ty_trait]
K
>
{
fn
foo
(
&
self
,
_
:
K
);
}
//~^ ERROR The attribute `ty_trait` is currently unknown to the compiler
type
TyLt
<
#[lt_type]
'd
>
=
&
'd
u32
;
//~^ ERROR The attribute `lt_type` is currently unknown to the compiler
type
TyTy
<
#[ty_type]
L
>
=
(
L
,
);
//~^ ERROR The attribute `ty_type` is currently unknown to the compiler
impl
<
#[lt_inherent]
'e
>
StLt
<
'e
>
{
}
//~^ ERROR The attribute `lt_inherent` is currently unknown to the compiler
impl
<
#[ty_inherent]
M
>
StTy
<
M
>
{
}
//~^ ERROR The attribute `ty_inherent` is currently unknown to the compiler
impl
<
#[lt_impl_for]
'f
>
TrLt
<
'f
>
for
StLt
<
'f
>
{
//~^ ERROR The attribute `lt_impl_for` is currently unknown to the compiler
fn
foo
(
&
self
,
_
:
&
'f
[
u32
])
->
&
'f
u32
{
loop
{
}
}
}
impl
<
#[ty_impl_for]
N
>
TrTy
<
N
>
for
StTy
<
N
>
{
//~^ ERROR The attribute `ty_impl_for` is currently unknown to the compiler
fn
foo
(
&
self
,
_
:
N
)
{
}
}
fn
f_lt
<
#[lt_fn]
'g
>
(
_
:
&
'g
[
u32
])
->
&
'g
u32
{
loop
{
}
}
//~^ ERROR The attribute `lt_fn` is currently unknown to the compiler
fn
f_ty
<
#[ty_fn]
O
>
(
_
:
O
)
{
}
//~^ ERROR The attribute `ty_fn` is currently unknown to the compiler
impl
<
I
>
StTy
<
I
>
{
fn
m_lt
<
#[lt_meth]
'h
>
(
_
:
&
'h
[
u32
])
->
&
'h
u32
{
loop
{
}
}
//~^ ERROR The attribute `lt_meth` is currently unknown to the compiler
fn
m_ty
<
#[ty_meth]
P
>
(
_
:
P
)
{
}
//~^ ERROR The attribute `ty_meth` is currently unknown to the compiler
}
fn
hof_lt
<
Q
>
(
_
:
Q
)
where
Q
:
for
<
#[lt_hof]
'i
>
Fn
(
&
'i
[
u32
])
->
&
'i
u32
//~^ ERROR The attribute `lt_hof` is currently unknown to the compiler
{
}
fn
main
()
{
}
src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test ensures that attributes on formals in generic parameter
// lists are rejected if feature(generic_param_attrs) is not enabled.
//
// (We are prefixing all tested features with `rustc_`, to ensure that
// the attributes themselves won't be rejected by the compiler when
// using `rustc_attrs` feature. There is a separate compile-fail/ test
// ensuring that the attribute feature-gating works in this context.)
#![feature(rustc_attrs)]
#![allow(dead_code)]
struct
StLt
<
#[rustc_lt_struct]
'a
>
(
&
'a
u32
);
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
struct
StTy
<
#[rustc_ty_struct]
I
>
(
I
);
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
enum
EnLt
<
#[rustc_lt_enum]
'b
>
{
A
(
&
'b
u32
),
B
}
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
enum
EnTy
<
#[rustc_ty_enum]
J
>
{
A
(
J
),
B
}
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
trait
TrLt
<
#[rustc_lt_trait]
'c
>
{
fn
foo
(
&
self
,
_
:
&
'c
[
u32
])
->
&
'c
u32
;
}
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
trait
TrTy
<
#[rustc_ty_trait]
K
>
{
fn
foo
(
&
self
,
_
:
K
);
}
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
type
TyLt
<
#[rustc_lt_type]
'd
>
=
&
'd
u32
;
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
type
TyTy
<
#[rustc_ty_type]
L
>
=
(
L
,
);
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
impl
<
#[rustc_lt_inherent]
'e
>
StLt
<
'e
>
{
}
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
impl
<
#[rustc_ty_inherent]
M
>
StTy
<
M
>
{
}
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
impl
<
#[rustc_lt_impl_for]
'f
>
TrLt
<
'f
>
for
StLt
<
'f
>
{
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
fn
foo
(
&
self
,
_
:
&
'f
[
u32
])
->
&
'f
u32
{
loop
{
}
}
}
impl
<
#[rustc_ty_impl_for]
N
>
TrTy
<
N
>
for
StTy
<
N
>
{
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
fn
foo
(
&
self
,
_
:
N
)
{
}
}
fn
f_lt
<
#[rustc_lt_fn]
'g
>
(
_
:
&
'g
[
u32
])
->
&
'g
u32
{
loop
{
}
}
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
fn
f_ty
<
#[rustc_ty_fn]
O
>
(
_
:
O
)
{
}
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
impl
<
I
>
StTy
<
I
>
{
fn
m_lt
<
#[rustc_lt_meth]
'h
>
(
_
:
&
'h
[
u32
])
->
&
'h
u32
{
loop
{
}
}
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
fn
m_ty
<
#[rustc_ty_meth]
P
>
(
_
:
P
)
{
}
//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
}
fn
hof_lt
<
Q
>
(
_
:
Q
)
where
Q
:
for
<
#[rustc_lt_hof]
'i
>
Fn
(
&
'i
[
u32
])
->
&
'i
u32
//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
{
}
fn
main
()
{
}
src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test checks variations on `<#[attr] 'a, #[oops]>`, where
// `#[oops]` is left dangling (that is, it is unattached, with no
// formal binding following it).
#![feature(generic_param_attrs,
rustc_attrs)]
#![allow(dead_code)]
struct
RefIntPair
<
'a
,
'b
>
(
&
'a
u32
,
&
'b
u32
);
impl
<
#[rustc_1]
'a
,
'b
,
#[oops]
>
RefIntPair
<
'a
,
'b
>
{
//~^ ERROR trailing attribute after lifetime parameters
}
fn
main
()
{
}
src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test checks variations on `<#[attr] 'a, #[oops]>`, where
// `#[oops]` is left dangling (that is, it is unattached, with no
// formal binding following it).
#![feature(generic_param_attrs,
rustc_attrs)]
#![allow(dead_code)]
struct
RefAny
<
'a
,
T
>
(
&
'a
T
);
impl
<
#[rustc_1]
'a
,
#[rustc_2]
T
,
#[oops]
>
RefAny
<
'a
,
T
>
{
//~^ ERROR expected identifier, found `>`
}
fn
main
()
{
}
src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test checks variations on `<#[attr] 'a, #[oops]>`, where
// `#[oops]` is left dangling (that is, it is unattached, with no
// formal binding following it).
struct
RefIntPair
<
'a
,
'b
>
(
&
'a
u32
,
&
'b
u32
);
fn
hof_lt
<
Q
>
(
_
:
Q
)
where
Q
:
for
<
#[rustc_1]
'a
,
'b
,
#[oops]
>
Fn
(
RefIntPair
<
'a
,
'b
>
)
->
&
'b
u32
//~^ ERROR trailing attribute after lifetime parameters
{
}
fn
main
()
{
}
src/test/run-pass/attr-on-generic-formals.rs
0 → 100644
浏览文件 @
406fe7e3
// Copyright 2016 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.
// This test ensures we can attach attributes to the formals in all
// places where generic parameter lists occur, assuming appropriate
// feature gates are enabled.
//
// (We are prefixing all tested features with `rustc_`, to ensure that
// the attributes themselves won't be rejected by the compiler when
// using `rustc_attrs` feature. There is a separate compile-fail/ test
// ensuring that the attribute feature-gating works in this context.)
#![feature(generic_param_attrs,
rustc_attrs)]
#![allow(dead_code)]
struct
StLt
<
#[rustc_lt_struct]
'a
>
(
&
'a
u32
);
struct
StTy
<
#[rustc_ty_struct]
I
>
(
I
);
enum
EnLt
<
#[rustc_lt_enum]
'b
>
{
A
(
&
'b
u32
),
B
}
enum
EnTy
<
#[rustc_ty_enum]
J
>
{
A
(
J
),
B
}
trait
TrLt
<
#[rustc_lt_trait]
'c
>
{
fn
foo
(
&
self
,
_
:
&
'c
[
u32
])
->
&
'c
u32
;
}
trait
TrTy
<
#[rustc_ty_trait]
K
>
{
fn
foo
(
&
self
,
_
:
K
);
}
type
TyLt
<
#[rustc_lt_type]
'd
>
=
&
'd
u32
;
type
TyTy
<
#[rustc_ty_type]
L
>
=
(
L
,
);
impl
<
#[rustc_lt_inherent]
'e
>
StLt
<
'e
>
{
}
impl
<
#[rustc_ty_inherent]
M
>
StTy
<
M
>
{
}
impl
<
#[rustc_lt_impl_for]
'f
>
TrLt
<
'f
>
for
StLt
<
'f
>
{
fn
foo
(
&
self
,
_
:
&
'f
[
u32
])
->
&
'f
u32
{
loop
{
}
}
}
impl
<
#[rustc_ty_impl_for]
N
>
TrTy
<
N
>
for
StTy
<
N
>
{
fn
foo
(
&
self
,
_
:
N
)
{
}
}
fn
f_lt
<
#[rustc_lt_fn]
'g
>
(
_
:
&
'g
[
u32
])
->
&
'g
u32
{
loop
{
}
}
fn
f_ty
<
#[rustc_ty_fn]
O
>
(
_
:
O
)
{
}
impl
<
I
>
StTy
<
I
>
{
fn
m_lt
<
#[rustc_lt_meth]
'h
>
(
_
:
&
'h
[
u32
])
->
&
'h
u32
{
loop
{
}
}
fn
m_ty
<
#[rustc_ty_meth]
P
>
(
_
:
P
)
{
}
}
fn
hof_lt
<
Q
>
(
_
:
Q
)
where
Q
:
for
<
#[rustc_lt_hof]
'i
>
Fn
(
&
'i
[
u32
])
->
&
'i
u32
{
}
fn
main
()
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录