diff options
| author | bors <bors@rust-lang.org> | 2015-04-12 06:48:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-04-12 06:48:28 +0000 |
| commit | feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718 (patch) | |
| tree | 4acbbacbb3f8c2633b3bcfe79658f55db9a4f900 /src/test | |
| parent | 03f563a0e01bed68a44bf1fab946e0b6620bc153 (diff) | |
| parent | ddbdf51f394226bcae162ed2d5348126b32e7dbd (diff) | |
| download | rust-feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718.tar.gz rust-feeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718.zip | |
Auto merge of #24003 - rprichard:span-fixes, r=huonw
* In `noop_fold_expr`, call `new_span` in these cases:
- `ExprMethodCall`'s identifier
- `ExprField`'s identifier
- `ExprTupField`'s integer
Calling `new_span` for `ExprMethodCall`'s identifier is necessary to print
an acceptable diagnostic for `write!(&2, "")`. We see this error:
```
<std macros>:2:20: 2:66 error: type `&mut _` does not implement any method in scope named `write_fmt`
<std macros>:2 ( & mut * $ dst ) . write_fmt ( format_args ! ( $ ( $ arg ) * ) ) )
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
With this change, we also see a macro expansion backtrace leading to
the `write!(&2, "")` call site.
* After fully expanding a macro, we replace the expansion expression's
span with the original span. Call `fld.new_span` to add a backtrace to
this span. (Note that I'm call `new_span` after `bt.pop()`, so the macro
just expanded isn't on the backtrace.)
The motivating example for this change is `println!("{}")`. The format
string literal is `concat!($fmt, "arg")` and is inside the libstd macro.
We need to see the backtrace to find the `println!` call site.
* Add a backtrace to the `format_args!` format expression span.
r? alexcrichton
Addresses #23459
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/auxiliary/internal_unstable.rs | 33 | ||||
| -rw-r--r-- | src/test/compile-fail/internal-unstable-noallow.rs | 6 | ||||
| -rwxr-xr-x | src/test/compile-fail/internal-unstable.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/macro-backtrace-invalid-internals.rs | 57 | ||||
| -rw-r--r-- | src/test/compile-fail/macro-backtrace-nested.rs | 29 | ||||
| -rw-r--r-- | src/test/compile-fail/macro-backtrace-println.rs | 29 |
6 files changed, 156 insertions, 0 deletions
diff --git a/src/test/auxiliary/internal_unstable.rs b/src/test/auxiliary/internal_unstable.rs index 3d59b8e9009..7f682d5d8d1 100644 --- a/src/test/auxiliary/internal_unstable.rs +++ b/src/test/auxiliary/internal_unstable.rs @@ -22,6 +22,17 @@ pub struct Foo { pub x: u8 } +impl Foo { + #[unstable(feature = "method")] + pub fn method(&self) {} +} + +#[stable(feature = "stable", since = "1.0.0")] +pub struct Bar { + #[unstable(feature = "struct2_field")] + pub x: u8 +} + #[allow_internal_unstable] #[macro_export] macro_rules! call_unstable_allow { @@ -38,6 +49,18 @@ macro_rules! construct_unstable_allow { #[allow_internal_unstable] #[macro_export] +macro_rules! call_method_allow { + ($e: expr) => { $e.method() } +} + +#[allow_internal_unstable] +#[macro_export] +macro_rules! access_field_allow { + ($e: expr) => { $e.x } +} + +#[allow_internal_unstable] +#[macro_export] macro_rules! pass_through_allow { ($e: expr) => { $e } } @@ -55,6 +78,16 @@ macro_rules! construct_unstable_noallow { } #[macro_export] +macro_rules! call_method_noallow { + ($e: expr) => { $e.method() } +} + +#[macro_export] +macro_rules! access_field_noallow { + ($e: expr) => { $e.x } +} + +#[macro_export] macro_rules! pass_through_noallow { ($e: expr) => { $e } } diff --git a/src/test/compile-fail/internal-unstable-noallow.rs b/src/test/compile-fail/internal-unstable-noallow.rs index 2b48d47e940..2e42e9d3b01 100644 --- a/src/test/compile-fail/internal-unstable-noallow.rs +++ b/src/test/compile-fail/internal-unstable-noallow.rs @@ -16,6 +16,8 @@ // aux-build:internal_unstable.rs // error-pattern:use of unstable library feature 'function' // error-pattern:use of unstable library feature 'struct_field' +// error-pattern:use of unstable library feature 'method' +// error-pattern:use of unstable library feature 'struct2_field' #[macro_use] extern crate internal_unstable; @@ -24,4 +26,8 @@ fn main() { call_unstable_noallow!(); construct_unstable_noallow!(0); + + |x: internal_unstable::Foo| { call_method_noallow!(x) }; + + |x: internal_unstable::Bar| { access_field_noallow!(x) }; } diff --git a/src/test/compile-fail/internal-unstable.rs b/src/test/compile-fail/internal-unstable.rs index accc898b8a8..e01259f0deb 100755 --- a/src/test/compile-fail/internal-unstable.rs +++ b/src/test/compile-fail/internal-unstable.rs @@ -36,6 +36,8 @@ fn main() { // ok, the instability is contained. call_unstable_allow!(); construct_unstable_allow!(0); + |x: internal_unstable::Foo| { call_method_allow!(x) }; + |x: internal_unstable::Bar| { access_field_allow!(x) }; // bad. pass_through_allow!(internal_unstable::unstable()); //~ ERROR use of unstable diff --git a/src/test/compile-fail/macro-backtrace-invalid-internals.rs b/src/test/compile-fail/macro-backtrace-invalid-internals.rs new file mode 100644 index 00000000000..df906d72356 --- /dev/null +++ b/src/test/compile-fail/macro-backtrace-invalid-internals.rs @@ -0,0 +1,57 @@ +// Copyright 2015 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. + +// Macros in statement vs expression position handle backtraces differently. + +macro_rules! fake_method_stmt { //~ NOTE in expansion of + () => { + 1.fake() //~ ERROR does not implement any method + } +} + +macro_rules! fake_field_stmt { //~ NOTE in expansion of + () => { + 1.fake //~ ERROR no field with that name + } +} + +macro_rules! fake_anon_field_stmt { //~ NOTE in expansion of + () => { + (1).0 //~ ERROR type was not a tuple + } +} + +macro_rules! fake_method_expr { //~ NOTE in expansion of + () => { + 1.fake() //~ ERROR does not implement any method + } +} + +macro_rules! fake_field_expr { + () => { + 1.fake + } +} + +macro_rules! fake_anon_field_expr { + () => { + (1).0 + } +} + +fn main() { + fake_method_stmt!(); //~ NOTE expansion site + fake_field_stmt!(); //~ NOTE expansion site + fake_anon_field_stmt!(); //~ NOTE expansion site + + let _ = fake_method_expr!(); //~ NOTE expansion site + let _ = fake_field_expr!(); //~ ERROR no field with that name + let _ = fake_anon_field_expr!(); //~ ERROR type was not a tuple +} diff --git a/src/test/compile-fail/macro-backtrace-nested.rs b/src/test/compile-fail/macro-backtrace-nested.rs new file mode 100644 index 00000000000..7c1dc1a468c --- /dev/null +++ b/src/test/compile-fail/macro-backtrace-nested.rs @@ -0,0 +1,29 @@ +// Copyright 2015 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. + +// In expression position, but not statement position, when we expand a macro, +// we replace the span of the expanded expression with that of the call site. + +macro_rules! nested_expr { + () => (fake) +} + +macro_rules! call_nested_expr { + () => (nested_expr!()) +} + +macro_rules! call_nested_expr_sum { //~ NOTE in expansion of + () => { 1 + nested_expr!(); } //~ ERROR unresolved name +} + +fn main() { + 1 + call_nested_expr!(); //~ ERROR unresolved name + call_nested_expr_sum!(); //~ NOTE expansion site +} diff --git a/src/test/compile-fail/macro-backtrace-println.rs b/src/test/compile-fail/macro-backtrace-println.rs new file mode 100644 index 00000000000..0c66bbfcf04 --- /dev/null +++ b/src/test/compile-fail/macro-backtrace-println.rs @@ -0,0 +1,29 @@ +// Copyright 2015 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. + +// The `format_args!` syntax extension issues errors before code expansion +// has completed, but we still need a backtrace. + +// This test includes stripped-down versions of `print!` and `println!`, +// because we can't otherwise verify the lines of the backtrace. + +fn print(_args: std::fmt::Arguments) {} + +macro_rules! myprint { //~ NOTE in expansion of + ($($arg:tt)*) => (print(format_args!($($arg)*))); +} + +macro_rules! myprintln { //~ NOTE in expansion of + ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ ERROR invalid reference to argument `0` +} + +fn main() { + myprintln!("{}"); //~ NOTE expansion site +} |
