diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a79a571f0c7a..64575e685699 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1611,7 +1611,7 @@ impl Clean for ast::Ty { TyTypeof(..) => { panic!("Unimplemented type {:?}", self.node) }, - TyMac(..) => { + TyMac(ref m) => { cx.tcx().sess.span_bug(m.span, "unexpanded type macro found during cleaning") } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index cd340fc91891..aadc3cfbafe0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1555,29 +1555,39 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P, pub fn expand_type(t: P, fld: &mut MacroExpander) -> P { let t = match t.node.clone() { ast::Ty_::TyMac(mac) => { - let expanded_ty = match expand_mac_invoc(mac, t.span, - |r| r.make_ty(), - mark_ty, - fld) { - Some(ty) => ty, - None => { - return DummyResult::raw_ty(t.span); - } - }; + if fld.cx.ecfg.features.unwrap().type_macros { + let expanded_ty = match expand_mac_invoc(mac, t.span, + |r| r.make_ty(), + mark_ty, + fld) { + Some(ty) => ty, + None => { + return DummyResult::raw_ty(t.span); + } + }; - // Keep going, outside-in. - // - let fully_expanded = fld.fold_ty(expanded_ty); - fld.cx.bt_pop(); + // Keep going, outside-in. + // + let fully_expanded = fld.fold_ty(expanded_ty); + fld.cx.bt_pop(); - fully_expanded.map(|t| ast::Ty { - id: ast::DUMMY_NODE_ID, - node: t.node, - span: t.span, - }) + fully_expanded.map(|t| ast::Ty { + id: ast::DUMMY_NODE_ID, + node: t.node, + span: t.span, + }) + } else { + feature_gate::emit_feature_err( + &fld.cx.parse_sess.span_diagnostic, + "type_macros", + t.span, + "type macros are experimental (see tracking issue: 27336)"); + t + } } _ => t }; + fold::noop_fold_ty(t, fld) } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 945e457a77b7..02764215612e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -169,6 +169,8 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // Allows associated type defaults ("associated_type_defaults", "1.2.0", Active), +// Allows macros to appear in the type position. + ("type_macros", "1.3.0", Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -228,8 +230,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ "no_std is experimental")), ("lang", Gated("lang_items", "language items are subject to change")), - ("linkage", Gated("linkage", - "the `linkage` attribute is experimental \ + ("linkage", Gated("linkage", "the `linkage` attribute is experimental \ and not portable across platforms")), ("thread_local", Gated("thread_local", "`#[thread_local]` is an experimental feature, and does not \ @@ -349,6 +350,7 @@ pub struct Features { pub const_fn: bool, pub static_recursion: bool, pub default_type_parameter_fallback: bool, + pub type_macros: bool, } impl Features { @@ -375,6 +377,7 @@ impl Features { const_fn: false, static_recursion: false, default_type_parameter_fallback: false, + type_macros: false, } } } @@ -878,6 +881,7 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, const_fn: cx.has_feature("const_fn"), static_recursion: cx.has_feature("static_recursion"), default_type_parameter_fallback: cx.has_feature("default_type_parameter_fallback"), + type_macros: cx.has_feature("type_macros"), } }