about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authormatthewjasper <mjjasper1@gmail.com>2017-04-22 17:55:59 +0100
committermatthewjasper <mjjasper1@gmail.com>2017-04-22 17:55:59 +0100
commit8a3ea01bcae85a3ed0c90ca5603cd88c469172c3 (patch)
tree291c7e740787ea95d87ac7a39f89a99d00b41c3c /src/libsyntax
parent5fc25224da78afcfdd76783c38ad3beff42a990c (diff)
parent6d841da4a0d7629f826117f99052e3d4a7997a7e (diff)
downloadrust-8a3ea01bcae85a3ed0c90ca5603cd88c469172c3.tar.gz
rust-8a3ea01bcae85a3ed0c90ca5603cd88c469172c3.zip
Resolve merge conflict
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr.rs55
-rw-r--r--src/libsyntax/diagnostic_list.rs2
-rw-r--r--src/libsyntax/ext/expand.rs14
-rw-r--r--src/libsyntax/feature_gate.rs8
-rw-r--r--src/libsyntax/test_snippet.rs93
5 files changed, 116 insertions, 56 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 6f5f52ff1e9..82492d97627 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -147,6 +147,24 @@ impl NestedMetaItem {
         self.meta_item().and_then(|meta_item| meta_item.value_str())
     }
 
+    /// Returns a name and single literal value tuple of the MetaItem.
+    pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
+        self.meta_item().and_then(
+            |meta_item| meta_item.meta_item_list().and_then(
+                |meta_item_list| {
+                    if meta_item_list.len() == 1 {
+                        let nested_item = &meta_item_list[0];
+                        if nested_item.is_literal() {
+                            Some((meta_item.name(), nested_item.literal().unwrap()))
+                        } else {
+                            None
+                        }
+                    }
+                    else {
+                        None
+                    }}))
+    }
+
     /// Returns a MetaItem if self is a MetaItem with Kind Word.
     pub fn word(&self) -> Option<&MetaItem> {
         self.meta_item().and_then(|meta_item| if meta_item.is_word() {
@@ -931,6 +949,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                     continue
                 }
 
+                let mut recognised = false;
                 if let Some(mi) = item.word() {
                     let word = &*mi.name().as_str();
                     let hint = match word {
@@ -941,20 +960,43 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                         _ => match int_type_of_word(word) {
                             Some(ity) => Some(ReprInt(ity)),
                             None => {
-                                // Not a word we recognize
-                                span_err!(diagnostic, item.span, E0552,
-                                          "unrecognized representation hint");
                                 None
                             }
                         }
                     };
 
                     if let Some(h) = hint {
+                        recognised = true;
                         acc.push(h);
                     }
-                } else {
-                    span_err!(diagnostic, item.span, E0553,
-                              "unrecognized enum representation hint");
+                } else if let Some((name, value)) = item.name_value_literal() {
+                    if name == "align" {
+                        recognised = true;
+                        let mut align_error = None;
+                        if let ast::LitKind::Int(align, ast::LitIntType::Unsuffixed) = value.node {
+                            if align.is_power_of_two() {
+                                // rustc::ty::layout::Align restricts align to <= 32768
+                                if align <= 32768 {
+                                    acc.push(ReprAlign(align as u16));
+                                } else {
+                                    align_error = Some("larger than 32768");
+                                }
+                            } else {
+                                align_error = Some("not a power of two");
+                            }
+                        } else {
+                            align_error = Some("not an unsuffixed integer");
+                        }
+                        if let Some(align_error) = align_error {
+                            span_err!(diagnostic, item.span, E0589,
+                                      "invalid `repr(align)` attribute: {}", align_error);
+                        }
+                    }
+                }
+                if !recognised {
+                    // Not a word we recognize
+                    span_err!(diagnostic, item.span, E0552,
+                              "unrecognized representation hint");
                 }
             }
         }
@@ -986,6 +1028,7 @@ pub enum ReprAttr {
     ReprExtern,
     ReprPacked,
     ReprSimd,
+    ReprAlign(u16),
 }
 
 #[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 2d59051ec4a..01d1277ea62 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -287,10 +287,10 @@ register_diagnostics! {
     E0550, // multiple deprecated attributes
     E0551, // incorrect meta item
     E0552, // unrecognized representation hint
-    E0553, // unrecognized enum representation hint
     E0554, // #[feature] may not be used on the [] release channel
     E0555, // malformed feature attribute, expected #![feature(...)]
     E0556, // malformed feature, expected just one word
     E0557, // feature has been removed
     E0584, // file for module `..` found at both .. and ..
+    E0589, // invalid `repr(align)` attribute
 }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 680bd7599ac..842398ea02b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -205,6 +205,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         module.directory.pop();
         self.cx.current_expansion.module = Rc::new(module);
 
+        let orig_mod_span = krate.module.inner;
+
         let krate_item = Expansion::Items(SmallVector::one(P(ast::Item {
             attrs: krate.attrs,
             span: krate.span,
@@ -214,11 +216,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             vis: ast::Visibility::Public,
         })));
 
-        match self.expand(krate_item).make_items().pop().unwrap().unwrap() {
-            ast::Item { attrs, node: ast::ItemKind::Mod(module), .. } => {
+        match self.expand(krate_item).make_items().pop().map(P::unwrap) {
+            Some(ast::Item { attrs, node: ast::ItemKind::Mod(module), .. }) => {
                 krate.attrs = attrs;
                 krate.module = module;
             },
+            None => {
+                // Resolution failed so we return an empty expansion
+                krate.attrs = vec![];
+                krate.module = ast::Mod {
+                    inner: orig_mod_span,
+                    items: vec![],
+                };
+            },
             _ => unreachable!(),
         };
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 81ab1a348d6..fa0e45194dc 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -335,6 +335,9 @@ declare_features! (
     // Allows the `catch {...}` expression
     (active, catch_expr, "1.17.0", Some(31436)),
 
+    // Allows `repr(align(u16))` struct attribute (RFC 1358)
+    (active, repr_align, "1.17.0", Some(33626)),
+
     // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work.
     (active, rvalue_static_promotion, "1.15.1", Some(38865)),
 
@@ -1185,6 +1188,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                                     and possibly buggy");
 
                             }
+                            if item.check_name("align") {
+                                gate_feature_post!(&self, repr_align, i.span,
+                                                   "the struct `#[repr(align(u16))]` attribute \
+                                                    is experimental");
+                            }
                         }
                     }
                 }
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index a74f59b004b..dc9b22c37e2 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -128,9 +128,9 @@ error: foo
  --> test.rs:2:10
   |
 2 |   fn foo() {
-  |  __________^ starting here...
+  |  __________^
 3 | | }
-  | |_^ ...ending here: test
+  | |_^ test
 
 "#);
 }
@@ -161,11 +161,11 @@ error: foo
  --> test.rs:2:10
   |
 2 |   fn foo() {
-  |  __________^ starting here...
+  |  __________^
 3 | |
 4 | |
 5 | |   }
-  | |___^ ...ending here: test
+  | |___^ test
 
 "#);
 }
@@ -207,14 +207,14 @@ error: foo
  --> test.rs:3:3
   |
 3 |      X0 Y0
-  |  ____^__- starting here...
+  |  ____^__-
   | | ___|
-  | ||   starting here...
+  | ||
 4 | ||   X1 Y1
 5 | ||   X2 Y2
-  | ||____^__- ...ending here: `Y` is a good letter too
+  | ||____^__- `Y` is a good letter too
   |  |____|
-  |       ...ending here: `X` is a good letter
+  |       `X` is a good letter
 
 "#);
 }
@@ -256,13 +256,13 @@ error: foo
  --> test.rs:3:3
   |
 3 |      X0 Y0
-  |  ____^__- starting here...
+  |  ____^__-
   | | ___|
-  | ||   starting here...
+  | ||
 4 | ||   Y1 X1
-  | ||____-__^ ...ending here: `X` is a good letter
+  | ||____-__^ `X` is a good letter
   | |_____|
-  |       ...ending here: `Y` is a good letter too
+  |       `Y` is a good letter too
 
 "#);
 }
@@ -306,13 +306,13 @@ error: foo
  --> test.rs:3:6
   |
 3 |      X0 Y0 Z0
-  |   ______^ starting here...
+  |   ______^
 4 |  |   X1 Y1 Z1
-  |  |_________- starting here...
+  |  |_________-
 5 | ||   X2 Y2 Z2
-  | ||____^ ...ending here: `X` is a good letter
+  | ||____^ `X` is a good letter
 6 | |    X3 Y3 Z3
-  | |_____- ...ending here: `Y` is a good letter too
+  | |_____- `Y` is a good letter too
 
 "#);
 }
@@ -366,16 +366,16 @@ error: foo
  --> test.rs:3:3
   |
 3 |       X0 Y0 Z0
-  |  _____^__-__- starting here...
+  |  _____^__-__-
   | | ____|__|
-  | || ___|  starting here...
-  | |||   starting here...
+  | || ___|
+  | |||
 4 | |||   X1 Y1 Z1
 5 | |||   X2 Y2 Z2
-  | |||____^__-__- ...ending here: `Z` label
+  | |||____^__-__- `Z` label
   |  ||____|__|
-  |   |____|  ...ending here: `Y` is a good letter too
-  |        ...ending here: `X` is a good letter
+  |   |____|  `Y` is a good letter too
+  |        `X` is a good letter
 
 "#);
 }
@@ -430,17 +430,17 @@ error: foo
  --> test.rs:3:6
   |
 3 |      X0 Y0 Z0
-  |   ______^ starting here...
+  |   ______^
 4 |  |   X1 Y1 Z1
-  |  |____^_- starting here...
+  |  |____^_-
   | ||____|
-  | |     ...ending here: `X` is a good letter
+  | |     `X` is a good letter
 5 | |    X2 Y2 Z2
-  | |____-______- ...ending here: `Y` is a good letter too
+  | |____-______- `Y` is a good letter too
   |  ____|
-  | |    starting here...
+  | |
 6 | |    X3 Y3 Z3
-  | |________- ...ending here: `Z`
+  | |________- `Z`
 
 "#);
 }
@@ -458,7 +458,7 @@ fn foo() {
     vec![
         SpanLabel {
             start: Position {
-                string: "Y0",
+                string: "X0",
                 count: 1,
             },
             end: Position {
@@ -481,16 +481,15 @@ fn foo() {
     ],
     r#"
 error: foo
- --> test.rs:3:6
+ --> test.rs:3:3
   |
-3 |     X0 Y0 Z0
-  |  ______^ starting here...
+3 | /   X0 Y0 Z0
 4 | |   X1 Y1 Z1
-  | |____^ ...ending here: `X` is a good letter
+  | |____^ `X` is a good letter
 5 |     X2 Y2 Z2
-  |  ______- starting here...
+  |  ______-
 6 | |   X3 Y3 Z3
-  | |__________- ...ending here: `Y` is a good letter too
+  | |__________- `Y` is a good letter too
 
 "#);
 }
@@ -534,14 +533,14 @@ error: foo
  --> test.rs:3:6
   |
 3 |      X0 Y0 Z0
-  |   ______^ starting here...
+  |   ______^
 4 |  |   X1 Y1 Z1
-  |  |____^____- starting here...
+  |  |____^____-
   | ||____|
-  | |     ...ending here: `X` is a good letter
+  | |     `X` is a good letter
 5 | |    X2 Y2 Z2
 6 | |    X3 Y3 Z3
-  | |___________- ...ending here: `Y` is a good letter too
+  | |___________- `Y` is a good letter too
 
 "#);
 }
@@ -982,18 +981,18 @@ error: foo
   --> test.rs:3:6
    |
 3  |      X0 Y0 Z0
-   |   ______^ starting here...
+   |   ______^
 4  |  |   X1 Y1 Z1
-   |  |____^____- starting here...
+   |  |____^____-
    | ||____|
-   | |     ...ending here: `X` is a good letter
+   | |     `X` is a good letter
 5  | |  1
 6  | |  2
 7  | |  3
 ...  |
 15 | |    X2 Y2 Z2
 16 | |    X3 Y3 Z3
-   | |___________- ...ending here: `Y` is a good letter too
+   | |___________- `Y` is a good letter too
 
 "#);
 }
@@ -1047,21 +1046,21 @@ error: foo
   --> test.rs:3:6
    |
 3  |      X0 Y0 Z0
-   |   ______^ starting here...
+   |   ______^
 4  |  | 1
 5  |  | 2
 6  |  | 3
 7  |  |   X1 Y1 Z1
-   |  |_________- starting here...
+   |  |_________-
 8  | || 4
 9  | || 5
 10 | || 6
 11 | ||   X2 Y2 Z2
-   | ||__________- ...ending here: `Z` is a good letter too
+   | ||__________- `Z` is a good letter too
 ...   |
 15 |  | 10
 16 |  |   X3 Y3 Z3
-   |  |_______^ ...ending here: `Y` is a good letter
+   |  |_______^ `Y` is a good letter
 
 "#);
 }