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
This commit is contained in:
parent
faf6d1e873
commit
b285ebc48e
@ -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;
|
||||
|
23
src/test/compile-fail/issue-25385.rs
Normal file
23
src/test/compile-fail/issue-25385.rs
Normal file
@ -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
|
||||
}
|
38
src/test/compile-fail/issue-25386.rs
Normal file
38
src/test/compile-fail/issue-25386.rs
Normal file
@ -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));
|
||||
}
|
34
src/test/compile-fail/issue-25793.rs
Normal file
34
src/test/compile-fail/issue-25793.rs
Normal file
@ -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?");
|
||||
}
|
20
src/test/compile-fail/issue-26093.rs
Normal file
20
src/test/compile-fail/issue-26093.rs
Normal file
@ -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);
|
||||
}
|
23
src/test/compile-fail/issue-26094.rs
Normal file
23
src/test/compile-fail/issue-26094.rs
Normal file
@ -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);
|
||||
}
|
22
src/test/compile-fail/issue-26237.rs
Normal file
22
src/test/compile-fail/issue-26237.rs
Normal file
@ -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);
|
||||
}
|
42
src/test/compile-fail/issue-26480.rs
Normal file
42
src/test/compile-fail/issue-26480.rs
Normal file
@ -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);
|
||||
}
|
14
src/test/compile-fail/issue-28308.rs
Normal file
14
src/test/compile-fail/issue-28308.rs
Normal file
@ -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`'`
|
||||
}
|
21
src/test/compile-fail/issue-29084.rs
Normal file
21
src/test/compile-fail/issue-29084.rs
Normal file
@ -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);
|
||||
}
|
38
src/test/compile-fail/issue-31011.rs
Normal file
38
src/test/compile-fail/issue-31011.rs
Normal file
@ -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");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user