use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
use syntax::attr;
-use syntax::visit::{self, FnKind, Visitor};
+use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use log::debug;
);
}
}
- ast::ForeignItemKind::Ty => {
+ ast::ForeignItemKind::TyAlias(..) => {
gate_feature_post!(&self, extern_types, i.span, "extern types are experimental");
}
- ast::ForeignItemKind::Macro(..) => {}
+ ast::ForeignItemKind::Macro(..) | ast::ForeignItemKind::Const(..) => {}
}
visit::walk_foreign_item(self, i)
visit::walk_pat(self, pattern)
}
- fn visit_fn(
- &mut self,
- fn_kind: FnKind<'a>,
- fn_decl: &'a ast::FnDecl,
- span: Span,
- _node_id: NodeId,
- ) {
+ fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
if let Some(header) = fn_kind.header() {
- // Stability of const fn methods are covered in
- // `visit_trait_item` and `visit_impl_item` below; this is
- // because default methods don't pass through this point.
+ // Stability of const fn methods are covered in `visit_assoc_item` below.
self.check_extern(header.ext);
+
+ if let (ast::Const::Yes(_), ast::Extern::Implicit)
+ | (ast::Const::Yes(_), ast::Extern::Explicit(_)) = (header.constness, header.ext)
+ {
+ gate_feature_post!(
+ &self,
+ const_extern_fn,
+ span,
+ "`const extern fn` definitions are unstable"
+ );
+ }
}
- if fn_decl.c_variadic() {
+ if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
}
- visit::walk_fn(self, fn_kind, fn_decl, span)
+ visit::walk_fn(self, fn_kind, span)
}
fn visit_generic_param(&mut self, param: &'a GenericParam) {
visit::walk_assoc_ty_constraint(self, constraint)
}
- fn visit_trait_item(&mut self, ti: &'a ast::AssocItem) {
- match ti.kind {
- ast::AssocItemKind::Fn(ref sig, ref block) => {
- if block.is_none() {
- self.check_extern(sig.header.ext);
- }
- if sig.header.constness.node == ast::Constness::Const {
- gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
+ fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
+ if i.defaultness == ast::Defaultness::Default {
+ gate_feature_post!(&self, specialization, i.span, "specialization is unstable");
+ }
+
+ match i.kind {
+ ast::AssocItemKind::Fn(ref sig, _, _) => {
+ if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
+ gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
}
}
- ast::AssocItemKind::TyAlias(_, ref default) => {
- if let Some(_) = default {
+ ast::AssocItemKind::TyAlias(ref generics, _, ref ty) => {
+ if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!(
&self,
associated_type_defaults,
- ti.span,
+ i.span,
"associated type defaults are unstable"
);
}
- }
- _ => {}
- }
- visit::walk_trait_item(self, ti)
- }
-
- fn visit_assoc_item(&mut self, ii: &'a ast::AssocItem) {
- if ii.defaultness == ast::Defaultness::Default {
- gate_feature_post!(&self, specialization, ii.span, "specialization is unstable");
- }
-
- match ii.kind {
- ast::AssocItemKind::Fn(ref sig, _) => {
- if sig.decl.c_variadic() {
- gate_feature_post!(
- &self,
- c_variadic,
- ii.span,
- "C-variadic functions are unstable"
- );
- }
- }
- ast::AssocItemKind::TyAlias(_, ref ty) => {
if let Some(ty) = ty {
self.check_impl_trait(ty);
}
- self.check_gat(&ii.generics, ii.span);
+ self.check_gat(generics, i.span);
}
_ => {}
}
- visit::walk_assoc_item(self, ii)
+ visit::walk_assoc_item(self, i, ctxt)
}
fn visit_vis(&mut self, vis: &'a ast::Visibility) {
gate_all!(async_closure, "async closures are unstable");
gate_all!(generators, "yield syntax is experimental");
gate_all!(or_patterns, "or-patterns syntax is experimental");
- gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
gate_all!(raw_ref_op, "raw address of syntax is experimental");
gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental");
gate_all!(const_trait_impl, "const trait impls are experimental");