Improve checking for attribute
This commit is contained in:
parent
22184a0f5d
commit
00afbe70f2
3 changed files with 85 additions and 63 deletions
|
@ -760,7 +760,7 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
target: Target,
|
target: Target,
|
||||||
item: Option<ItemLike<'_>>,
|
item: Option<ItemLike<'_>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let is_function = matches!(target, Target::Fn | Target::Method(..) | Target::ForeignFn);
|
let is_function = matches!(target, Target::Fn | Target::Method(..));
|
||||||
if !is_function {
|
if !is_function {
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
|
@ -776,55 +776,64 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (decl, generics) = match item {
|
||||||
|
Some(ItemLike::Item(Item {
|
||||||
|
kind: ItemKind::Fn(FnSig { decl, .. }, generics, _),
|
||||||
|
..
|
||||||
|
})) => (decl, generics),
|
||||||
|
_ => bug!("should be a function item"),
|
||||||
|
};
|
||||||
|
|
||||||
|
for param in generics.params {
|
||||||
|
match param.kind {
|
||||||
|
hir::GenericParamKind::Const { .. } => {}
|
||||||
|
_ => {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(
|
||||||
|
attr.span,
|
||||||
|
"#[rustc_legacy_const_generics] functions must \
|
||||||
|
only have const generics",
|
||||||
|
)
|
||||||
|
.span_label(param.span, "non-const generic parameter")
|
||||||
|
.emit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if list.len() != generics.params.len() {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(
|
||||||
|
attr.span,
|
||||||
|
"#[rustc_legacy_const_generics] must have one index for each generic parameter",
|
||||||
|
)
|
||||||
|
.span_label(generics.span, "generic parameters")
|
||||||
|
.emit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
|
||||||
let mut invalid_args = vec![];
|
let mut invalid_args = vec![];
|
||||||
for meta in list {
|
for meta in list {
|
||||||
if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
|
if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
|
||||||
if let Some(ItemLike::Item(Item {
|
if *val >= arg_count {
|
||||||
kind: ItemKind::Fn(FnSig { decl, .. }, generics, _),
|
let span = meta.span();
|
||||||
..
|
self.tcx
|
||||||
}))
|
.sess
|
||||||
| Some(ItemLike::ForeignItem(ForeignItem {
|
.struct_span_err(span, "index exceeds number of arguments")
|
||||||
kind: ForeignItemKind::Fn(decl, _, generics),
|
.span_label(
|
||||||
..
|
span,
|
||||||
})) = item
|
format!(
|
||||||
{
|
"there {} only {} argument{}",
|
||||||
let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
|
if arg_count != 1 { "are" } else { "is" },
|
||||||
for param in generics.params {
|
arg_count,
|
||||||
match param.kind {
|
pluralize!(arg_count)
|
||||||
hir::GenericParamKind::Const { .. } => {}
|
),
|
||||||
_ => {
|
)
|
||||||
self.tcx
|
.emit();
|
||||||
.sess
|
return false;
|
||||||
.struct_span_err(
|
|
||||||
meta.span(),
|
|
||||||
"#[rustc_legacy_const_generics] functions must \
|
|
||||||
only have const generics",
|
|
||||||
)
|
|
||||||
.span_label(param.span, "non-const generic parameter")
|
|
||||||
.emit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if *val >= arg_count {
|
|
||||||
let span = meta.span();
|
|
||||||
self.tcx
|
|
||||||
.sess
|
|
||||||
.struct_span_err(span, "index exceeds number of arguments")
|
|
||||||
.span_label(
|
|
||||||
span,
|
|
||||||
format!(
|
|
||||||
"there {} only {} argument{}",
|
|
||||||
if arg_count != 1 { "are" } else { "is" },
|
|
||||||
arg_count,
|
|
||||||
pluralize!(arg_count)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bug!("should be a function item");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalid_args.push(meta.span());
|
invalid_args.push(meta.span());
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(0)] //~ ERROR index exceeds number of arguments
|
#[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] must have one index for
|
||||||
fn foo1() {}
|
fn foo1() {}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(1)] //~ ERROR index exceeds number of arguments
|
#[rustc_legacy_const_generics(1)] //~ ERROR index exceeds number of arguments
|
||||||
fn foo2(_: u8) {}
|
fn foo2<const X: usize>() {}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments
|
#[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments
|
||||||
fn foo3<const X: usize>(_: u8) {}
|
fn foo3<const X: usize>(_: u8) {}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers
|
#[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers
|
||||||
fn foo4() {}
|
fn foo4<const X: usize>() {}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers
|
#[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers
|
||||||
fn foo5(_: u8, _: u8, _: u8) {}
|
fn foo5<const X: usize, const Y: usize, const Z: usize, const W: usize>() {}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function
|
#[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes
|
#[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes
|
||||||
fn foo6(_: u8) {}
|
fn foo6<const X: usize>() {}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
#[rustc_legacy_const_generics(1)] //~ ERROR index exceeds number of arguments
|
#[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function
|
||||||
fn foo7(_: u8);
|
fn foo7<const X: usize>(); //~ ERROR foreign items may not have const parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] functions must only have
|
#[rustc_legacy_const_generics(0)] //~ ERROR #[rustc_legacy_const_generics] functions must only have
|
||||||
|
|
|
@ -18,11 +18,13 @@ error: malformed `rustc_legacy_const_generics` attribute input
|
||||||
LL | #[rustc_legacy_const_generics = 1]
|
LL | #[rustc_legacy_const_generics = 1]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]`
|
||||||
|
|
||||||
error: index exceeds number of arguments
|
error: #[rustc_legacy_const_generics] must have one index for each generic parameter
|
||||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:31
|
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:1
|
||||||
|
|
|
|
||||||
LL | #[rustc_legacy_const_generics(0)]
|
LL | #[rustc_legacy_const_generics(0)]
|
||||||
| ^ there are only 0 arguments
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | fn foo1() {}
|
||||||
|
| - generic parameters
|
||||||
|
|
||||||
error: index exceeds number of arguments
|
error: index exceeds number of arguments
|
||||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:6:31
|
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:6:31
|
||||||
|
@ -57,18 +59,29 @@ LL | struct S;
|
||||||
| --------- not a function
|
| --------- not a function
|
||||||
|
|
||||||
error: #[rustc_legacy_const_generics] functions must only have const generics
|
error: #[rustc_legacy_const_generics] functions must only have const generics
|
||||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:31
|
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1
|
||||||
|
|
|
|
||||||
LL | #[rustc_legacy_const_generics(0)]
|
LL | #[rustc_legacy_const_generics(0)]
|
||||||
| ^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
LL | fn foo8<X>() {}
|
LL | fn foo8<X>() {}
|
||||||
| - non-const generic parameter
|
| - non-const generic parameter
|
||||||
|
|
||||||
error: index exceeds number of arguments
|
error: attribute should be applied to a function
|
||||||
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:35
|
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5
|
||||||
|
|
|
|
||||||
LL | #[rustc_legacy_const_generics(1)]
|
LL | #[rustc_legacy_const_generics(1)]
|
||||||
| ^ there is only 1 argument
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | fn foo7<const X: usize>();
|
||||||
|
| -------------------------- not a function
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error[E0044]: foreign items may not have const parameters
|
||||||
|
--> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5
|
||||||
|
|
|
||||||
|
LL | fn foo7<const X: usize>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
|
||||||
|
|
|
||||||
|
= help: replace the const parameters with concrete consts
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0044`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue