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

Qualify panic! as core::panic! in non-built-in core macros #78343

Merged
merged 2 commits into from
Nov 24, 2020

Conversation

camelid
Copy link
Member

@camelid camelid commented Oct 25, 2020

Fixes #78333.


Otherwise code like this

#![no_implicit_prelude]

fn main() {
    ::std::todo!();
    ::std::unimplemented!();
}

will fail to compile, which is unfortunate and presumably unintended.

This changes many invocations of panic! in a macro_rules! definition
to invocations of $crate::panic!, which makes the invocations hygienic.

Note that this does not make the built-in macro assert! hygienic.

@camelid camelid added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 25, 2020
@rust-highfive
Copy link
Collaborator

r? @Mark-Simulacrum

(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 Oct 25, 2020
@camelid
Copy link
Member Author

camelid commented Oct 25, 2020

I would like to write a test for this, but I'm not sure where to put it. Where are library compiletests put?

@camelid
Copy link
Member Author

camelid commented Oct 25, 2020

Tested locally and it seems to work.

stderr (compiling)

warning: unreachable statement
 --> issue-78333.rs:5:5
  |
4 |     ::std::todo!();
  |     --------------- any code following this expression is unreachable
5 |     ::std::unimplemented!();
  |     ^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
  |
  = note: `#[warn(unreachable_code)]` on by default
  = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 1 warning emitted

stderr (running)

thread 'main' panicked at 'not yet implemented', issue-78333.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

@jyn514
Copy link
Member

jyn514 commented Oct 25, 2020

I would like to write a test for this, but I'm not sure where to put it. Where are library compiletests put?

src/test/ui/macros/ seems fine.

@petrochenkov
Copy link
Contributor

petrochenkov commented Oct 25, 2020

This PR reroutes majority of code that previously called std::panic to core::panic.
We can only do this if core::panic and std::panic have identical interface and behavior in all case affected by the PR.
cc @RalfJung @m-ou-se

cc #61629 #63613

@RalfJung
Copy link
Member

Seems fine to me, and actually with @m-ou-se's recent changes the two macros are now more similar than before.

@m-ou-se
Copy link
Member

m-ou-se commented Oct 25, 2020

For all cases of the form panic!(format, one or more args ..), they do exactly the same, which covers almost all cases in this PR.

The other cases in this PR are of the form panic!("just a literal"), which used to work differently, but that was fixed just a few hours ago by #78119.

However, two important notes:

  1. You used to be able to 'intercept' panic!() from these macros by adding your own custom panic! macro. This is not a guarantee made anywhere in the documentation, so I think it's fine to break that.

  2. This PR changes assert_eq! and assert_ne!, but doesn't change assert!. (assert! is not a macro_rules, but it's implemented in compiler/rustc_builtin_macros/src/assert.rs.) assert!(expr, args ..) has the same problem this PR is fixing: it also expands to just panic!(args ..) without $crate::. However, this macro does expose the forms of {std,core}::panic! that are different:

assert!(1 + 1 == 3, 123); // ok with std, error with core
assert!(1 + 1 == 3, &String::from("hello")); // ok with core, error with std

I think it's fine to merge this PR as is, and fix assert!() later if possible. I already have a PR open that fixes this problem for assert!(expr), but not for assert!(expr, args ..): 049f2f2. The second form probably has to wait for std::panic!() and core::panic!() to become completely identical in behaviour, which will probably only happen in Rust 2021 to avoid breakage.

@m-ou-se m-ou-se added the A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows label Oct 25, 2020
@RalfJung
Copy link
Member

assert!(1 + 1 == 3, 123); // ok with std, error with core

I doubt this was ever intended to work, and even for people using panic! with a custom payload, this seems like a stretch. It would be worth a crater run to see how often this actually occurs in practice.

@m-ou-se
Copy link
Member

m-ou-se commented Oct 25, 2020

assert!(1 + 1 == 3, 123); // ok with std, error with core

I doubt this was ever intended to work, and even for people using panic! with a custom payload, this seems like a stretch. It would be worth a crater run to see how often this actually occurs in practice.

I'm all for just breaking assert!(.., 123) (and panic!(123)). But most discussions about this came to the conclusion that this should probably be gated on the next edition.

I'll turn my notes about this into an RFC today (and also add something about assert!()), so we can make a final decision about how to go forward with panic!() (and assert!() (and debug_assert!())).

@RalfJung
Copy link
Member

I'm all for just breaking assert!(.., 123) (and panic!(123)). But most discussions about this came to the conclusion that this should probably be gated on the next edition.

For panic! I agree the change is too invasive, but for assert! I am less sure.

I'll turn my notes about this into an RFC today (and also add something about assert!()), so we can make a final decision about how to go forward with panic!() (and assert!() (and debug_assert!())).

Okay, great. :) (But some of this will likely require further data, in particular for assert! I think it would be really good to know how wide-spread such non-string uses are.)

@m-ou-se
Copy link
Member

m-ou-se commented Oct 25, 2020

I'll turn my notes about this into an RFC today

Here it is

The proposed steps include this PR and the problem it solves. See the second to last step under 'Proposed solution'.

@Mark-Simulacrum
Copy link
Member

I'm going to r? @m-ou-se here, I'm not sure what the right path is -- would need to think about it -- but you seem to have a better handle on it than I :)

@camelid
Copy link
Member Author

camelid commented Oct 26, 2020

Yeah, this is much more complicated than I thought!

@camelid camelid changed the title Qualify panic! with $crate:: in core macros Qualify panic! as core::panic! Oct 26, 2020
@m-ou-se
Copy link
Member

m-ou-se commented Oct 26, 2020

Now that you're also updating assert!, this PR is a good candidate for a crater run to see if anyone relies on being able to intercept panic!()s from those macros, or uses non-string messages for assert! (e.g. assert!(false, 123)).

@camelid
Copy link
Member Author

camelid commented Oct 28, 2020

Yeah, I think I'll have to adjust the code if we're going to go forward with updating assert!, because it no longer allows you to use String as the assert message :/

error[E0308]: mismatched types
  --> /Users/nlroscoemeow/rust/src/test/ui/macros/assert-macro-owned.rs:6:20
   |
LL |     assert!(false, "test-assert-owned".to_string());
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                    |
   |                    expected `&str`, found struct `String`
   |                    help: consider borrowing here: `&"test-assert-owned".to_string()`

@camelid camelid marked this pull request as draft October 28, 2020 02:41
@m-ou-se
Copy link
Member

m-ou-se commented Oct 28, 2020

Yup. But we can still use this to do a crater run. Curious to see if anything other than this unit test fails.

@bors try

@bors
Copy link
Contributor

bors commented Oct 28, 2020

⌛ Trying commit 3fd3d0e53589340759a75a5ea28c858c21860484 with merge d17e02cd82564103b338f152142ccfe1a9b9fbc0...

@rust-log-analyzer
Copy link
Collaborator

The job dist-x86_64-linux of your PR failed (pretty log, 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.
error[E0308]: mismatched types
    | 
   ::: /cargo/registry/src/github.com-1ecc6299db9ec823/clap-2.33.3/src/app/parser.rs:183:13
    |
183 |               format!("Non-unique argument name: {} is already in use", a.b.name)

   Compiling bitmaps v2.1.0
   Compiling cc v1.0.60
   Compiling regex v1.3.9
   Compiling regex v1.3.9
error[E0308]: mismatched types
    | 
   ::: /cargo/registry/src/github.com-1ecc6299db9ec823/clap-2.33.3/src/usage_parser.rs:64:13
    |
64  | /             format!(
65  | |                 "No name found for Arg when parsing usage string: {}",
66  | |                 self.usage
    | |_____________- in this macro invocation

error: aborting due to 2 previous errors

---
== clock drift check ==
  local time: Wed Oct 28 10:29:02 UTC 2020
  network time: Tue, 27 Oct 2020 15:46:01 GMT
== end clock drift check ==
##[error]Process completed with exit code 1.
Terminate orphan process: pid (6055) (python)

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 @rust-lang/infra. (Feature Requests)

@camelid
Copy link
Member Author

camelid commented Nov 23, 2020

Rebased.

@camelid
Copy link
Member Author

camelid commented Nov 23, 2020

CI should pass now.

@camelid
Copy link
Member Author

camelid commented Nov 23, 2020

Squashed.

Otherwise code like this

    #![no_implicit_prelude]

    fn main() {
        ::std::todo!();
        ::std::unimplemented!();
    }

will fail to compile, which is unfortunate and presumably unintended.

This changes many invocations of `panic!` in a `macro_rules!` definition
to invocations of `$crate::panic!`, which makes the invocations hygienic.

Note that this does not make the built-in macro `assert!` hygienic.
* Switch a couple links over to intra-doc links
* Clean up some formatting/typography
@m-ou-se
Copy link
Member

m-ou-se commented Nov 23, 2020

@bors r+ 🎉

@bors
Copy link
Contributor

bors commented Nov 23, 2020

📌 Commit d8b1d51 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 23, 2020
@bors
Copy link
Contributor

bors commented Nov 23, 2020

⌛ Testing commit d8b1d51 with merge f32a0cc...

@bors
Copy link
Contributor

bors commented Nov 24, 2020

☀️ Test successful - checks-actions
Approved by: m-ou-se
Pushing f32a0cc to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 24, 2020
@bors bors merged commit f32a0cc into rust-lang:master Nov 24, 2020
@rustbot rustbot added this to the 1.50.0 milestone Nov 24, 2020
@m-ou-se
Copy link
Member

m-ou-se commented Nov 24, 2020

🎉 Thanks for making this happen, @camelid!

@camelid camelid deleted the macros-qualify-panic branch November 24, 2020 00:32
@camelid
Copy link
Member Author

camelid commented Nov 24, 2020

Thanks for helping me with this, @m-ou-se and @flip1995!

flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 6, 2020
Qualify `panic!` as `core::panic!` in non-built-in `core` macros

Fixes rust-lang#78333.

-----

Otherwise code like this

    #![no_implicit_prelude]

    fn main() {
        ::std::todo!();
        ::std::unimplemented!();
    }

will fail to compile, which is unfortunate and presumably unintended.

This changes many invocations of `panic!` in a `macro_rules!` definition
to invocations of `$crate::panic!`, which makes the invocations hygienic.

Note that this does not make the built-in macro `assert!` hygienic.
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Apr 19, 2021
Pkgsrc changes:
 * Adjust patches, re-compute line offsets, fix capitalization.
 * Remove i686/FreeBSD support, no longer provided upstream.
 * Bump bootstraps to 1.49.0.
 * Change USE_TOOLS from bsdtar to gtar.
 * Reduce diffs to pkgsrc-wip package patches.
 * Allow rust.BUILD_TARGET to override automatic choice of target.
 * Add an i586/NetBSD (pentium) bootstrap variant (needs testing),
   not yet added as bootstrap since 1.49 doesn't have that variant.

Upstream changes:

Version 1.50.0 (2021-02-11)
============================

Language
-----------------------
- [You can now use `const` values for `x` in `[x; N]` array
  expressions.][79270] This has been technically possible since
  1.38.0, as it was unintentionally stabilized.
- [Assignments to `ManuallyDrop<T>` union fields are now considered
  safe.][78068]

Compiler
-----------------------
- [Added tier 3\* support for the `armv5te-unknown-linux-uclibceabi`
  target.][78142]
- [Added tier 3 support for the `aarch64-apple-ios-macabi` target.][77484]
- [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484]

\* Refer to Rust's [platform support page][forge-platform-support] for more
information on Rust's tiered platform support.

Libraries
-----------------------

- [`proc_macro::Punct` now implements `PartialEq<char>`.][78636]
- [`ops::{Index, IndexMut}` are now implemented for fixed sized
  arrays of any length.][74989]
- [On Unix platforms, the `std::fs::File` type now has a "niche"
  of `-1`.][74699] This value cannot be a valid file descriptor,
  and now means `Option<File>` takes up the same amount of space
  as `File`.

Stabilized APIs
---------------

- [`bool::then`]
- [`btree_map::Entry::or_insert_with_key`]
- [`f32::clamp`]
- [`f64::clamp`]
- [`hash_map::Entry::or_insert_with_key`]
- [`Ord::clamp`]
- [`RefCell::take`]
- [`slice::fill`]
- [`UnsafeCell::get_mut`]

The following previously stable methods are now `const`.

- [`IpAddr::is_ipv4`]
- [`IpAddr::is_ipv6`]
- [`Layout::size`]
- [`Layout::align`]
- [`Layout::from_size_align`]
- `pow` for all integer types.
- `checked_pow` for all integer types.
- `saturating_pow` for all integer types.
- `wrapping_pow` for all integer types.
- `next_power_of_two` for all unsigned integer types.
- `checked_power_of_two` for all unsigned integer types.

Cargo
-----------------------

- [Added the `[build.rustc-workspace-wrapper]` option.][cargo/8976]
  This option sets a wrapper to execute instead of `rustc`, for
  workspace members only.
- [`cargo:rerun-if-changed` will now, if provided a directory, scan the entire
  contents of that directory for changes.][cargo/8973]
- [Added the `--workspace` flag to the `cargo update` command.][cargo/8725]

Misc
----

- [The search results tab and the help button are focusable with
  keyboard in rustdoc.][79896]
- [Running tests will now print the total time taken to execute.][75752]

Compatibility Notes
-------------------

- [The `compare_and_swap` method on atomics has been deprecated.][79261]
  It's recommended to use the `compare_exchange` and
  `compare_exchange_weak` methods instead.
- [Changes in how `TokenStream`s are checked have fixed some cases
  where you could write unhygenic `macro_rules!` macros.][79472]
- [`#![test]` as an inner attribute is now considered unstable like
  other inner macro attributes, and reports an error by default
  through the `soft_unstable` lint.][79003]
- [Overriding a `forbid` lint at the same level that it was set is
  now a hard error.][78864]
- [Dropped support for all cloudabi targets.][78439]
- [You can no longer intercept `panic!` calls by supplying your
  own macro.][78343] It's recommended to use the `#[panic_handler]`
  attribute to provide your own implementation.
- [Semi-colons after item statements (e.g. `struct Foo {};`) now
  produce a warning.][78296]

[74989]: rust-lang/rust#74989
[79261]: rust-lang/rust#79261
[79896]: rust-lang/rust#79896
[79484]: rust-lang/rust#79484
[79472]: rust-lang/rust#79472
[79270]: rust-lang/rust#79270
[79003]: rust-lang/rust#79003
[78864]: rust-lang/rust#78864
[78636]: rust-lang/rust#78636
[78439]: rust-lang/rust#78439
[78343]: rust-lang/rust#78343
[78296]: rust-lang/rust#78296
[78068]: rust-lang/rust#78068
[75752]: rust-lang/rust#75752
[74699]: rust-lang/rust#74699
[78142]: rust-lang/rust#78142
[77484]: rust-lang/rust#77484
[cargo/8976]: rust-lang/cargo#8976
[cargo/8973]: rust-lang/cargo#8973
[cargo/8725]: rust-lang/cargo#8725
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv6
[`Layout::align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align
[`Layout::from_size_align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.from_size_align
[`Layout::size`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.size
[`Ord::clamp`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#method.clamp
[`RefCell::take`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.take
[`UnsafeCell::get_mut`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.get_mut
[`bool::then`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then
[`btree_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.or_insert_with_key
[`f32::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.clamp
[`f64::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.clamp
[`hash_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/hash_map/enum.Entry.html#method.or_insert_with_key
[`slice::fill`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.fill
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows merged-by-bors This PR was explicitly merged by bors. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

error: cannot find macro panic in this scope