|
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