1
Fork 0

passes: prohibit attrs on generic params

This commit modifies the `check_attr` pass so that attribute placement
on generic parameters is checked for validity.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-11-15 13:03:30 +00:00
parent 2e5723137b
commit 75eb72cc9c
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
6 changed files with 147 additions and 5 deletions

View file

@ -9,6 +9,13 @@ use crate::{Item, ItemKind, TraitItem, TraitItemKind};
use std::fmt::{self, Display};
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum GenericParamKind {
Type,
Lifetime,
Const,
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum MethodKind {
Trait { body: bool },
@ -43,6 +50,7 @@ pub enum Target {
ForeignFn,
ForeignStatic,
ForeignTy,
GenericParam(GenericParamKind),
}
impl Display for Target {
@ -77,6 +85,11 @@ impl Display for Target {
Target::ForeignFn => "foreign function",
Target::ForeignStatic => "foreign static item",
Target::ForeignTy => "foreign type",
Target::GenericParam(kind) => match kind {
GenericParamKind::Type => "type parameter",
GenericParamKind::Lifetime => "lifetime parameter",
GenericParamKind::Const => "const parameter",
},
}
)
}
@ -124,4 +137,14 @@ impl Target {
hir::ForeignItemKind::Type => Target::ForeignTy,
}
}
pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
match generic_param.kind {
hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type),
hir::GenericParamKind::Lifetime { .. } => {
Target::GenericParam(GenericParamKind::Lifetime)
}
hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
}
}
}

View file

@ -814,6 +814,18 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_item(self, item)
}
fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) {
let target = Target::from_generic_param(generic_param);
self.check_attributes(
generic_param.hir_id,
generic_param.attrs,
&generic_param.span,
target,
None,
);
intravisit::walk_generic_param(self, generic_param)
}
fn visit_trait_item(&mut self, trait_item: &'tcx TraitItem<'tcx>) {
let target = Target::from_trait_item(trait_item);
self.check_attributes(trait_item.hir_id, &trait_item.attrs, &trait_item.span, target, None);