Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experiment] Introduce a reliable way to refer to the standard library and use it for calling panic #62002

Closed
wants to merge 2 commits into from

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Jun 20, 2019

The second part of #61629.

  • A new reserved identifier __rustc_standard_library is introduced (it can be further uglified as much as necessary, but it must be a valid identifier).
  • __rustc_standard_library refers to the standard library crate when used in a path.
  • "Standard library" means libstd or libcore depending on #![no_std] settings, regardless of shadowing or renaming.

This PR is minimal, but __rustc_standard_library could also be used for std paths like std::option::Option in built-in derives, which currently use a special compiler hack ($crate in built-in macros specifically is re-routed to the standard library).
Unlike $crate re-routing, this PR's approach feels like a "proper" solution to the problem to me, the only downside is an introduction of a niche keyword.

TODO: Feature gating.

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 20, 2019
@petrochenkov
Copy link
Contributor Author

cc @rust-lang/lang

@Centril Centril added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 20, 2019
@joshtriplett
Copy link
Member

What prevents us from writing this as ::core or similar?

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:0dccee46:start=1561054847727710243,finish=1561054848531866590,duration=804156347
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
travis_time:start:test_assembly
Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:01:31] 
[01:01:31] running 9 tests
[01:01:31] iiiiiiiii
[01:01:31] 
[01:01:31]  finished in 0.148
[01:01:31] travis_fold:end:test_assembly

---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:01:47] 
[01:01:47] running 122 tests
[01:02:10] .iiiii...i.....i..i...i..i.i.i..i.ii..i.i.....i..i....i..........iiii..........i...ii...i.......ii.i 100/122
[01:02:15] .i.i......iii.i.....ii
[01:02:15] 
[01:02:15]  finished in 28.218
[01:02:15] travis_fold:end:test_debuginfo

---
[01:14:22]    Compiling std v0.0.0 (/checkout/src/libstd)
[01:14:29] error[E0308]: mismatched types
[01:14:29]     --> <::alloc::macros::format macros>:2:1
[01:14:29]      |
[01:14:29] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:29] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:29]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:29]      |   expected reference, found struct `realstd::string::String`
[01:14:29]      | 
[01:14:29]     ::: src/libstd/fs.rs:2175:5
[01:14:29]      |
[01:14:29]      |
[01:14:29] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:29]      |       |                                            |
[01:14:29]      |       |                                            in this macro invocation (#2)
[01:14:29]      |       in this expansion of `error!` (#1)
[01:14:29] 2176 | 
[01:14:29] 2176 | 
[01:14:29] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:29] 2178 | |         match $e {
[01:14:29] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:29] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:29] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:29] 2182 | |         }
[01:14:29] 2183 | |     ) }
[01:14:29]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:29] ...
[01:14:29] ...
[01:14:29] 2231 |           error!(result, "No such file or directory");
[01:14:29]      |
[01:14:29]      = note: expected type `&'static str`
[01:14:29]                 found type `realstd::string::String`
[01:14:29] 
[01:14:29] 
[01:14:29] error[E0308]: mismatched types
[01:14:29]     --> <::alloc::macros::format macros>:2:1
[01:14:29]      |
[01:14:29] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:29] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:29]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:29]      |   expected reference, found struct `realstd::string::String`
[01:14:29]      | 
[01:14:29]     ::: src/libstd/fs.rs:2175:5
[01:14:29]      |
[01:14:29]      |
[01:14:29] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:29]      |       |                                            |
[01:14:29]      |       |                                            in this macro invocation (#2)
[01:14:29]      |       in this expansion of `error!` (#1)
[01:14:29] 2176 | 
[01:14:29] 2176 | 
[01:14:29] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:29] 2178 | |         match $e {
[01:14:29] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:29] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:29] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:29] 2182 | |         }
[01:14:29] 2183 | |     ) }
[01:14:29]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:29] ...
[01:14:29] ...
[01:14:29] 2244 |           error!(result, "No such file or directory");
[01:14:29]      |
[01:14:29]      = note: expected type `&'static str`
[01:14:29]                 found type `realstd::string::String`
[01:14:29] 
[01:14:29] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3111 |           error!(c(&r).create_new(true).open(&tmpdir.join("b")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3112 |           error!(c(&r).create(true).truncate(true).open(&tmpdir.join("b")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3113 |           error!(c(&r).truncate(true).open(&tmpdir.join("b")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3114 |           error!(c(&r).create(true).open(&tmpdir.join("b")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3126 |           error!(c(&a).create(true).truncate(true).open(&tmpdir.join("d")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3127 |           error!(c(&a).truncate(true).open(&tmpdir.join("d")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3133 |           error!(c(&ra).create(true).truncate(true).open(&tmpdir.join("e")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3134 |           error!(c(&ra).truncate(true).open(&tmpdir.join("e")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!` (#3)
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2175:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2175 |       macro_rules! error { ($e:expr, $s:expr) => ( error_contains!($e, $s) ) }
[01:14:30]      |       |                                            |
[01:14:30]      |       |                                            in this macro invocation (#2)
[01:14:30]      |       in this expansion of `error!` (#1)
[01:14:30] 2176 | 
[01:14:30] 2176 | 
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!` (#2)
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3140 |            error!(blank.create(true).open(&tmpdir.join("f")), invalid_options);
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
[01:14:30] 
[01:14:30] error[E0308]: mismatched types
[01:14:30]     --> <::alloc::macros::format macros>:2:1
[01:14:30]      |
[01:14:30] 1    | / ( $ ( $ arg : tt ) * ) => (
[01:14:30] 2    | | $ crate :: fmt :: format ( format_args ! ( $ ( $ arg ) * ) ) )
[01:14:30]      | |_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_- in this expansion of `format!`
[01:14:30]      |   expected reference, found struct `realstd::string::String`
[01:14:30]      | 
[01:14:30]     ::: src/libstd/fs.rs:2177:5
[01:14:30]      |
[01:14:30]      |
[01:14:30] 2177 | /     macro_rules! error_contains { ($e:expr, $s:expr) => (
[01:14:30] 2178 | |         match $e {
[01:14:30] 2179 | |             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
[01:14:30] 2180 | |             Err(ref err) => assert!(err.to_string().contains($s),
[01:14:30] 2181 | |                                     format!("`{}` did not contain `{}`", err, $s))
[01:14:30] 2182 | |         }
[01:14:30] 2183 | |     ) }
[01:14:30]      | |_______- in this expansion of `error_contains!`
[01:14:30] ...
[01:14:30] ...
[01:14:30] 3218 | /         error_contains!(fs::read_to_string(&tmpdir.join("not-utf8")),
[01:14:30] 3219 | |                         "stream did not contain valid UTF-8");
[01:14:30]      |
[01:14:30]      = note: expected type `&'static str`
[01:14:30]                 found type `realstd::string::String`
[01:14:30] 
---
[01:14:40] 
[01:14:40] To learn more, run the command again with --verbose.
[01:14:40] 
[01:14:40] 
[01:14:40] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "-p" "std" "--" "--quiet"
[01:14:40] 
[01:14:40] 
[01:14:40] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:14:40] Build completed unsuccessfully in 1:10:22
---
travis_time:end:2cd6cebc:start=1561059341530039278,finish=1561059341535840034,duration=5800756
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0a8e59a3
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0f316603
travis_time:start:0f316603
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:102dacba
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@petrochenkov
Copy link
Contributor Author

@joshtriplett
core::panic and std::panic are two different macros doing different things (apparently).
So we want to call std::panic, not core::panic, if we are in non-no_std mode.

If std::panic simply reexported core::panic and all the panic implementation dispatch was done through #[panic_handler] somehow, then this problem would not exist.
I don't know whether that is possible or not, hopefully @alexcrichton will clarify.

@cramertj
Copy link
Member

We discussed this in the @rust-lang/lang meeting and were all fairly apprehensive about this approach. There are a number of strange interactions e.g. around #![no_std] libraries being used from with-std binaries or libraries that use #![no_std] and then optionally pull in std based on a feature gate.

As a potential alternative, we discussed that core::panic and std::panic macros are nearly identical: the only difference is that core calls core::panicking::panic(_fmt) while std calls std::rt::begin_panic(_fmt). I suggested that we could possibly unify the two macros into a single core::panic macro which calls an extern "C" fn panic(_fmt), which we provide an implementation of in both core and std. Then, we ensure that libstd is linked after libcore so that its symbol is given priority, giving us the libstd implementation for all callers.

Example:
in crate corelike:

mod some_private_mod {
    #[no_mangle]
    pub extern "C" fn __panic_internal() {
        println!("the one from core");
    }
}

extern "C" {
    fn __panic_internal();
}

pub fn function_in_core() {
    unsafe { __panic_internal() }
}

in crate stdlike:

// whether or not this function is included will change what is printed
// this is analogous to including `std` or not
#[no_mangle]
pub extern "C" fn __panic_internal() {
    println!("the one from std");
}

fn main() {
    // prints "the one from std" or "the one from core" based on whether or not the
    // above function is commented out
    corelike::function_in_core();
}

@cramertj
Copy link
Member

@nikomatsakis also mentioned @alexcrichton might have opinions about my linkage hack idea, so cc'ing them here.

@Centril Centril removed I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jun 20, 2019
@alexcrichton
Copy link
Member

alexcrichton commented Jun 21, 2019

Sorry I haven't followed this a ton so I wouldn't say I'm at all up to speed on all the relevant ins and outs here.

That being said there's an important difference between the std/core macros which I think justifies their current state. For invocations like panic!("foo {}", "bar") there is no difference but they behave radically different where core::panic!(1) doesn't work but std::panic!(1) does work. Notably you can panic with arbitrary Box<Any> payloads via libstd but with libcore you can only panic with strings.

That functionality difference may be resolvable with linkage still, but I'd have to dig into it myself to get a better idea.

I'm not really entirely certain though what the motivation is to make these hygienic. I feel like it'd be nice to do so but it doesn't really seem like we need to bend over backwards. I could be missing something though!

@petrochenkov
Copy link
Contributor Author

I'll close this PR since this should preferably be solved through lang items and/or linkage rather than name resolution, and I won't work on that in the near future.

I'm not really entirely certain though what the motivation is to make these hygienic.

I'm not sure what is the practical impact, but the situation with the panic kind being selected semi-arbitrarily when you leave the default setup with libstd being available and its prelude being in scope is a bug, and bugs are supposed to be fixed.

@petrochenkov petrochenkov deleted the dontpanic branch July 1, 2019 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants