Disallow derive on items with type macros

This commit is contained in:
Jeffrey Seyfried 2016-06-24 03:23:44 +00:00
parent ea0dc92972
commit 66ef652559
2 changed files with 20 additions and 10 deletions

View File

@ -345,15 +345,18 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
/// This method helps to extract all the type parameters referenced from a
/// type. For a type parameter `<T>`, it looks for either a `TyPath` that
/// is not global and starts with `T`, or a `TyQPath`.
fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast::Ty>> {
fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name], span: Span, cx: &ExtCtxt)
-> Vec<P<ast::Ty>> {
use syntax::visit;
struct Visitor<'a> {
struct Visitor<'a, 'b: 'a> {
cx: &'a ExtCtxt<'b>,
span: Span,
ty_param_names: &'a [ast::Name],
types: Vec<P<ast::Ty>>,
}
impl<'a> visit::Visitor for Visitor<'a> {
impl<'a, 'b> visit::Visitor for Visitor<'a, 'b> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyKind::Path(_, ref path) if !path.global => {
@ -371,11 +374,18 @@ fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast
visit::walk_ty(self, ty)
}
fn visit_mac(&mut self, mac: &ast::Mac) {
let span = Span { expn_id: self.span.expn_id, ..mac.span };
self.cx.span_err(span, "`derive` cannot be used on items with type macros");
}
}
let mut visitor = Visitor {
ty_param_names: ty_param_names,
types: Vec::new(),
span: span,
cx: cx,
};
visit::Visitor::visit_ty(&mut visitor, ty);
@ -556,7 +566,7 @@ impl<'a> TraitDef<'a> {
let mut processed_field_types = HashSet::new();
for field_ty in field_tys {
let tys = find_type_parameters(&field_ty, &ty_param_names);
let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
for ty in tys {
// if we have already handled this type, skip it

View File

@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(type_macros, concat_idents, rustc_attrs)]
#![allow(unused)]
#![feature(type_macros, concat_idents)]
#[derive(Debug)] struct FooBar;
#[derive(Debug)] struct Baz<T>(T, concat_idents!(Foo, Bar));
#[derive(Debug)] //~ NOTE in this expansion
struct Baz<T>(
concat_idents!(Foo, Bar) //~ ERROR `derive` cannot be used on items with type macros
);
#[rustc_error]
fn main() {} //~ ERROR compilation successful
fn main() {}