about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-12 06:48:28 +0000
committerbors <bors@rust-lang.org>2015-04-12 06:48:28 +0000
commitfeeb23d42e0b1bc6f0466d4c6f035cfc3a4e9718 (patch)
tree4acbbacbb3f8c2633b3bcfe79658f55db9a4f900 /src/test
parent03f563a0e01bed68a44bf1fab946e0b6620bc153 (diff)
parentddbdf51f394226bcae162ed2d5348126b32e7dbd (diff)
downloadrust-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.rs33
-rw-r--r--src/test/compile-fail/internal-unstable-noallow.rs6
-rwxr-xr-xsrc/test/compile-fail/internal-unstable.rs2
-rw-r--r--src/test/compile-fail/macro-backtrace-invalid-internals.rs57
-rw-r--r--src/test/compile-fail/macro-backtrace-nested.rs29
-rw-r--r--src/test/compile-fail/macro-backtrace-println.rs29
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
+}