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 or the MIT license +// , 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 or the MIT license +// , 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, + } + pub struct CObj { + name: Option, + } + 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 or the MIT license +// , 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 +} + +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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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) -> usize { + ::std::mem::size_of::() +} + +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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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(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"); +}