|
20 | 20 |
|
21 | 21 | use middle::lint; |
22 | 22 |
|
| 23 | +use syntax::abi::RustIntrinsic; |
| 24 | +use syntax::ast::NodeId; |
23 | 25 | use syntax::ast; |
24 | 26 | use syntax::attr; |
25 | 27 | use syntax::attr::AttrMetaMethods; |
@@ -51,6 +53,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ |
51 | 53 | ("trace_macros", Active), |
52 | 54 | ("concat_idents", Active), |
53 | 55 | ("unsafe_destructor", Active), |
| 56 | + ("intrinsics", Active), |
| 57 | + ("lang_items", Active), |
54 | 58 |
|
55 | 59 | ("simd", Active), |
56 | 60 | ("default_type_params", Active), |
@@ -187,13 +191,18 @@ impl<'a> Visitor<()> for Context<'a> { |
187 | 191 | } |
188 | 192 | } |
189 | 193 |
|
190 | | - ast::ItemForeignMod(..) => { |
| 194 | + ast::ItemForeignMod(ref foreign_module) => { |
191 | 195 | if attr::contains_name(i.attrs.as_slice(), "link_args") { |
192 | 196 | self.gate_feature("link_args", i.span, |
193 | 197 | "the `link_args` attribute is not portable \ |
194 | 198 | across platforms, it is recommended to \ |
195 | 199 | use `#[link(name = \"foo\")]` instead") |
196 | 200 | } |
| 201 | + if foreign_module.abi == RustIntrinsic { |
| 202 | + self.gate_feature("intrinsics", |
| 203 | + i.span, |
| 204 | + "intrinsics are subject to change") |
| 205 | + } |
197 | 206 | } |
198 | 207 |
|
199 | 208 | ast::ItemFn(..) => { |
@@ -283,14 +292,10 @@ impl<'a> Visitor<()> for Context<'a> { |
283 | 292 | } |
284 | 293 |
|
285 | 294 | fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) { |
286 | | - match i.node { |
287 | | - ast::ForeignItemFn(..) | ast::ForeignItemStatic(..) => { |
288 | | - if attr::contains_name(i.attrs.as_slice(), "linkage") { |
289 | | - self.gate_feature("linkage", i.span, |
290 | | - "the `linkage` attribute is experimental \ |
291 | | - and not portable across platforms") |
292 | | - } |
293 | | - } |
| 295 | + if attr::contains_name(i.attrs.as_slice(), "linkage") { |
| 296 | + self.gate_feature("linkage", i.span, |
| 297 | + "the `linkage` attribute is experimental \ |
| 298 | + and not portable across platforms") |
294 | 299 | } |
295 | 300 | visit::walk_foreign_item(self, i, ()) |
296 | 301 | } |
@@ -338,6 +343,32 @@ impl<'a> Visitor<()> for Context<'a> { |
338 | 343 | } |
339 | 344 | visit::walk_generics(self, generics, ()); |
340 | 345 | } |
| 346 | + |
| 347 | + fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) { |
| 348 | + if attr::contains_name([*attr], "lang") { |
| 349 | + self.gate_feature("lang_items", |
| 350 | + attr.span, |
| 351 | + "language items are subject to change"); |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + fn visit_fn(&mut self, |
| 356 | + fn_kind: &visit::FnKind, |
| 357 | + fn_decl: &ast::FnDecl, |
| 358 | + block: &ast::Block, |
| 359 | + span: Span, |
| 360 | + _: NodeId, |
| 361 | + (): ()) { |
| 362 | + match *fn_kind { |
| 363 | + visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => { |
| 364 | + self.gate_feature("intrinsics", |
| 365 | + span, |
| 366 | + "intrinsics are subject to change") |
| 367 | + } |
| 368 | + _ => {} |
| 369 | + } |
| 370 | + visit::walk_fn(self, fn_kind, fn_decl, block, span, ()); |
| 371 | + } |
341 | 372 | } |
342 | 373 |
|
343 | 374 | pub fn check_crate(sess: &Session, krate: &ast::Crate) { |
|
0 commit comments