about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2016-01-21 22:14:09 +0100
committerFlorian Hahn <flo@fhahn.com>2016-01-26 10:31:54 +0100
commitb285ebc48ee7f342ca5a83e8b030359ab84e9ea0 (patch)
treeec9961b9ac6b29208b919c83a3f6e312c5d7d141
parentfaf6d1e87391b25196b35909c3c95e5d873cacf0 (diff)
downloadrust-b285ebc48ee7f342ca5a83e8b030359ab84e9ea0.tar.gz
rust-b285ebc48ee7f342ca5a83e8b030359ab84e9ea0.zip
Update expression span when transcribing macro args
closes #29084
closes #28308
closes #25385
closes #28288
closes #31011
closes #26480
closes #26093
closes #26094
closes #25386
closes #26237
closes #25793
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs19
-rw-r--r--src/test/compile-fail/issue-25385.rs23
-rw-r--r--src/test/compile-fail/issue-25386.rs38
-rw-r--r--src/test/compile-fail/issue-25793.rs34
-rw-r--r--src/test/compile-fail/issue-26093.rs20
-rw-r--r--src/test/compile-fail/issue-26094.rs23
-rw-r--r--src/test/compile-fail/issue-26237.rs22
-rw-r--r--src/test/compile-fail/issue-26480.rs42
-rw-r--r--src/test/compile-fail/issue-28308.rs14
-rw-r--r--src/test/compile-fail/issue-29084.rs21
-rw-r--r--src/test/compile-fail/issue-31011.rs38
11 files changed, 292 insertions, 2 deletions
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 8878c606d6a..c048547f5c9 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -10,12 +10,13 @@
 use self::LockstepIterSize::*;
 
 use ast;
+use ptr;
 use ast::{TokenTree, Ident, Name};
 use codemap::{Span, DUMMY_SP};
 use errors::Handler;
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use parse::token::{DocComment, MatchNt, SubstNt};
-use parse::token::{Token, NtIdent, SpecialMacroVar};
+use parse::token::{Token, NtIdent, NtExpr, SpecialMacroVar};
 use parse::token;
 use parse::lexer::TokenAndSpan;
 
@@ -173,6 +174,11 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
     }
 }
 
+fn update_span(base: Span, expr: &mut ast::Expr) {
+    expr.span.lo = base.lo;
+    expr.span.hi = base.hi;
+}
+
 /// Return the next token from the TtReader.
 /// EFFECT: advances the reader's token field
 pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
@@ -279,6 +285,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
             }
             // FIXME #2887: think about span stuff here
             TokenTree::Token(sp, SubstNt(ident, namep)) => {
+                //println!("SubstNt {:?} {:?}", ident, sp);
                 r.stack.last_mut().unwrap().idx += 1;
                 match lookup_cur_matched(r, ident) {
                     None => {
@@ -293,10 +300,18 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                             // (a) idents can be in lots of places, so it'd be a pain
                             // (b) we actually can, since it's a token.
                             MatchedNonterminal(NtIdent(ref sn, b)) => {
-                                r.cur_span = sn.span;
+                                r.cur_span = sp;
                                 r.cur_tok = token::Ident(sn.node, b);
                                 return ret_val;
                             }
+                            MatchedNonterminal(NtExpr(ref expr)) => {
+                                let mut expr = (**expr).clone();
+                                update_span(sp, &mut expr);
+                                // FIXME(pcwalton): Bad copy.
+                                r.cur_span = sp;
+                                r.cur_tok = token::Interpolated(NtExpr(ptr::P(expr)));
+                                return ret_val;
+                            }
                             MatchedNonterminal(ref other_whole_nt) => {
                                 // FIXME(pcwalton): Bad copy.
                                 r.cur_span = sp;
diff --git a/src/test/compile-fail/issue-25385.rs b/src/test/compile-fail/issue-25385.rs
new file mode 100644
index 00000000000..5025b5ef13e
--- /dev/null
+++ b/src/test/compile-fail/issue-25385.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+macro_rules! foo {
+    ($e:expr) => { $e.foo() }
+    //~^ ERROR no method named `foo` found for type `i32` in the current scope
+}
+
+fn main() {
+    let a = 1i32;
+    foo!(a);
+
+    foo!(1.i32.foo());
+    //~^ ERROR attempted access of field `i32` on type `_`, but no field with that name was found
+}
diff --git a/src/test/compile-fail/issue-25386.rs b/src/test/compile-fail/issue-25386.rs
new file mode 100644
index 00000000000..b2775db5e75
--- /dev/null
+++ b/src/test/compile-fail/issue-25386.rs
@@ -0,0 +1,38 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod stuff {
+    pub struct Item {
+        c_object: Box<CObj>,
+    }
+    pub struct CObj {
+        name: Option<String>,
+    }
+    impl Item {
+        pub fn new() -> Item {
+            Item {
+                c_object: Box::new(CObj { name: None }),
+            }
+        }
+    }
+}
+
+macro_rules! check_ptr_exist {
+    ($var:expr, $member:ident) => (
+        (*$var.c_object).$member.is_some()
+        //~^ ERROR field `name` of struct `stuff::CObj` is private
+        //~^^ ERROR field `c_object` of struct `stuff::Item` is private
+    );
+}
+
+fn main() {
+    let item = stuff::Item::new();
+    println!("{}", check_ptr_exist!(item, name));
+}
diff --git a/src/test/compile-fail/issue-25793.rs b/src/test/compile-fail/issue-25793.rs
new file mode 100644
index 00000000000..e4199fcc126
--- /dev/null
+++ b/src/test/compile-fail/issue-25793.rs
@@ -0,0 +1,34 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! width(
+    ($this:expr) => {
+        $this.width.unwrap()
+        //~^ ERROR cannot use `self.width` because it was mutably borrowed
+    }
+);
+
+struct HasInfo {
+    width: Option<usize>
+}
+
+impl HasInfo {
+    fn get_size(&mut self, n: usize) -> usize {
+        n
+    }
+
+    fn get_other(&mut self) -> usize {
+        self.get_size(width!(self))
+    }
+}
+
+fn main() {
+    println!("hello?");
+}
diff --git a/src/test/compile-fail/issue-26093.rs b/src/test/compile-fail/issue-26093.rs
new file mode 100644
index 00000000000..3489a2ca9be
--- /dev/null
+++ b/src/test/compile-fail/issue-26093.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! not_an_lvalue {
+    ($thing:expr) => {
+        $thing = 42;
+        //~^ ERROR invalid left-hand side expression
+    }
+}
+
+fn main() {
+    not_an_lvalue!(99);
+}
diff --git a/src/test/compile-fail/issue-26094.rs b/src/test/compile-fail/issue-26094.rs
new file mode 100644
index 00000000000..8b4ac7ddab9
--- /dev/null
+++ b/src/test/compile-fail/issue-26094.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! some_macro {
+    ($other: expr) => ({
+        $other(None)
+        //~^ this function takes 0 parameters but 1 parameter was supplied
+    })
+}
+
+fn some_function() {
+}
+
+fn main() {
+    some_macro!(some_function);
+}
diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs
new file mode 100644
index 00000000000..1cfece0d0b7
--- /dev/null
+++ b/src/test/compile-fail/issue-26237.rs
@@ -0,0 +1,22 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! macro_panic {
+    ($not_a_function:expr, $some_argument:ident) => {
+        $not_a_function($some_argument)
+        //~^ ERROR expected function, found `_`
+    }
+}
+
+fn main() {
+    let mut value_a = 0;
+    let mut value_b = 0;
+    macro_panic!(value_a, value_b);
+}
diff --git a/src/test/compile-fail/issue-26480.rs b/src/test/compile-fail/issue-26480.rs
new file mode 100644
index 00000000000..e41db5645ae
--- /dev/null
+++ b/src/test/compile-fail/issue-26480.rs
@@ -0,0 +1,42 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern {
+    fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
+}
+
+#[inline(always)]
+fn size_of<T>(_: T) -> usize {
+    ::std::mem::size_of::<T>()
+}
+
+macro_rules! write {
+    ($arr:expr) => {{
+        #[allow(non_upper_case_globals)]
+        const stdout: i32 = 1;
+        unsafe {
+            write(stdout, $arr.as_ptr() as *const i8,
+                  $arr.len() * size_of($arr[0]));
+            //~^ ERROR mismatched types: expected `u64`, found `usize`
+        }
+    }}
+}
+
+macro_rules! cast {
+    ($x:expr) => ($x as ())
+    //~^ ERROR non-scalar cast: `i32` as `()`
+}
+
+fn main() {
+    let hello = ['H', 'e', 'y'];
+    write!(hello);
+
+    cast!(2);
+}
diff --git a/src/test/compile-fail/issue-28308.rs b/src/test/compile-fail/issue-28308.rs
new file mode 100644
index 00000000000..27066dc8984
--- /dev/null
+++ b/src/test/compile-fail/issue-28308.rs
@@ -0,0 +1,14 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    assert!("foo");
+    //~^ ERROR cannot apply unary operator `!` to type `&'static str`'`
+}
diff --git a/src/test/compile-fail/issue-29084.rs b/src/test/compile-fail/issue-29084.rs
new file mode 100644
index 00000000000..4967cd0024c
--- /dev/null
+++ b/src/test/compile-fail/issue-29084.rs
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! foo {
+    ($d:expr) => {{
+        fn bar(d: u8) { }
+        bar(&mut $d);
+        //~^ ERROR mismatched types: expected `u8`, found `&mut u8`
+    }}
+}
+
+fn main() {
+    foo!(0u8);
+}
diff --git a/src/test/compile-fail/issue-31011.rs b/src/test/compile-fail/issue-31011.rs
new file mode 100644
index 00000000000..87c1732b897
--- /dev/null
+++ b/src/test/compile-fail/issue-31011.rs
@@ -0,0 +1,38 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! log {
+    ( $ctx:expr, $( $args:expr),* ) => {
+        if $ctx.trace {
+        //~^ attempted access of field `trace` on type `&T`, but no field with that name was found
+            println!( $( $args, )* );
+        }
+    }
+}
+
+// Create a structure.
+struct Foo {
+  trace: bool,
+}
+
+// Generic wrapper calls log! with a structure.
+fn wrap<T>(context: &T) -> ()
+{
+    log!(context, "entered wrapper");
+}
+
+fn main() {
+    // Create a structure.
+    let x = Foo { trace: true };
+    log!(x, "run started");
+    // Apply a closure which accesses internal fields.
+    wrap(&x);
+    log!(x, "run finished");
+}