From 2cee9ec3b36933e143f2b2cc36a351da0a9114eb Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 17 Sep 2016 23:14:09 +0000 Subject: [PATCH 1/2] Ensure that macro invocations are folded and visited the same order. --- src/libsyntax/fold.rs | 84 ++++++++++++++++-------------------------- src/libsyntax/visit.rs | 10 ++--- 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 9fb4d0203f41e..36f273e1dbc29 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -478,8 +478,8 @@ pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedPara pub fn noop_fold_local(l: P, fld: &mut T) -> P { l.map(|Local {id, pat, ty, init, span, attrs}| Local { id: fld.new_id(id), - ty: ty.map(|t| fld.fold_ty(t)), pat: fld.fold_pat(pat), + ty: ty.map(|t| fld.fold_ty(t)), init: init.map(|e| fld.fold_expr(e)), span: fld.new_span(span), attrs: fold_attrs(attrs.into(), fld).into(), @@ -860,14 +860,10 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e)) } ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => { - ItemKind::Fn( - folder.fold_fn_decl(decl), - unsafety, - constness, - abi, - folder.fold_generics(generics), - folder.fold_block(body) - ) + let generics = folder.fold_generics(generics); + let decl = folder.fold_fn_decl(decl); + let body = folder.fold_block(body); + ItemKind::Fn(decl, unsafety, constness, abi, generics, body) } ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), @@ -875,50 +871,35 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) } ItemKind::Enum(enum_definition, generics) => { - ItemKind::Enum( - ast::EnumDef { - variants: enum_definition.variants.move_map(|x| folder.fold_variant(x)), - }, - folder.fold_generics(generics)) + let generics = folder.fold_generics(generics); + let variants = enum_definition.variants.move_map(|x| folder.fold_variant(x)); + ItemKind::Enum(ast::EnumDef { variants: variants }, generics) } ItemKind::Struct(struct_def, generics) => { - let struct_def = folder.fold_variant_data(struct_def); - ItemKind::Struct(struct_def, folder.fold_generics(generics)) + let generics = folder.fold_generics(generics); + ItemKind::Struct(folder.fold_variant_data(struct_def), generics) } ItemKind::Union(struct_def, generics) => { - let struct_def = folder.fold_variant_data(struct_def); - ItemKind::Union(struct_def, folder.fold_generics(generics)) + let generics = folder.fold_generics(generics); + ItemKind::Union(folder.fold_variant_data(struct_def), generics) } ItemKind::DefaultImpl(unsafety, ref trait_ref) => { ItemKind::DefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone())) } - ItemKind::Impl(unsafety, polarity, generics, ifce, ty, impl_items) => { - let new_impl_items = impl_items.move_flat_map(|item| { - folder.fold_impl_item(item) - }); - let ifce = match ifce { - None => None, - Some(ref trait_ref) => { - Some(folder.fold_trait_ref((*trait_ref).clone())) - } - }; - ItemKind::Impl(unsafety, - polarity, - folder.fold_generics(generics), - ifce, - folder.fold_ty(ty), - new_impl_items) - } - ItemKind::Trait(unsafety, generics, bounds, items) => { - let bounds = folder.fold_bounds(bounds); - let items = items.move_flat_map(|item| { - folder.fold_trait_item(item) - }); - ItemKind::Trait(unsafety, - folder.fold_generics(generics), - bounds, - items) - } + ItemKind::Impl(unsafety, polarity, generics, ifce, ty, impl_items) => ItemKind::Impl( + unsafety, + polarity, + folder.fold_generics(generics), + ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())), + folder.fold_ty(ty), + impl_items.move_flat_map(|item| folder.fold_impl_item(item)), + ), + ItemKind::Trait(unsafety, generics, bounds, items) => ItemKind::Trait( + unsafety, + folder.fold_generics(generics), + folder.fold_bounds(bounds), + items.move_flat_map(|item| folder.fold_trait_item(item)), + ), ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)), } } @@ -954,9 +935,9 @@ pub fn noop_fold_impl_item(i: ImplItem, folder: &mut T) -> SmallVector { SmallVector::one(ImplItem { id: folder.new_id(i.id), + vis: folder.fold_vis(i.vis), ident: folder.fold_ident(i.ident), attrs: fold_attrs(i.attrs, folder), - vis: folder.fold_vis(i.vis), defaultness: i.defaultness, node: match i.node { ast::ImplItemKind::Const(ty, expr) => { @@ -1031,15 +1012,12 @@ pub fn noop_fold_item(i: P, folder: &mut T) -> SmallVector(Item {id, ident, attrs, node, vis, span}: Item, folder: &mut T) -> Item { - let id = folder.new_id(id); - let node = folder.fold_item_kind(node); - Item { - id: id, + id: folder.new_id(id), + vis: folder.fold_vis(vis), ident: folder.fold_ident(ident), attrs: fold_attrs(attrs, folder), - node: node, - vis: folder.fold_vis(vis), + node: folder.fold_item_kind(node), span: folder.new_span(span) } } @@ -1047,6 +1025,7 @@ pub fn noop_fold_item_simple(Item {id, ident, attrs, node, vis, span} pub fn noop_fold_foreign_item(ni: ForeignItem, folder: &mut T) -> ForeignItem { ForeignItem { id: folder.new_id(ni.id), + vis: folder.fold_vis(ni.vis), ident: folder.fold_ident(ni.ident), attrs: fold_attrs(ni.attrs, folder), node: match ni.node { @@ -1057,7 +1036,6 @@ pub fn noop_fold_foreign_item(ni: ForeignItem, folder: &mut T) -> For ForeignItemKind::Static(folder.fold_ty(t), m) } }, - vis: folder.fold_vis(ni.vis), span: folder.new_span(ni.span) } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index efd9b027504f0..57b06c40878fe 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -532,8 +532,8 @@ pub fn walk_fn_kind(visitor: &mut V, function_kind: FnKind) { pub fn walk_fn(visitor: &mut V, kind: FnKind, declaration: &FnDecl, body: &Block, _span: Span) where V: Visitor, { - walk_fn_decl(visitor, declaration); walk_fn_kind(visitor, kind); + walk_fn_decl(visitor, declaration); visitor.visit_block(body) } @@ -652,13 +652,13 @@ pub fn walk_expr(visitor: &mut V, expression: &Expr) { walk_list!(visitor, visit_expr, subexpressions); } ExprKind::Call(ref callee_expression, ref arguments) => { + visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); - visitor.visit_expr(callee_expression) } ExprKind::MethodCall(ref ident, ref types, ref arguments) => { visitor.visit_ident(ident.span, ident.node); - walk_list!(visitor, visit_expr, arguments); walk_list!(visitor, visit_ty, types); + walk_list!(visitor, visit_expr, arguments); } ExprKind::Binary(_, ref left_expression, ref right_expression) => { visitor.visit_expr(left_expression); @@ -717,12 +717,12 @@ pub fn walk_expr(visitor: &mut V, expression: &Expr) { } ExprKind::Block(ref block) => visitor.visit_block(block), ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => { + visitor.visit_expr(left_hand_expression); visitor.visit_expr(right_hand_expression); - visitor.visit_expr(left_hand_expression) } ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(left_expression); visitor.visit_expr(right_expression); - visitor.visit_expr(left_expression) } ExprKind::Field(ref subexpression, ref ident) => { visitor.visit_expr(subexpression); From c7e4ae0d8d22847259e2e08a851f80e375221707 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 17 Sep 2016 23:31:32 +0000 Subject: [PATCH 2/2] Add regression test. --- src/test/run-pass/type-macros-simple.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/run-pass/type-macros-simple.rs b/src/test/run-pass/type-macros-simple.rs index 7d1045cf3f1a8..6b0deff3ba4fa 100644 --- a/src/test/run-pass/type-macros-simple.rs +++ b/src/test/run-pass/type-macros-simple.rs @@ -15,3 +15,22 @@ macro_rules! Tuple { fn main() { let x: Tuple!(i32, i32) = (1, 2); } + +fn issue_36540() { + let i32 = 0; + macro_rules! m { () => { i32 } } + struct S(m!(), T) where T: Trait; + + let x: m!() = m!(); + std::cell::Cell::::new(m!()); + impl std::ops::Index for Trait<(m!(), T)> + where T: Trait + { + type Output = m!(); + fn index(&self, i: m!()) -> &m!() { + unimplemented!() + } + } +} + +trait Trait {}