From b285ebc48ee7f342ca5a83e8b030359ab84e9ea0 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 21 Jan 2016 22:14:09 +0100 Subject: [PATCH 1/9] 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 --- src/libsyntax/ext/tt/transcribe.rs | 19 +++++++++++-- src/test/compile-fail/issue-25385.rs | 23 +++++++++++++++ src/test/compile-fail/issue-25386.rs | 38 +++++++++++++++++++++++++ src/test/compile-fail/issue-25793.rs | 34 ++++++++++++++++++++++ src/test/compile-fail/issue-26093.rs | 20 +++++++++++++ src/test/compile-fail/issue-26094.rs | 23 +++++++++++++++ src/test/compile-fail/issue-26237.rs | 22 +++++++++++++++ src/test/compile-fail/issue-26480.rs | 42 ++++++++++++++++++++++++++++ src/test/compile-fail/issue-28308.rs | 14 ++++++++++ src/test/compile-fail/issue-29084.rs | 21 ++++++++++++++ src/test/compile-fail/issue-31011.rs | 38 +++++++++++++++++++++++++ 11 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/issue-25385.rs create mode 100644 src/test/compile-fail/issue-25386.rs create mode 100644 src/test/compile-fail/issue-25793.rs create mode 100644 src/test/compile-fail/issue-26093.rs create mode 100644 src/test/compile-fail/issue-26094.rs create mode 100644 src/test/compile-fail/issue-26237.rs create mode 100644 src/test/compile-fail/issue-26480.rs create mode 100644 src/test/compile-fail/issue-28308.rs create mode 100644 src/test/compile-fail/issue-29084.rs create mode 100644 src/test/compile-fail/issue-31011.rs diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 8878c606d6a2c..c048547f5c979 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 0000000000000..5025b5ef13e29 --- /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 0000000000000..b2775db5e75a7 --- /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 0000000000000..e4199fcc12688 --- /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 0000000000000..3489a2ca9be15 --- /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 0000000000000..8b4ac7ddab9d3 --- /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 0000000000000..1cfece0d0b7a2 --- /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 0000000000000..e41db5645aeb3 --- /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 0000000000000..27066dc89841b --- /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 0000000000000..4967cd0024c59 --- /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 0000000000000..87c1732b897ac --- /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"); +} From 877ed0d0683b7ec0d217f6b00e520dc79e515ebd Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 24 Jan 2016 00:51:15 +0100 Subject: [PATCH 2/9] Update tests --- src/test/compile-fail/issue-25385.rs | 2 +- src/test/compile-fail/issue-26093.rs | 2 ++ src/test/compile-fail/issue-26480.rs | 2 +- src/test/compile-fail/issue-28308.rs | 2 +- src/test/compile-fail/issue-29084.rs | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/compile-fail/issue-25385.rs b/src/test/compile-fail/issue-25385.rs index 5025b5ef13e29..3ee6cdedf0c04 100644 --- a/src/test/compile-fail/issue-25385.rs +++ b/src/test/compile-fail/issue-25385.rs @@ -18,6 +18,6 @@ fn main() { let a = 1i32; foo!(a); - foo!(1.i32.foo()); + foo!(1i32.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-26093.rs b/src/test/compile-fail/issue-26093.rs index 3489a2ca9be15..6ac36707505a4 100644 --- a/src/test/compile-fail/issue-26093.rs +++ b/src/test/compile-fail/issue-26093.rs @@ -16,5 +16,7 @@ macro_rules! not_an_lvalue { } fn main() { + + 0 = 42; not_an_lvalue!(99); } diff --git a/src/test/compile-fail/issue-26480.rs b/src/test/compile-fail/issue-26480.rs index e41db5645aeb3..66bb0de13c48e 100644 --- a/src/test/compile-fail/issue-26480.rs +++ b/src/test/compile-fail/issue-26480.rs @@ -24,7 +24,7 @@ macro_rules! write { unsafe { write(stdout, $arr.as_ptr() as *const i8, $arr.len() * size_of($arr[0])); - //~^ ERROR mismatched types: expected `u64`, found `usize` + //~^ ERROR mismatched types } }} } diff --git a/src/test/compile-fail/issue-28308.rs b/src/test/compile-fail/issue-28308.rs index 27066dc89841b..43261a97f7b15 100644 --- a/src/test/compile-fail/issue-28308.rs +++ b/src/test/compile-fail/issue-28308.rs @@ -10,5 +10,5 @@ fn main() { assert!("foo"); - //~^ ERROR cannot apply unary operator `!` to type `&'static str`'` + //~^ 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 index 4967cd0024c59..a9f3643112051 100644 --- a/src/test/compile-fail/issue-29084.rs +++ b/src/test/compile-fail/issue-29084.rs @@ -12,7 +12,7 @@ macro_rules! foo { ($d:expr) => {{ fn bar(d: u8) { } bar(&mut $d); - //~^ ERROR mismatched types: expected `u8`, found `&mut u8` + //~^ ERROR mismatched types }} } From 20edb366e7d16da946c2484a8542dffb07b79837 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 24 Jan 2016 00:52:43 +0100 Subject: [PATCH 3/9] Set span for interpolated tokens correctly --- src/libsyntax/ext/tt/transcribe.rs | 4 ++-- src/libsyntax/parse/parser.rs | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index c048547f5c979..6cf05558adb55 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -300,13 +300,13 @@ 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 = sp; + r.cur_span = sn.span; 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); + //update_span(sp, &mut expr); // FIXME(pcwalton): Bad copy. r.cur_span = sp; r.cur_tok = token::Interpolated(NtExpr(ptr::P(expr))); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index acce6ed87d00b..f5ebe842577c6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2322,18 +2322,29 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); + let interp = if let token::Interpolated(..) = self.token { + true + } else { + false + }; let b = try!(self.parse_bottom_expr()); - self.parse_dot_or_call_expr_with(b, attrs) + let lo = if interp { + self.last_span.lo + } else { + b.span.lo + }; + self.parse_dot_or_call_expr_with(b, lo, attrs) } pub fn parse_dot_or_call_expr_with(&mut self, e0: P, + lo: BytePos, attrs: ThinAttributes) -> PResult<'a, P> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure - self.parse_dot_or_call_expr_with_(e0) + self.parse_dot_or_call_expr_with_(e0, lo) .map(|expr| expr.map(|mut expr| { expr.attrs.update(|a| a.prepend(attrs)); @@ -2408,9 +2419,8 @@ impl<'a> Parser<'a> { }) } - fn parse_dot_or_call_expr_with_(&mut self, e0: P) -> PResult<'a, P> { + fn parse_dot_or_call_expr_with_(&mut self, e0: P, lo: BytePos) -> PResult<'a, P> { let mut e = e0; - let lo = e.span.lo; let mut hi; loop { // expr.f @@ -3828,7 +3838,8 @@ impl<'a> Parser<'a> { let e = self.mk_mac_expr(span.lo, span.hi, mac.and_then(|m| m.node), None); - let e = try!(self.parse_dot_or_call_expr_with(e, attrs)); + let lo = e.span.lo; + let e = try!(self.parse_dot_or_call_expr_with(e, lo, attrs)); let e = try!(self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))); try!(self.handle_expression_like_statement( e, From 1bde18d60c2e2a4fec149312bae6e20609b6599b Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 24 Jan 2016 22:46:39 +0100 Subject: [PATCH 4/9] Use interpolated token span when building spans for bigger expressions --- src/libsyntax/ext/tt/transcribe.rs | 17 +--------- src/libsyntax/parse/parser.rs | 48 +++++++++++++++++----------- src/libsyntax/parse/token.rs | 8 +++++ src/test/compile-fail/issue-25385.rs | 2 +- src/test/compile-fail/issue-26093.rs | 2 -- src/test/compile-fail/issue-28308.rs | 4 ++- 6 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 6cf05558adb55..8878c606d6a2c 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -10,13 +10,12 @@ 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, NtExpr, SpecialMacroVar}; +use parse::token::{Token, NtIdent, SpecialMacroVar}; use parse::token; use parse::lexer::TokenAndSpan; @@ -174,11 +173,6 @@ 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 { @@ -285,7 +279,6 @@ 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 => { @@ -304,14 +297,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { 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/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f5ebe842577c6..6b41900282845 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -928,6 +928,7 @@ impl<'a> Parser<'a> { // Stash token for error recovery (sometimes; clone is not necessarily cheap). self.last_token = if self.token.is_ident() || self.token.is_path() || + self.token.is_interpolated() || self.token == token::Comma { Some(Box::new(self.token.clone())) } else { @@ -2322,13 +2323,9 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let interp = if let token::Interpolated(..) = self.token { - true - } else { - false - }; + let is_interpolated = self.token.is_interpolated(); let b = try!(self.parse_bottom_expr()); - let lo = if interp { + let lo = if is_interpolated { self.last_span.lo } else { b.span.lo @@ -2719,27 +2716,31 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let e = try!(self.parse_prefix_expr(None)); - hi = e.span.hi; + hi = if interpolated { prev_span.hi } else { e.span.hi }; ExprAddrOf(m, e) } token::Ident(..) if self.token.is_keyword(keywords::In) => { @@ -2757,8 +2758,9 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); + let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); let subexpression = try!(self.parse_prefix_expr(None)); - hi = subexpression.span.hi; + hi = if interpolated { prev_span.hi } else { subexpression.span.hi }; ExprBox(subexpression) } _ => return self.parse_dot_or_call_expr(Some(attrs)) @@ -2794,12 +2796,20 @@ impl<'a> Parser<'a> { try!(self.parse_prefix_expr(attrs)) } }; + + if self.expr_is_complete(&*lhs) { // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071 return Ok(lhs); } self.expected_tokens.push(TokenType::Operator); while let Some(op) = AssocOp::from_token(&self.token) { + + let lhs_span = match self.last_token { + Some(ref lt) if lt.is_interpolated() => self.last_span, + _ => lhs.span + }; + let cur_op_span = self.span; let restrictions = if op.is_assign_like() { self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL @@ -2815,13 +2825,13 @@ impl<'a> Parser<'a> { } // Special cases: if op == AssocOp::As { - let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, + let rhs = try!(self.parse_ty()); + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprCast(lhs, rhs), None); continue } else if op == AssocOp::Colon { let rhs = try!(self.parse_ty()); - lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, + lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprType(lhs, rhs), None); continue } else if op == AssocOp::DotDot { @@ -2843,7 +2853,7 @@ impl<'a> Parser<'a> { } else { None }; - let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs { + let (lhs_span, rhs_span) = (lhs_span, if let Some(ref x) = rhs { x.span } else { cur_op_span @@ -2883,14 +2893,14 @@ impl<'a> Parser<'a> { AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual | AssocOp::Greater | AssocOp::GreaterEqual => { let ast_op = op.to_ast_binop().unwrap(); - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let binary = self.mk_binary(codemap::respan(cur_op_span, ast_op), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, binary, None) } AssocOp::Assign => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprAssign(lhs, rhs), None), AssocOp::Inplace => - self.mk_expr(lhs.span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None), + self.mk_expr(lhs_span.lo, rhs.span.hi, ExprInPlace(lhs, rhs), None), AssocOp::AssignOp(k) => { let aop = match k { token::Plus => BiAdd, @@ -2904,7 +2914,7 @@ impl<'a> Parser<'a> { token::Shl => BiShl, token::Shr => BiShr }; - let (lhs_span, rhs_span) = (lhs.span, rhs.span); + let (lhs_span, rhs_span) = (lhs_span, rhs.span); let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 242626154fc8c..220d0aff2e3af 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -223,6 +223,14 @@ impl Token { } } + /// Returns `true` if the token is interpolated. + pub fn is_interpolated(&self) -> bool { + match *self { + Interpolated(..) => true, + _ => false, + } + } + /// Returns `true` if the token is an interpolated path. pub fn is_path(&self) -> bool { match *self { diff --git a/src/test/compile-fail/issue-25385.rs b/src/test/compile-fail/issue-25385.rs index 3ee6cdedf0c04..aa941bc569130 100644 --- a/src/test/compile-fail/issue-25385.rs +++ b/src/test/compile-fail/issue-25385.rs @@ -19,5 +19,5 @@ fn main() { foo!(a); foo!(1i32.foo()); - //~^ ERROR attempted access of field `i32` on type `_`, but no field with that name was found + //~^ ERROR no method named `foo` found for type `i32` in the current scope } diff --git a/src/test/compile-fail/issue-26093.rs b/src/test/compile-fail/issue-26093.rs index 6ac36707505a4..3489a2ca9be15 100644 --- a/src/test/compile-fail/issue-26093.rs +++ b/src/test/compile-fail/issue-26093.rs @@ -16,7 +16,5 @@ macro_rules! not_an_lvalue { } fn main() { - - 0 = 42; not_an_lvalue!(99); } diff --git a/src/test/compile-fail/issue-28308.rs b/src/test/compile-fail/issue-28308.rs index 43261a97f7b15..642bb0c4a107e 100644 --- a/src/test/compile-fail/issue-28308.rs +++ b/src/test/compile-fail/issue-28308.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// this error is dispayed in `` +// error-pattern:cannot apply unary operator `!` to type `&'static str` + fn main() { assert!("foo"); - //~^ ERROR cannot apply unary operator `!` to type `&'static str` } From 2bc8f4ff80a4343bacfcab9629eb681e576dee48 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 26 Jan 2016 11:34:32 +0100 Subject: [PATCH 5/9] Add interpolated_or_expr_span macro and pass lo to newly added parse_dot_suffix --- src/libsyntax/parse/parser.rs | 68 ++++++++++++++++------------ src/test/compile-fail/issue-31011.rs | 2 +- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6b41900282845..e00e72a72e99d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -233,6 +233,21 @@ macro_rules! maybe_whole { ) } +/// Uses $parse_expr to parse an expression and returns the span of the interpolated +/// token or the span of the parsed expression, if it was not interpolated +macro_rules! interpolated_or_expr_span { + ($p:expr, $parse_expr:expr) => { + { + let is_interpolated = $p.token.is_interpolated(); + let e = $parse_expr; + if is_interpolated { + ($p.last_span, e) + } else { + (e.span, e) + } + } + } +} fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { @@ -2323,14 +2338,8 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let is_interpolated = self.token.is_interpolated(); - let b = try!(self.parse_bottom_expr()); - let lo = if is_interpolated { - self.last_span.lo - } else { - b.span.lo - }; - self.parse_dot_or_call_expr_with(b, lo, attrs) + let (span, b) = interpolated_or_expr_span!(self, try!(self.parse_bottom_expr())); + self.parse_dot_or_call_expr_with(b, span.lo, attrs) } pub fn parse_dot_or_call_expr_with(&mut self, @@ -2368,7 +2377,8 @@ impl<'a> Parser<'a> { fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, - self_value: P) + self_value: P, + lo: BytePos) -> PResult<'a, P> { let (_, tys, bindings) = if self.eat(&token::ModSep) { try!(self.expect_lt()); @@ -2382,8 +2392,6 @@ impl<'a> Parser<'a> { self.span_err(last_span, "type bindings are only permitted on trait paths"); } - let lo = self_value.span.lo; - Ok(match self.token { // expr.f() method call. token::OpenDelim(token::Paren) => { @@ -2428,7 +2436,7 @@ impl<'a> Parser<'a> { hi = self.span.hi; self.bump(); - e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e)); + e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e, lo)); } token::Literal(token::Integer(n), suf) => { let sp = self.span; @@ -2481,7 +2489,7 @@ impl<'a> Parser<'a> { let dot_pos = self.last_span.hi; e = try!(self.parse_dot_suffix(special_idents::invalid, mk_sp(dot_pos, dot_pos), - e)); + e, lo)); } } continue; @@ -2716,31 +2724,31 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let e = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { e.span.hi }; + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; ExprAddrOf(m, e) } token::Ident(..) if self.token.is_keyword(keywords::In) => { @@ -2758,10 +2766,10 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (interpolated, prev_span) = (self.token.is_interpolated(), self.span); - let subexpression = try!(self.parse_prefix_expr(None)); - hi = if interpolated { prev_span.hi } else { subexpression.span.hi }; - ExprBox(subexpression) + let (span, e) = interpolated_or_expr_span!(self, + try!(self.parse_prefix_expr(None))); + hi = span.hi; + ExprBox(e) } _ => return self.parse_dot_or_call_expr(Some(attrs)) }; @@ -2825,7 +2833,7 @@ impl<'a> Parser<'a> { } // Special cases: if op == AssocOp::As { - let rhs = try!(self.parse_ty()); + let rhs = try!(self.parse_ty()); lhs = self.mk_expr(lhs_span.lo, rhs.span.hi, ExprCast(lhs, rhs), None); continue diff --git a/src/test/compile-fail/issue-31011.rs b/src/test/compile-fail/issue-31011.rs index 87c1732b897ac..a55b6f13872bf 100644 --- a/src/test/compile-fail/issue-31011.rs +++ b/src/test/compile-fail/issue-31011.rs @@ -11,7 +11,7 @@ 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 + //~^ ERROR attempted access of field `trace` on type `&T`, but no field with that name println!( $( $args, )* ); } } From 9d8c64b9966a2e6fe6b022491eb3fb7bb81ec292 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 26 Jan 2016 12:49:22 +0100 Subject: [PATCH 6/9] Push try! to call site of interpolated_or_expr_span! --- src/libsyntax/parse/parser.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e00e72a72e99d..4c818da633607 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -239,12 +239,13 @@ macro_rules! interpolated_or_expr_span { ($p:expr, $parse_expr:expr) => { { let is_interpolated = $p.token.is_interpolated(); - let e = $parse_expr; - if is_interpolated { - ($p.last_span, e) - } else { - (e.span, e) - } + $parse_expr.map(|e| { + if is_interpolated { + ($p.last_span, e) + } else { + (e.span, e) + } + }) } } } @@ -2338,7 +2339,7 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let (span, b) = interpolated_or_expr_span!(self, try!(self.parse_bottom_expr())); + let (span, b) = try!(interpolated_or_expr_span!(self, self.parse_bottom_expr())); self.parse_dot_or_call_expr_with(b, span.lo, attrs) } @@ -2724,30 +2725,30 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; ExprAddrOf(m, e) } @@ -2766,8 +2767,8 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (span, e) = interpolated_or_expr_span!(self, - try!(self.parse_prefix_expr(None))); + let (span, e) = try!(interpolated_or_expr_span!(self, + self.parse_prefix_expr(None))); hi = span.hi; ExprBox(e) } From 47bfd8c93c71730628af48818dd04ed62cffee74 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Jan 2016 10:47:33 +0100 Subject: [PATCH 7/9] Turn interpolated_or_expr_span into a function --- src/libsyntax/parse/parser.rs | 52 ++++++++++++++++------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4c818da633607..24a71e019f032 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -233,23 +233,6 @@ macro_rules! maybe_whole { ) } -/// Uses $parse_expr to parse an expression and returns the span of the interpolated -/// token or the span of the parsed expression, if it was not interpolated -macro_rules! interpolated_or_expr_span { - ($p:expr, $parse_expr:expr) => { - { - let is_interpolated = $p.token.is_interpolated(); - $parse_expr.map(|e| { - if is_interpolated { - ($p.last_span, e) - } else { - (e.span, e) - } - }) - } - } -} - fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { if let Some(ref attrs) = rhs { @@ -558,6 +541,18 @@ impl<'a> Parser<'a> { self.commit_stmt(&[edible], &[]) } + /// returns the span of expr, if it was not interpolated or the span of the interpolated token + fn interpolated_or_expr_span(&self, expr: PResult<'a, P>) -> PResult<'a, (Span, P)> { + let is_interpolated = self.token.is_interpolated(); + expr.map(|e| { + if is_interpolated { + (self.last_span, e) + } else { + (e.span, e) + } + }) + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.check_strict_keywords(); self.check_reserved_keywords(); @@ -2339,7 +2334,8 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); - let (span, b) = try!(interpolated_or_expr_span!(self, self.parse_bottom_expr())); + let b = self.parse_bottom_expr(); + let (span, b) = try!(self.interpolated_or_expr_span(b)); self.parse_dot_or_call_expr_with(b, span.lo, attrs) } @@ -2725,30 +2721,30 @@ impl<'a> Parser<'a> { let ex = match self.token { token::Not => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnNot, e) } token::BinOp(token::Minus) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnNeg, e) } token::BinOp(token::Star) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; self.mk_unary(UnDeref, e) } token::BinOp(token::And) | token::AndAnd => { try!(self.expect_and()); let m = try!(self.parse_mutability()); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; ExprAddrOf(m, e) } @@ -2767,8 +2763,8 @@ impl<'a> Parser<'a> { } token::Ident(..) if self.token.is_keyword(keywords::Box) => { self.bump(); - let (span, e) = try!(interpolated_or_expr_span!(self, - self.parse_prefix_expr(None))); + let e = self.parse_prefix_expr(None); + let (span, e) = try!(self.interpolated_or_expr_span(e)); hi = span.hi; ExprBox(e) } From e533ed91be4c39d718ad4bfa78165f77db842e49 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Jan 2016 11:26:38 +0100 Subject: [PATCH 8/9] Avoid storing interolated token in Parser.last_token --- src/libsyntax/parse/parser.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 24a71e019f032..883a54079d8d3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -254,6 +254,7 @@ pub struct Parser<'a> { pub cfg: CrateConfig, /// the previous token or None (only stashed sometimes). pub last_token: Option>, + last_token_interpolated: bool, pub buffer: [TokenAndSpan; 4], pub buffer_start: isize, pub buffer_end: isize, @@ -361,6 +362,7 @@ impl<'a> Parser<'a> { span: span, last_span: span, last_token: None, + last_token_interpolated: false, buffer: [ placeholder.clone(), placeholder.clone(), @@ -542,10 +544,11 @@ impl<'a> Parser<'a> { } /// returns the span of expr, if it was not interpolated or the span of the interpolated token - fn interpolated_or_expr_span(&self, expr: PResult<'a, P>) -> PResult<'a, (Span, P)> { - let is_interpolated = self.token.is_interpolated(); + fn interpolated_or_expr_span(&self, + expr: PResult<'a, P>) + -> PResult<'a, (Span, P)> { expr.map(|e| { - if is_interpolated { + if self.last_token_interpolated { (self.last_span, e) } else { (e.span, e) @@ -939,12 +942,12 @@ impl<'a> Parser<'a> { // Stash token for error recovery (sometimes; clone is not necessarily cheap). self.last_token = if self.token.is_ident() || self.token.is_path() || - self.token.is_interpolated() || self.token == token::Comma { Some(Box::new(self.token.clone())) } else { None }; + self.last_token_interpolated = self.token.is_interpolated(); let next = if self.buffer_start == self.buffer_end { self.reader.real_token() } else { @@ -2810,9 +2813,10 @@ impl<'a> Parser<'a> { self.expected_tokens.push(TokenType::Operator); while let Some(op) = AssocOp::from_token(&self.token) { - let lhs_span = match self.last_token { - Some(ref lt) if lt.is_interpolated() => self.last_span, - _ => lhs.span + let lhs_span = if self.last_token_interpolated { + self.last_span + } else { + lhs.span }; let cur_op_span = self.span; From ecb7b01a08095a8b657995da344bb47097efd43f Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Jan 2016 11:48:46 +0100 Subject: [PATCH 9/9] Add NOTE test annotations --- src/test/compile-fail/issue-25385.rs | 1 + src/test/compile-fail/issue-25386.rs | 2 ++ src/test/compile-fail/issue-25793.rs | 5 ++--- src/test/compile-fail/issue-26093.rs | 1 + src/test/compile-fail/issue-26094.rs | 4 ++-- src/test/compile-fail/issue-26237.rs | 1 + src/test/compile-fail/issue-26480.rs | 2 ++ src/test/compile-fail/issue-28308.rs | 1 + src/test/compile-fail/issue-29084.rs | 1 + src/test/compile-fail/issue-31011.rs | 1 + 10 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/test/compile-fail/issue-25385.rs b/src/test/compile-fail/issue-25385.rs index aa941bc569130..4aacb6840e9d5 100644 --- a/src/test/compile-fail/issue-25385.rs +++ b/src/test/compile-fail/issue-25385.rs @@ -17,6 +17,7 @@ macro_rules! foo { fn main() { let a = 1i32; foo!(a); + //~^ NOTE in this expansion of foo! foo!(1i32.foo()); //~^ ERROR no method named `foo` found for type `i32` in the current scope diff --git a/src/test/compile-fail/issue-25386.rs b/src/test/compile-fail/issue-25386.rs index b2775db5e75a7..297d3aacfd51e 100644 --- a/src/test/compile-fail/issue-25386.rs +++ b/src/test/compile-fail/issue-25386.rs @@ -35,4 +35,6 @@ macro_rules! check_ptr_exist { fn main() { let item = stuff::Item::new(); println!("{}", check_ptr_exist!(item, name)); + //~^ NOTE in this expansion of check_ptr_exist! + //~^^ NOTE in this expansion of check_ptr_exist! } diff --git a/src/test/compile-fail/issue-25793.rs b/src/test/compile-fail/issue-25793.rs index e4199fcc12688..fd3e3186bc5c9 100644 --- a/src/test/compile-fail/issue-25793.rs +++ b/src/test/compile-fail/issue-25793.rs @@ -26,9 +26,8 @@ impl HasInfo { fn get_other(&mut self) -> usize { self.get_size(width!(self)) + //~^ NOTE in this expansion of width! } } -fn main() { - println!("hello?"); -} +fn main() {} diff --git a/src/test/compile-fail/issue-26093.rs b/src/test/compile-fail/issue-26093.rs index 3489a2ca9be15..2f43388b7afb0 100644 --- a/src/test/compile-fail/issue-26093.rs +++ b/src/test/compile-fail/issue-26093.rs @@ -17,4 +17,5 @@ macro_rules! not_an_lvalue { fn main() { not_an_lvalue!(99); + //~^ NOTE in this expansion of not_an_lvalue! } diff --git a/src/test/compile-fail/issue-26094.rs b/src/test/compile-fail/issue-26094.rs index 8b4ac7ddab9d3..99add95e806f6 100644 --- a/src/test/compile-fail/issue-26094.rs +++ b/src/test/compile-fail/issue-26094.rs @@ -15,9 +15,9 @@ macro_rules! some_macro { }) } -fn some_function() { -} +fn some_function() {} fn main() { some_macro!(some_function); + //~^ in this expansion of some_macro! } diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs index 1cfece0d0b7a2..11e236d22126b 100644 --- a/src/test/compile-fail/issue-26237.rs +++ b/src/test/compile-fail/issue-26237.rs @@ -19,4 +19,5 @@ fn main() { let mut value_a = 0; let mut value_b = 0; macro_panic!(value_a, value_b); + //~^ in this expansion of macro_panic! } diff --git a/src/test/compile-fail/issue-26480.rs b/src/test/compile-fail/issue-26480.rs index 66bb0de13c48e..903df42291c63 100644 --- a/src/test/compile-fail/issue-26480.rs +++ b/src/test/compile-fail/issue-26480.rs @@ -37,6 +37,8 @@ macro_rules! cast { fn main() { let hello = ['H', 'e', 'y']; write!(hello); + //~^ NOTE in this expansion of write! cast!(2); + //~^ NOTE in this expansion of cast! } diff --git a/src/test/compile-fail/issue-28308.rs b/src/test/compile-fail/issue-28308.rs index 642bb0c4a107e..b0c44b5f33af1 100644 --- a/src/test/compile-fail/issue-28308.rs +++ b/src/test/compile-fail/issue-28308.rs @@ -10,6 +10,7 @@ // this error is dispayed in `` // error-pattern:cannot apply unary operator `!` to type `&'static str` +// error-pattern:in this expansion of assert! fn main() { assert!("foo"); diff --git a/src/test/compile-fail/issue-29084.rs b/src/test/compile-fail/issue-29084.rs index a9f3643112051..78913e759a1cc 100644 --- a/src/test/compile-fail/issue-29084.rs +++ b/src/test/compile-fail/issue-29084.rs @@ -18,4 +18,5 @@ macro_rules! foo { fn main() { foo!(0u8); + //~^ NOTE in this expansion of foo! } diff --git a/src/test/compile-fail/issue-31011.rs b/src/test/compile-fail/issue-31011.rs index a55b6f13872bf..b828b11030d71 100644 --- a/src/test/compile-fail/issue-31011.rs +++ b/src/test/compile-fail/issue-31011.rs @@ -26,6 +26,7 @@ struct Foo { fn wrap(context: &T) -> () { log!(context, "entered wrapper"); + //~^ in this expansion of log! } fn main() {