Skip to content

Commit 66ef652

Browse files
committed
Disallow derive on items with type macros
1 parent ea0dc92 commit 66ef652

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/libsyntax_ext/deriving/generic/mod.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,18 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
345345
/// This method helps to extract all the type parameters referenced from a
346346
/// type. For a type parameter `<T>`, it looks for either a `TyPath` that
347347
/// is not global and starts with `T`, or a `TyQPath`.
348-
fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast::Ty>> {
348+
fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name], span: Span, cx: &ExtCtxt)
349+
-> Vec<P<ast::Ty>> {
349350
use syntax::visit;
350351

351-
struct Visitor<'a> {
352+
struct Visitor<'a, 'b: 'a> {
353+
cx: &'a ExtCtxt<'b>,
354+
span: Span,
352355
ty_param_names: &'a [ast::Name],
353356
types: Vec<P<ast::Ty>>,
354357
}
355358

356-
impl<'a> visit::Visitor for Visitor<'a> {
359+
impl<'a, 'b> visit::Visitor for Visitor<'a, 'b> {
357360
fn visit_ty(&mut self, ty: &ast::Ty) {
358361
match ty.node {
359362
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
371374

372375
visit::walk_ty(self, ty)
373376
}
377+
378+
fn visit_mac(&mut self, mac: &ast::Mac) {
379+
let span = Span { expn_id: self.span.expn_id, ..mac.span };
380+
self.cx.span_err(span, "`derive` cannot be used on items with type macros");
381+
}
374382
}
375383

376384
let mut visitor = Visitor {
377385
ty_param_names: ty_param_names,
378386
types: Vec::new(),
387+
span: span,
388+
cx: cx,
379389
};
380390

381391
visit::Visitor::visit_ty(&mut visitor, ty);
@@ -556,7 +566,7 @@ impl<'a> TraitDef<'a> {
556566

557567
let mut processed_field_types = HashSet::new();
558568
for field_ty in field_tys {
559-
let tys = find_type_parameters(&field_ty, &ty_param_names);
569+
let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
560570

561571
for ty in tys {
562572
// if we have already handled this type, skip it

src/test/compile-fail/issue-32950.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(type_macros, concat_idents, rustc_attrs)]
12-
#![allow(unused)]
11+
#![feature(type_macros, concat_idents)]
1312

14-
#[derive(Debug)] struct FooBar;
15-
#[derive(Debug)] struct Baz<T>(T, concat_idents!(Foo, Bar));
13+
#[derive(Debug)] //~ NOTE in this expansion
14+
struct Baz<T>(
15+
concat_idents!(Foo, Bar) //~ ERROR `derive` cannot be used on items with type macros
16+
);
1617

17-
#[rustc_error]
18-
fn main() {} //~ ERROR compilation successful
18+
fn main() {}

0 commit comments

Comments
 (0)