Skip to content

Commit

Permalink
Disallow derive on items with type macros
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed Jun 29, 2016
1 parent ea0dc92 commit 66ef652
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
18 changes: 14 additions & 4 deletions src/libsyntax_ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions src/test/compile-fail/issue-32950.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

0 comments on commit 66ef652

Please sign in to comment.