profile
viewpoint
jumbatm jumbatm Brisbane, Australia (GMT+10)

jumbatm/mod-player 1

Work in progress. A player for MOD tracker files.

jumbatm/catch-tiny 0

An even smaller Catch2 subset - Test cases, assertions and sections only. Goodbye, long test compile times!

jumbatm/cloud-path-tracer 0

A toy online path tracing service.

jumbatm/dcpu 0

DCPU-16 emulator & assembler.

jumbatm/enumerate 0

For when you need to keep track of an index in a ranged-for.

jumbatm/JobMap 0

Find jobs near you and their commute times.

jumbatm/Matrix 0

Just for fun - Matrix class with lazy evaluation using templates.

jumbatm/median-algorithms 0

Source code for empirical analysis of two functionally-similar median-finding algorithms.

pull request commentrust-lang/rust

SessionDiagnostic: Fix non-determinism in generated format string.

No worries - thank you for checking :)

jumbatm

comment created time in 18 days

pull request commentrust-lang/rust

SessionDiagnostic: Fix non-determinism in generated format string.

So the fix is twofold: First change all the HashSet and HashMap to FxHashSet and FxHashMap where possible, and second, collect to a Vec and sort that Vec before iterating over the set/map

rustc_macros can't depend on rustc_data_structures for FxHash* because it depends a circular dependency. Instead, I've switched to a BTreeSet so the iteration order is deterministic.

@jgalenson -- I know it's a bit of an ask, but can you confirm this fixes the problem?

jumbatm

comment created time in 19 days

PR opened rust-lang/rust

SessionDiagnostic: Fix non-determinism in generated format string.

Fixes #76496.

r? @oli-obk

+6 -5

0 comment

1 changed file

pr created time in 19 days

push eventjumbatm/rust

jumbatm

commit sha 8b392505ae8e5645f3f254caa8aff2a932df4d72

Fix non-determinism in generated format string.

view details

push time in 19 days

push eventjumbatm/rust

jumbatm

commit sha 7aabc86a1c8416b4bf65e8725423361aa2e803e6

Fix non-determinism in generated format string.

view details

push time in 19 days

create barnchjumbatm/rust

branch : issue76496-reproducibility-regression

created branch time in 19 days

issue commentrust-lang/rust

Reproducibility regression caused by 57edf88

Ah, my bad. I can take this.

@rustbot claim

jgalenson

comment created time in 19 days

issue commentrust-lang/rust

Incorrect MIR optimizations at level 3: local incorrectly marked dead

Diff for this case before/after SimplifyComparisonIntegral:

--- dead.main-test.005-004.SimplifyComparisonIntegral.before.mir 
+++ dead.main-test.005-004.SimplifyComparisonIntegral.after.mir
@@ -1,4 +1,4 @@
-// MIR for `test` before SimplifyComparisonIntegral
+// MIR for `test` after SimplifyComparisonIntegral
 
 fn test(_1: T) -> () {
     debug x => _1;                       // in scope 0 at dead.rs:4:43: 4:44
@@ -56,11 +56,12 @@
         StorageLive(_9);                 // scope 1 at dead.rs:6:9: 9:10
         _10 = Len((*_2));                // scope 1 at dead.rs:7:13: 7:37
         _11 = const 3_usize;             // scope 1 at dead.rs:7:13: 7:37
-        _12 = Eq(move _10, const 3_usize); // scope 1 at dead.rs:7:13: 7:37
-        switchInt(move _12) -> [false: bb1, otherwise: bb2]; // scope 1 at dead.rs:7:13: 7:37
+        nop;                             // scope 1 at dead.rs:7:13: 7:37
+        switchInt(move _10) -> [3_usize: bb2, otherwise: bb1]; // scope 1 at dead.rs:7:13: 7:37
     }
 
     bb1: {
+        StorageDead(_10);                // scope 1 at dead.rs:7:13: 7:37
         StorageLive(_22);                // scope 1 at /rust/library/std/src/macros.rs:13:23: 13:52
         begin_panic::<&str>(const "internal error: entered unreachable code"); // scope 1 at /rust/library/std/src/macros.rs:13:23: 13:52
                                          // mir::Constant
@@ -75,6 +76,7 @@
     }
 
     bb2: {
+        StorageDead(_10);                // scope 1 at dead.rs:7:13: 7:37
         StorageLive(_13);                // scope 1 at dead.rs:7:14: 7:20
         _13 = &(*_2)[0 of 3];            // scope 1 at dead.rs:7:14: 7:20
         StorageLive(_14);                // scope 1 at dead.rs:7:22: 7:28

Note the StorageDead(_10) placed in both successors of the switchInt, when there was no StorageLive(_10) to begin with.

cc @simonvandel -- along the lines of https://github.com/rust-lang/rust/pull/75370#issuecomment-680826582, you could leave the switchInt as a copy in this case for later optimisation passes to clean up. This is definitely a case I can cover for #75993.

RalfJung

comment created time in 20 days

issue commentrust-lang/rust

MIR building: Place should be moved if not used later

Hmm, it looks like SimplifyComparisonIntegral already converts that copy to a move for the example you gave:

Before:

// MIR for `f` before SimplifyComparisonIntegral

fn f(_1: i8) -> i8 {
...
    bb0: {
        StorageLive(_2);                 // scope 0 at switchInt.rs:4:9: 4:10
        _2 = _1;                         // scope 0 at switchInt.rs:4:13: 4:14
        StorageLive(_3);                 // scope 1 at switchInt.rs:5:8: 5:15
        StorageLive(_4);                 // scope 1 at switchInt.rs:5:8: 5:9
        _4 = _2;                         // scope 1 at switchInt.rs:5:8: 5:9
        _3 = Eq(move _4, const 42_i8);   // scope 1 at switchInt.rs:5:8: 5:15
        StorageDead(_4);                 // scope 1 at switchInt.rs:5:14: 5:15
        switchInt(_3) -> [false: bb1, otherwise: bb2]; // scope 1 at switchInt.rs:5:5: 5:32
    }
...
}

After:

// MIR for `f` after SimplifyComparisonIntegral                                                                                                     
                                                                                                                                                    
fn f(_1: i8) -> i8 {                                                                                                                                
...
    bb0: {
        StorageLive(_2);                 // scope 0 at switchInt.rs:4:9: 4:10
        _2 = _1;                         // scope 0 at switchInt.rs:4:13: 4:14
        StorageLive(_3);                 // scope 1 at switchInt.rs:5:8: 5:15
        StorageLive(_4);                 // scope 1 at switchInt.rs:5:8: 5:9
        _4 = _2;                         // scope 1 at switchInt.rs:5:8: 5:9
        _3 = Eq(_4, const 42_i8);        // scope 1 at switchInt.rs:5:8: 5:15
        nop;                             // scope 1 at switchInt.rs:5:14: 5:15
        switchInt(move _4) -> [42_i8: bb2, otherwise: bb1]; // scope 1 at switchInt.rs:5:5: 5:32
    }
...
    bb1: {
        StorageDead(_4);                 // scope 1 at switchInt.rs:5:5: 5:32
        ...
    }
    bb2: {
        StorageDead(_4);                 // scope 1 at switchInt.rs:5:5: 5:32
        ...
   }
...
}

I'm now trying to understand this comment here: https://github.com/rust-lang/rust/pull/75370#issuecomment-678792210 to see whether I can chip in. In the code you linked, you mention that your pass generates code that moves _3 twice, but I only see a single move _3. Are you instead referring to that you generate two StorageDead(_3) statements, the same thing happens for _4 here?

simonvandel

comment created time in 23 days

issue commentrust-lang/rust

MIR building: Place should be moved if not used later

Great, thanks!

@rustbot claim

simonvandel

comment created time in 25 days

issue commentrust-lang/rust

MIR building: Place should be moved if not used later

pass that promotes copies to moves

Hi, I'm interested in implementing this. @simonvandel -- I know this issue came up on your PR. Were you intending on also taking this?

simonvandel

comment created time in 25 days

PR closed rust-lang/rust

Deny clashing extern declarations by default. S-waiting-on-review

Changes the clashing_extern_declarations lint to be deny by default, as the lint addresses a soundness issue (see #70496).

Note that this change should go through a crater-check run before being merged (as mentioned in https://github.com/rust-lang/rust/pull/70946#issuecomment-632084879).

r? @nagisa

+4 -39

10 comments

4 changed files

jumbatm

pr closed time in a month

pull request commentrust-lang/rust

Deny clashing extern declarations by default.

I took a closer look at the regressed (by clashing_extern_declarations) crates. As a summary:

  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/gh/1000VICKY.ishell_in_Rust/log.txt -- redeclares printf in various, inconsistent ways. I believe the lint is correct -- the correct, consistent signature should be with varargs.
  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/gh/rybot666.bootloader/log.txt is an interesting case. There's a clash in the function signature _improper_ctypes_check which isn't used anywhere; it looks like the function exists to check certain structures for improper_ctypes that aren't otherwise used locally in any extern C functions.
    • Ditto for https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/reg/os_bootinfo-0.2.1/log.txt
  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/reg/awi-0.8.0/log.txt redeclares free for a number of structures, instead of consistently declaring it with a *const c_void parameter.
  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/reg/gli-rs-0.4.0/log.txt-- the clash appears in generated code, and appears to be by-design -- the external function must do some kind of runtime typechecking that makes the call safe
  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/reg/os_bootinfo-0.2.1/log.txt is an error on the same code as in rybot666.bootloader
  • https://crater-reports.s3.amazonaws.com/pr-75192/try%23169954edd744527414c631e9af1bbdc537b0cdf2/reg/vrust-0.0.1/log.txt is for a clash between an empty type enum xcb_connection_t { } and zero-sized type struct xcb_connection_t { [0; u32]; } that are both used opaquely. From what I understand, there's no memory unsafety here, but they're semantically not quite the same because the zst can be instantiated, while the empty type cannot. Again, appears in generated code.

Given these results, and some further reflection, I don't think we should proceed with making clashing_extern_declarations deny because

  • It would break builds using generated code (until tools like bindgen were updated, anyway)
  • Without knowing the behaviour of the external C code, I feel like we don't really have all the information we need to warrant erroring out the build -- gli being an example of this

Thinking about this more, I also realise the user doesn't really get any more value out of making the lint deny-by-default: as a warning, the lint already pushes the user to fix mistakes in the extern function declaration or allow the clash if they know it's safe.

For these reasons, I'm going to close this PR. Feel free to re-open -- I'm happy to discuss further.

jumbatm

comment created time in a month

push eventjumbatm/rust

Philippe Nadon

commit sha 2d1515a2c532b0cceec4a14da6f21e48fdca2da5

Miri: Renamed "undef" to "uninit" Renamed remaining references to "undef" to "uninit" when referring to Miri. Impacted directories are: - src/librustc_codegen_llvm/consts.rs - src/librustc_middle/mir/interpret/ - src/librustc_middle/ty/print/pretty.rs - src/librustc_mir/ - src/tools/clippy/clippy_lints/src/consts.rs Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project. Related issue #71193

view details

Wim Looman

commit sha a8de713e26cb0f8e8ae4a7ecb0bf8a413b539926

Improve rendering of crate features via doc(cfg)

view details

Wim Looman

commit sha 234ec956ab91d4aef51b63f25b78d176aa364a60

Render longhand multiple crate/target features nicer

view details

Tim Nielens

commit sha a77e881ec9f324cdc544150f897d8b34281f92e4

should_impl_trait - ignore methods with lifetime params

view details

Tim Nielens

commit sha 2bc0ecd44b4d09476eade641e02451d949a1c8e2

should_implement_trait - add test cases for every checked trait method

view details

Tim Nielens

commit sha e6b2254f9e55743dbace44cc73c6447b6bda58e5

should_implement_trait - pr remarks

view details

Tim Nielens

commit sha 7cc1a2ed879e45605a53b802cfa5291c9a51284c

should_implement_trait - filter on explicit lifetime param only

view details

Tim Nielens

commit sha 166c520e9a8b1a45819255e75dee737136aa6ec8

should_impl_trait - pr comments

view details

Tim Nielens

commit sha f9ba829f6701ae03a5c226044dbbde13ce87e123

should_impl_trait - self linting

view details

Ryan Wiedemann

commit sha 3e3e50bf0fa6282c7265e34589170033c2301edd

Add example of false positive to PTR_ARG docs. Fixes #214

view details

Ryan Wiedemann

commit sha fbf637d12c95528846bfa65ce67bd652f2affb43

formatting

view details

Yuki Okushi

commit sha 91aa55d891e029831e2eceb662184afc8d2e0415

Rollup merge of #75226 - pnadon:miri-undef-uninit, r=RalfJung Miri: Renamed "undef" to "uninit" Renamed remaining references to "undef" to "uninit" when referring to Miri. Impacted directories are: - `src/librustc_codegen_llvm/consts.rs` - `src/librustc_middle/mir/interpret/` - `src/librustc_middle/ty/print/pretty.rs` - `src/librustc_mir/` - `src/tools/clippy/clippy_lints/src/consts.rs` Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project. Related issue #71193

view details

Matthias Krüger

commit sha b8713e3854cb90b974eceaa1d50484831591619c

unnecessary-mut-passed: make lint message say if fn is a function or a method.

view details

bors

commit sha 3337f7956cf6100c9e5acfd72d42ec312efb6a7f

Auto merge of #5892 - matthiaskrgr:redundant_mut, r=flip1995 unnecessary-mut-passed: make lint message say if fn is a function or a method changelog: refine "unnecessary-mut-passed" lint message

view details

Matthias Krüger

commit sha c0a9d64818d7076b72fd6c3a9e6172eca659034b

stable-sort-primitive: make lint adhere to lint message convention

view details

Matthias Krüger

commit sha ac194cafc124276d4614bf023ca7ea6e9be9c6ed

map_clone: make lint adhere to lint message convention

view details

Matthias Krüger

commit sha 04867e004ebc0f2edf66d0a457e785848451f13a

mutex-atomic: make lint adhere to lint message convention

view details

Matthias Krüger

commit sha 6af297f80e59050c87078f1ba6f05c97d6f90fd7

iter-next-slice: make lint adhere to lint message convention

view details

Matthias Krüger

commit sha f171f89aed11043e459c3baab305e7f859debb94

int_plus_one: make lint adhere to lint message convention

view details

Matthias Krüger

commit sha bdf4dc3abd9a49f699d9de209a1f4d55ce770191

implicit-saturating-sub: make lint adhere to lint message convention

view details

push time in a month

pull request commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

Sure thing. This should be good to go once green.

jumbatm

comment created time in a month

push eventjumbatm/rust

Dylan McKay

commit sha d785f9ba76be199a47652f5841260a42390f611b

[AVR] Replace broken 'avr-unknown-unknown' target with 'avr-unknown-gnu-atmega328' target The `avr-unknown-unknown` target has never worked correctly, always trying to invoke the host linker and failing. It aimed to be a mirror of AVR-GCC's default handling of the `avr-unknown-unknown' triple (assume bare minimum chip features, silently skip linking runtime libraries, etc). This behaviour is broken-by-default as it will cause a miscompiled executable when flashed. This patch improves the AVR builtin target specifications to instead expose only a 'avr-unknown-gnu-atmega328' target. This target system is `gnu`, as it uses the AVR-GCC frontend along with avr-binutils. The target triple ABI is 'atmega328'. In the future, it should be possible to replace the dependency on AVR-GCC and binutils by using the in-progress AVR LLD and compiler-rt support. Perhaps at that point it would make sense to add an 'avr-unknown-unknown-atmega328' target as a better default when implemented. There is no current intention to add in-tree AVR target specifications for other AVR microcontrollers - this one can serve as a reference implementation for other devices via `rustc --print target-spec-json avr-unknown-gnu-atmega328p`. There should be no users of the existing 'avr-unknown-unknown' Rust target as a custom target specification JSON has always been recommended, and the avr-unknown-unknown target could never pass the linking step anyway.

view details

Dylan McKay

commit sha 53b940c74c4f56ef075ee3c71f3cb157aaff65af

[AVR] Remove unnecessary arguments passed to the linker for GNU target In general, linking with libc is not required, only libgcc is needed. As suggested in the code review, a better option for libc support is by building it into rust-lang/libc directly. This also removes the '-Os' argument to the linker, which is a NOP.

view details

Dylan McKay

commit sha dc2023801281dd21f04c97fc4ec073c02b2abd46

[AVR] Merge the 'freestanding' base target spec into AVR base target spec The 'freestanding' module was only ever used for AVR. It was an unnecessary layer of abstraction. This commit merges the 'freestanding_base' module into 'avr_gnu_base'.

view details

Dylan McKay

commit sha a0905ceff9e8a80aa39bb38dda2e74bddebe613d

[AVR] Rename the last few remaining references from 'avr-unknown-unknown' to 'avr-unknown-gnu-atmega328'

view details

Dylan McKay

commit sha c9ead8c895593452677a229fd19909c83283b33f

[AVR] Replace 'avr-unknown-unknown' with 'avr-unknown-gnu-atmega328' in platform-support.md

view details

Aaron Hill

commit sha b5b8b9329b3a118879bad6c476612d49f89461a3

Point to a move-related span when pointing to closure upvars Fixes #75904 When emitting move/borrow errors, we may point into a closure to indicate why an upvar is used in the closure. However, we use the 'upvar span', which is just an arbitrary usage of the upvar. If the upvar is used in multiple places (e.g. a borrow and a move), we may end up pointing to the borrow. If the overall error is a move error, this can be confusing. This PR tracks the span that caused an upvar to become captured by-value instead of by-ref (assuming that it's not a `move` closure). We use this span instead of the 'upvar' span when we need to point to an upvar usage during borrow checking.

view details

Pietro Albini

commit sha e88d79ca41181f5f306fe2ef25510318556bc963

bump version to 1.48

view details

Pietro Albini

commit sha 3e16d4af7f6b0524434e758331a7cb3013a69791

apply bootstrap cfgs

view details

Pietro Albini

commit sha 1b6590c9f4104df7d168474edf3c0ab966b44108

forgot to remove a cfg(not(bootstrap))

view details

bors

commit sha 118860a7e76daaac3564c7655d46ac65a14fc612

Auto merge of #75947 - pietroalbini:bootstrap-update, r=Mark-Simulacrum Bump version to 1.48 and update cfg(bootstrap)s r? @Mark-Simulacrum

view details

Guillaume Gomez

commit sha 1727c7a194187af70f44f3f5b160eea8439cbc6d

Improve helper wording

view details

Guillaume Gomez

commit sha 86e42c2742423aacbf70ba49c499a83846f57712

Delay help popup creation to when it's needed

view details

bors

commit sha 3d0c847d3353e319ed82598a106e28fd490caa6b

Auto merge of #74941 - dylanmckay:replace-broken-avr-unknown-unknown-target, r=oli-obk [AVR] Replace broken 'avr-unknown-unknown' target with 'avr-unknown-gnu-atmega328' target The `avr-unknown-unknown` target has never worked correctly, always trying to invoke the host linker and failing. It aimed to be a mirror of AVR-GCC's default handling of the `avr-unknown-unknown' triple (assume bare minimum chip features, silently skip linking runtime libraries, etc). This behaviour is broken-by-default as it will cause a miscompiled executable when flashed. This patch improves the AVR builtin target specifications to instead expose only a 'avr-unknown-gnu-atmega328' target. This target system is `gnu`, as it uses the AVR-GCC frontend along with avr-binutils. The target triple ABI is 'atmega328'. In the future, it should be possible to replace the dependency on AVR-GCC and binutils by using the in-progress AVR LLD and compiler-rt support. Perhaps at that point it would make sense to add an 'avr-unknown-unknown-atmega328' target as a better default when implemented. There is no current intention to add in-tree AVR target specifications for other AVR microcontrollers - this one can serve as a reference implementation for other devices via `rustc --print target-spec-json avr-unknown-gnu-atmega328p`. There should be no users of the existing 'avr-unknown-unknown' Rust target as a custom target specification JSON has always been recommended, and the avr-unknown-unknown target could never pass the linking step anyway.

view details

bors

commit sha 132f5fc2e5247cf5dab74e5a4408135056852c30

Auto merge of #75933 - Aaron1011:feature/closure-move-err, r=oli-obk Point to a move-related span when pointing to closure upvars Fixes #75904 When emitting move/borrow errors, we may point into a closure to indicate why an upvar is used in the closure. However, we use the 'upvar span', which is just an arbitrary usage of the upvar. If the upvar is used in multiple places (e.g. a borrow and a move), we may end up pointing to the borrow. If the overall error is a move error, this can be confusing. This PR tracks the span that caused an upvar to become captured by-value instead of by-ref (assuming that it's not a `move` closure). We use this span instead of the 'upvar' span when we need to point to an upvar usage during borrow checking.

view details

Pietro Albini

commit sha 19e70bf82265134d988810e4549d3b514211271b

ci: disable cancel-outdated-builds for auto-fallible

view details

Amanieu d'Antras

commit sha 239f833ed1842ce7ce5c9989871a9ce9b1ea3546

Abort when catch_unwind catches a foreign exception

view details

bors

commit sha 397b390cc76ba1d98f80b2a24a371f708dcc9169

Auto merge of #75976 - GuillaumeGomez:help-popup, r=jyn514 Improve help popup Fixes #75623. The second commit is just a slight improvement: the help popup won't be created until someone presses "?" or ESC. Not a big improvement in itself but considering the low amount of code required, I think it was worth the shot. r? @jyn514

view details

bors

commit sha 2aa741a9faf8519d3af98aba610677c8d2bc84a5

Auto merge of #75995 - pietroalbini:ci-let-fallible-finish, r=Mark-Simulacrum Disable cancel-outdated-builds for auto-fallible `cancel-outdated-builds` doesn't need to be enabled on fallible jobs, and it's actually making it harder for us to see if https://github.com/rust-lang/rust/issues/71988 is fixed. This adds some temporary code to avoid `auto-fallible` jobs from being cancelled by our tooling. r? @Mark-Simulacrum

view details

bors

commit sha 41aaa90c67cdb04cac7427756891ad04c3e0bebf

Auto merge of #70212 - Amanieu:catch_foreign, r=Mark-Simulacrum Abort when foreign exceptions are caught by catch_unwind Prior to this PR, foreign exceptions were not caught by catch_unwind, and instead passed through invisibly. This represented a painful soundness hole in some libraries ([take_mut](https://github.com/Sgeo/take_mut/blob/master/src/lib.rs#L37)), which relied on `catch_unwind` to handle all possible exit paths from a closure. With this PR, foreign exceptions are now caught by `catch_unwind` and will trigger an abort since catching foreign exceptions is currently UB according to the latest proposals by the FFI unwind project group. cc @rust-lang/wg-ffi-unwind

view details

jumbatm

commit sha 031dd09a042f3e46a598839d8ad70a68c9928285

Add SessionDiagnostic derive macro. Co-authored-by: Oliver Scherer <github35764891676564198441@oli-obk.de>

view details

push time in a month

push eventjumbatm/rust

Brian Cain

commit sha 2ca1e59bb60e27abc858fc271b91ef5ba4f6b6a6

Hexagon libstd: update type defs

view details

Aaron Hill

commit sha 5f7436b5fd27e534b2800389067b169cbe7864b7

Be consistent when describing a move as a 'partial' in diagnostics When an error occurs due to a partial move, we would use the world "partial" in some parts of the error message, but not in others. This commit ensures that we use the word 'partial' in either all or none of the diagnostic messages. Additionally, we no longer describe a move out of a `Box` via `*` as a 'partial move'. This was a pre-existing issue, but became more noticable when the word 'partial' is used in more places.

view details

Ryan Levick

commit sha 57572cf8096ccb332370f7a711641a061bfd7434

Call into fastfail on abort in libpanic_abort on Windows x86(_64)

view details

Ryan Levick

commit sha 6778baf516cf00d6ba2d3f448aa312b4ac2e43b5

Fix up docs

view details

Ryan Levick

commit sha b9b8b5c96b60789b6b7846a4036d3cbf2d393014

Reverse formatting

view details

Lzu Tao

commit sha 768509ff84d8527e587df68ecfc4ed962b9f5f2a

Minor changes to Ipv4Addr * Impl IntoInner rather than AsInner for Ipv4Addr * Add some comments * Add test to show endiannes of Ipv4Addr display

view details

Tim Diekmann

commit sha 438c40efa109d7a4d83efa066c19cb95dad9ed94

Allow reallocation to different alignment

view details

Mateusz Mikuła

commit sha fbce8785d4ca784006ff84d8226befe8b372decd

Fix windows-gnu host cross-compilation

view details

Tim Diekmann

commit sha 303ee3fd8382947d0da7a728c728bc672dc0f7be

Add debug assertion for equal alignment in RawVec

view details

Tim Diekmann

commit sha 46b547cb5861febd3e0401acb0af6f65be775948

Assume same alignment in `RawVec`

view details

Jubilee Young

commit sha 31afacf65182ef2db32e140b8ab6fe2c75a6daa7

bump tidy to cargo_metadata 0.11 Updates cargo_metadata in tidy's Cargo.toml from 0.9.1 to 0.11 Real version change 0.9.11 -> 0.11.1 https://github.com/oli-obk/cargo_metadata/compare/v0.9.1...v0.11.1

view details

Wesley Wiser

commit sha 8dea3088c6f36455a6d0a2eb7eaf7a81414ce967

Add a CGU partitioning trait This will allow us to prototype different partitioning schemes without adding a lot of extra conditionals everywhere.

view details

Wesley Wiser

commit sha 5d501f9cd21da6a175a51341ffdd83e7896c01e2

Split partitioning.rs into a module

view details

Wesley Wiser

commit sha 98b943e7d821aff17fefbf1a094503f9ae172a4a

Add partitioning -Z option to control which partitioning scheme is used

view details

Dylan MacKenzie

commit sha 766fcb0b01986396b2b87ba194dcd4392b57b613

Refactor dynamic library error checking on *nix The old code was checking `dlerror` more often than necessary, since the return value of `dlopen` indicates whether an error occurred.

view details

Dylan MacKenzie

commit sha e2326a1eecfe5562712649e8696c579bc919a9af

Treat a NULL return from `dlsym` as an error on illumos This works around behavior observed on illumos in #74469, in which foreign code (libc according to the OP) was racing with rustc to check `dlerror`.

view details

Oliver Middleton

commit sha 57e7e2875b3bb571703cbaa11aac92efea434f04

Update docs for SystemTime Windows implementation Windows now uses `GetSystemTimePreciseAsFileTime` on versions of Windows that support it.

view details

Guillaume Gomez

commit sha 6cb364cda47d960d08b8e7fb03d0df0e9bdbd190

Prevent automatic page change when using history

view details

DPC

commit sha 4cc2cabee25a2ea74d13720c980bfd0379b9945a

change offset from u32 to u64

view details

Guillaume Gomez

commit sha 5041aeef3d4155ac28245419193280491552fd35

Fix font color for help button in ayu and dark themes

view details

push time in a month

push eventjumbatm/rust

jumbatm

commit sha 4f8a84cd123d527f0d5133260d1cc25a55a292bc

fixup! squash! Start replacing struct_span_err!s in rustc_typeck.

view details

jumbatm

commit sha 8c1b178dcc580eee489c819f8ea30b06566cf0d7

squash! Start replacing struct_span_err!s in rustc_typeck.

view details

jumbatm

commit sha 414ea88703f8a32ec67775107472cd656f6fc590

Fix 'conflicting lifetime' error when using 'a.

view details

push time in a month

issue commentrust-lang/rust

compiler bug: Unexpected panic

Not a problem! Thank you for the report, and especially for taking the time to make a minimal example :)

Volker-Weissmann

comment created time in a month

push eventjumbatm/rust

jumbatm

commit sha 8c0128bb02ef528588777bda1e818e72749a7006

Fix ICE on unwrap of unknown layout.

view details

push time in a month

create barnchjumbatm/rust

branch : issue-75924-clashing-extern-decl-ice

created branch time in a month

issue commentrust-lang/rust

compiler bug: Unexpected panic

@rustbot claim

Volker-Weissmann

comment created time in a month

pull request commentrust-lang/rust

Fix another clashing_extern_declarations false positive.

Should be good to go once green.

jumbatm

comment created time in a month

push eventjumbatm/rust

jumbatm

commit sha 671770ed852daf803e6a49fc9b622a4a2e478efb

Also handle transparent single-variant enums

view details

jumbatm

commit sha 2ea86af1eaed20227a6176995aa6c082f245924c

Use same name as attr. Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

jumbatm

commit sha 352df40df53e0b559ecefcd5a4409ec43143c645

Remove unnecessary assert.

view details

push time in a month

push eventjumbatm/rust

jumbatm

commit sha a678150dc89ff95c9bb5c7a20593fb4bc255bf2e

Use same name as attr. Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

push time in a month

Pull request review commentrust-lang/rust

Fix another clashing_extern_declarations false positive.

 mod missing_return_type {             // the correct one -- if this one is the correct one, then calling the usize-returning             // version would allow reads into uninitialised memory.             fn missing_return_type();-            //~^ WARN `missing_return_type` redeclared with a different signature+        //~^ WARN `missing_return_type` redeclared with a different signature

Oops, no, these were from rustfmt

jumbatm

comment created time in a month

PullRequestReviewEvent

push eventjumbatm/rust

Leon Matthes

commit sha e6c83dd57b920d2069797736ae0a1c9fe14a97cb

Document that slice means pointer to a sequence Also document that slices are twice as large as pointers to Sized types

view details

Leon Matthes

commit sha a9af93beebe183d716c0e7313ff8a0fb79b27b6b

Add missing period

view details

Leon Matthes

commit sha 41d3e1cf738b6bfe1c7f85ad09b2adea9c8744e8

Add missing import to Rc

view details

DPC

commit sha 76b99d5f1d3eac78a4c4a383e42339fc88affeac

Add Arc::new_cyclic

view details

DPC

commit sha db34e352a7983bf5a4584e93e54362ef45b70b58

fix duplicated feature gate

view details

DPC

commit sha fdc2d1f49906752585177e99b8bc285d796e4b3e

add missing newline

view details

DPC

commit sha 9ad17b9ca7a0fce32abf4c85ee38ed14aefe39cf

tidy up

view details

Wonwoo Choi

commit sha c4fb3f297b36e902369a3f62214274149865e6e2

Provide better spans for the match arm without tail expression

view details

Joshua Nelson

commit sha 344a42e66eb9f78de7926df10e85ab51ba1aa69f

resolve: Move `get_traits_in_module_containing_item` to Resolver

view details

Joshua Nelson

commit sha 0647a48dc5ad98c2c7279889a5b5de2e0505c251

resolve: Split `ensure_traits` into a separate function

view details

Joshua Nelson

commit sha 9ed91f363afdea6c6619f4d017c2e583192c7347

resolve: Add public entrypoint `traits_in_module` - Consider the implicit prelude as well

view details

Joshua Nelson

commit sha a97d65d6e474e86cad99cd833a5cd2ba32eb678f

rustdoc: Rename misleading function - `is_associated` -> `is_type_alias` `is_associated` is not a good name for what this is doing. If you look at https://github.com/rust-lang/rust/pull/74489/files#diff-6a301d597807ee441a41e7237800563dR296, is_associated() and as_assoc_kind() do completely different things, but from the name it sounds like they're similar.

view details

Joshua Nelson

commit sha 42232ba70add056cf422960ac96986264870b313

rustdoc: Add support for associated items even outside the impl itself Previously, associated items would only be available for linking directly on the `impl Trait for Type`. Now they can be used anywhere. - Make `item` for resolve mandatory - Refactor resolving associated items into a separate function - Remove broken trait_item logic - Don't skip the type namespace for associated items - Only call `variant_field` for `TypeNS` - Add test for associated items - Use exhaustive matches instead of wildcards Wildcards caused several bugs while implementing this.

view details

Joshua Nelson

commit sha 9db0b86f4e24c939cd33cff050ce556faf30e47d

rustdoc: Cache traits implemented by a type This avoids taking the slow path several thousand times in a row. - Fallback to all traits if the traits in scope are unknown - Use a rustdoc thread_local cache instead of a query The set of traits implemented by a type is not stable across crates: there could be new traits added in a new crate. - Use DocContext instead of a thread-local

view details

Joshua Nelson

commit sha da921e97f4d3702ab60fb696699712444e8ec48f

rustdoc: Only resolve traits in scope

view details

Matthias Krüger

commit sha a2a387c7332f568fcc27186578254f6923994742

compiletest: fix a couple clippy lint findings

view details

Ralf Jung

commit sha 1241f1927eb1a8d2c87c2ada680afb16424862e5

offset_from: also document same-provenance requirement

view details

Ralf Jung

commit sha 7ad4369ba695b37b6f758ef94ff28597e840bc32

remove deprecated wrapping_offset_from

view details

Ralf Jung

commit sha 0e4f335e634d16f399647353dd70666423e402b4

stabilize ptr_offset_from

view details

Ralf Jung

commit sha 4f92f0d31bcdb25ab54e2deffa7f194c13d1c7ee

remove feature gate from tests

view details

push time in a month

Pull request review commentrust-lang/rust

Fix another clashing_extern_declarations false positive.

 impl ClashingExternDeclarations {             ckind: CItemKind,         ) -> bool {             debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b);+            let tcx = cx.tcx;++            // Given a transparent newtype, reach through and grab the inner+            // type unless the newtype makes the type non-null.+            let non_transparent_ty = |ty: Ty<'tcx>| -> Ty<'tcx> {+                let mut ty = ty;+                loop {+                    if let ty::Adt(def, substs) = ty.kind {+                        let is_transparent = def.subst(tcx, substs).repr.transparent();+                        let is_enum = def.is_enum();+                        let is_non_null = crate::types::guaranteed_nonnull_optimization(tcx, &def);+                        debug!(+                            "non_transparent_ty({:?}) -- type is transparent? {}, type is enum? {}, type is non-null? {}",+                            ty, is_transparent, is_enum, is_non_null+                        );+                        if is_transparent && !is_enum && !is_non_null {

Ah, true -- thanks!

jumbatm

comment created time in a month

PullRequestReviewEvent

push eventjumbatm/rust

jumbatm

commit sha 5b7e044a446f2d7a2ce9e6ff2192566ab6fd0dfc

Also handle transparent single-variant enums

view details

push time in a month

PR opened rust-lang/rust

Fix another clashing_extern_declarations false positive.

Fixes #75739.

Fix another clashing_extern_declarations false positive, this time for transparent newtype with a non-zero member.

r? @lcnr

+101 -9

0 comment

4 changed files

pr created time in a month

push eventjumbatm/rust

Vadim Petrochenkov

commit sha 712de2b5211ec9aad434358d459e843ca9a4622d

rustc_expand: Don not beautify doc comments before passing them to macros Beautify all doc strings in rustdoc instead, including those in `#[doc]` attributes

view details

Vadim Petrochenkov

commit sha 6b25c50ed467396c367d41eca6b8248136140974

Fix clippy

view details

Vadim Petrochenkov

commit sha d642c3b6f8d9679ee4fab5ffc6899f96071a0df0

Fix clippy

view details

Vadim Petrochenkov

commit sha a7eabec1df53fe726455c8088ecc0da07dd4009d

Add some comments for magic numbers + Add tests

view details

Vadim Petrochenkov

commit sha a285b5836883affe23e3d160013aaee0e74bd981

Add some comments for magic numbers + Add tests

view details

bors

commit sha 71f8d0c8f1060bbe74100f29cc6f2da63d697c28

Auto merge of #75228 - tmiasko:keep-stdout-open, r=ecstatic-morse Keep stdout open in limit_vector_count test

view details

Bastian Kauschke

commit sha 37c29adabc638f9c601daf5b78d0f6de63e35f99

allow complex expressions in assoc consts

view details

Nicholas Nethercote

commit sha ebbf07a1544151867e20ff75f740836aba1ff73a

Change the type of `AssertModuleSource::available_cgus`. It's currently a `BTreeSet<Symbol>`, which is a strange type. The `BTreeSet` suggests that element order is important, but `Symbol` is a type whose ordering isn't useful to humans. The ordering of the collection only manifests in an obscure error message ("no module named `...`") that doesn't appear in any tests. This commit changes the `Symbol` to a `String`, which is more typical.

view details

Joshua Nelson

commit sha f05e9da493a9e447dd2dafc271b06ad80358496f

Still print help even if there's no span

view details

Leijurv

commit sha 6eeae7d42013cc5deab74a43010721b98847c80d

Fix typo "TraitObligatiom" -> "TraitObligation"

view details

Ralf Jung

commit sha 854d8e8ceb78bb4fc0daf876518d0b0e323e0d22

update Miri

view details

Joshua Nelson

commit sha 0c99d806eabd32a2ee2e6c71b400222b99c659e1

Use the proper kind for associated items See comments in the diff; this is such a hack. The reason this can't be done properly in `register_res` is because there's no way to get back the parent type: calling `tcx.parent(assoc_item)` gets you the _impl_, not the type. You can call `tcx.impl_trait_ref(impl_).self_ty()`, but there's no way to go from that to a DefId without unwrapping.

view details

Amanieu d'Antras

commit sha b5cef24f5f82531403ecb3cf65f5ee045c349b1f

Update asm! documentation in unstable book - Update the list of supported architectures. - Clarify issues with LLVM's use of reserved registers.

view details

Joshua Nelson

commit sha ef54cde625966d4c103e067506ba31b3b79efec4

Improve tests

view details

Joshua Nelson

commit sha d240490229b31e1ebd6871a08ee2cefeb580ba78

Fix outdated code

view details

Joshua Nelson

commit sha 17263bc2da9fe312556afe0812db82e9f41b9a6e

Remove dead code

view details

Izzy Swart

commit sha b809f453cac600acef9de5fedb457f842563266c

Fix typo "biset" -> "bitset"

view details

Yuki Okushi

commit sha 9d5bd597ac2a7b00a5337677d8da49b1f8f58bb0

Rollup merge of #74888 - infinity0:ignore-endian-big, r=nikomatsakis compiletest: ignore-endian-big, fixes #74829, fixes #74885 See discussion on #74829 I tested it on a Debian s390x machine, works well.

view details

Yuki Okushi

commit sha c9c7048038d3776815f0952dcb15a7290297f8f5

Rollup merge of #75175 - lzutao:doctest-ipv4-fromu32, r=cuviper Make doctests of Ipv4Addr::from(u32) easier to read There are many zeroes in `0x0d0c0b0au32` which makes it hard to read.

view details

Yuki Okushi

commit sha 1b61fd3ccf1b646ec2bbf627df09040bec97bcae

Rollup merge of #75179 - lzutao:unsed-ipv4-frominner, r=alexcrichton Remove unused FromInner impl for Ipv4Addr The removed is a unused unstable implementation.

view details

push time in a month

issue openedrust-lang/rust

Additional incorrect clashing_extern_decl warning for `#[repr(transparent)]` non-zero types

It seems that there is a case still not being fixed, when #[repr(transparent)] is used with non-zero types.

mod a {
    use std::num::NonZeroUsize;
    extern "C" {
        fn a() -> NonZeroUsize;
    }
}

mod b {
    #[repr(transparent)]
    struct X(NonZeroUsize);
    use std::num::NonZeroUsize;
    extern "C" {
        fn a() -> X;
    }
}

Originally posted by @nbdd0121 in https://github.com/rust-lang/rust/issues/73735#issuecomment-677152928

created time in a month

issue commentrust-lang/rust

Incorrect clashing_extern_decl warning in nightly

Thanks, I'll open another issue for this case.

nbdd0121

comment created time in a month

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

+#![deny(unused_must_use)]+use quote::format_ident;+use quote::quote;++use proc_macro::Diagnostic;+use syn::spanned::Spanned;++use std::collections::{HashMap, HashSet};++/// Implements #[derive(SessionDiagnostic)], which allows for errors to be specified as a struct, independent+/// from the actual diagnostics emitting code.+/// ```ignore (pseudo-rust)+/// # extern crate rustc_errors;+/// # use rustc_errors::Applicability;+/// # extern crate rustc_span;+/// # use rustc_span::{symbol::Ident, Span};+/// # extern crate rust_middle;+/// # use rustc_middle::ty::Ty;+/// #[derive(SessionDiagnostic)]+/// #[code = "E0505"]+/// #[error = "cannot move out of {name} because it is borrowed"]+/// pub struct MoveOutOfBorrowError<'tcx> {+///     pub name: Ident,+///     pub ty: Ty<'tcx>,+///     #[label = "cannot move out of borrow"]+///     pub span: Span,+///     #[label = "`{ty}` first borrowed here"]+///     pub other_span: Span,+///     #[suggestion(message = "consider cloning here", code = "{name}.clone()")]+///     pub opt_sugg: Option<(Span, Applicability)>+/// }+/// ```+/// Then, later, to emit the error:+///+/// ```ignore (pseudo-rust)+/// sess.emit_err(MoveOutOfBorrowError {+///     expected,+///     actual,+///     span,+///     other_span,+///     opt_sugg: Some(suggestion, Applicability::MachineApplicable),+/// });+/// ```+pub fn session_diagnostic_derive(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {+    // Names for the diagnostic we build and the session we build it from.+    let diag = format_ident!("diag");+    let sess = format_ident!("sess");++    SessionDiagnosticDerive::new(diag, sess, s).into_tokens()+}++// Checks whether the type name of `ty` matches `name`.+//+// Given some struct at a::b::c::Foo, this will return true for c::Foo, b::c::Foo, or+// a::b::c::Foo. This reasonably allows qualified names to be used in the macro.+fn type_matches_path(ty: &syn::Type, name: &[&str]) -> bool {+    if let syn::Type::Path(ty) = ty {+        ty.path+            .segments+            .iter()+            .map(|s| s.ident.to_string())+            .rev()+            .zip(name.iter().rev())+            .all(|(x, y)| &x.as_str() == y)+    } else {+        false+    }+}++/// The central struct for constructing the as_error method from an annotated struct.+struct SessionDiagnosticDerive<'a> {+    structure: synstructure::Structure<'a>,+    builder: SessionDiagnosticDeriveBuilder<'a>,+}++impl std::convert::From<syn::Error> for SessionDiagnosticDeriveError {+    fn from(e: syn::Error) -> Self {+        SessionDiagnosticDeriveError::SynError(e)+    }+}++/// Equivalent to rustc:errors::diagnostic::DiagnosticId, except stores the quoted expression to+/// initialise the code with.+enum DiagnosticId {+    Error(proc_macro2::TokenStream),+    Lint(proc_macro2::TokenStream),+}++#[derive(Debug)]+enum SessionDiagnosticDeriveError {+    SynError(syn::Error),+    ErrorHandled,+}++impl SessionDiagnosticDeriveError {+    fn to_compile_error(self) -> proc_macro2::TokenStream {+        match self {+            SessionDiagnosticDeriveError::SynError(e) => e.to_compile_error(),+            SessionDiagnosticDeriveError::ErrorHandled => {+                // Return ! to avoid having to create a blank DiagnosticBuilder to return when an+                // error has already been emitted to the compiler.+                quote! {+                    unreachable!()+                }+            }+        }+    }+}++fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnostic {+    Diagnostic::spanned(span, proc_macro::Level::Error, msg)+}++/// For methods that return a Result<_, SessionDiagnosticDeriveError>: emit a diagnostic on+/// span $span with msg $msg (and, optionally, perform additional decoration using the FnOnce+/// passed in `diag`). Then, return Err(ErrorHandled).+macro_rules! throw_span_err {+    ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }};+    ($span:expr, $msg:expr, $f:expr) => {{+        return Err(_throw_span_err($span, $msg, $f));+    }};+}++/// When possible, prefer using throw_span_err! over using this function directly. This only exists+/// as a function to constrain `f` to an impl FnOnce.+fn _throw_span_err(+    span: impl proc_macro::MultiSpan,+    msg: &str,+    f: impl FnOnce(proc_macro::Diagnostic) -> proc_macro::Diagnostic,+) -> SessionDiagnosticDeriveError {+    let diag = span_err(span, msg);+    f(diag).emit();+    SessionDiagnosticDeriveError::ErrorHandled+}++impl<'a> SessionDiagnosticDerive<'a> {+    fn new(diag: syn::Ident, sess: syn::Ident, structure: synstructure::Structure<'a>) -> Self {+        // Build the mapping of field names to fields. This allows attributes to peek values from+        // other fields.+        let mut fields_map = HashMap::new();++        // Convenience bindings.+        let ast = structure.ast();++        if let syn::Data::Struct(syn::DataStruct { fields, .. }) = &ast.data {+            for field in fields.iter() {+                if let Some(ident) = &field.ident {+                    fields_map.insert(ident.to_string(), field);+                }+            }+        }++        Self {+            builder: SessionDiagnosticDeriveBuilder { diag, sess, fields: fields_map, kind: None },+            structure,+        }+    }+    fn into_tokens(self) -> proc_macro2::TokenStream {+        let SessionDiagnosticDerive { structure, mut builder } = self;++        let ast = structure.ast();+        let attrs = &ast.attrs;++        let implementation = {+            if let syn::Data::Struct(..) = ast.data {+                let preamble = {+                    let preamble = attrs.iter().map(|attr| {+                        builder+                            .generate_structure_code(attr)+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    quote! {+                        #(#preamble)*;+                    }+                };++                let body = structure.each(|field_binding| {+                    let field = field_binding.ast();+                    let result = field.attrs.iter().map(|attr| {+                        builder+                            .generate_field_code(+                                attr,+                                FieldInfo {+                                    vis: &field.vis,+                                    binding: field_binding,+                                    ty: &field.ty,+                                    span: &field.span(),+                                },+                            )+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    return quote! {+                        #(#result);*+                    };+                });+                // Finally, putting it altogether.+                match builder.kind {+                    None => {+                        span_err(ast.span().unwrap(), "`code` not specified")+                        .help("use the [code = \"...\"] attribute to set this diagnostic's error code ")+                        .emit();+                        SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+                    }+                    Some((kind, _)) => match kind {+                        DiagnosticId::Lint(_lint) => todo!(),+                        DiagnosticId::Error(code) => {+                            let (diag, sess) = (&builder.diag, &builder.sess);+                            quote! {+                                let mut #diag = #sess.struct_err_with_code("", rustc_errors::DiagnosticId::Error(#code));+                                #preamble+                                match self {+                                    #body+                                }+                                #diag+                            }+                        }+                    },+                }+            } else {+                span_err(+                    ast.span().unwrap(),+                    "`#[derive(SessionDiagnostic)]` can only be used on structs",+                )+                .emit();+                SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+            }+        };++        let sess = &builder.sess;+        structure.gen_impl(quote! {+            gen impl<'a> rustc_session::SessionDiagnostic<'a> for @Self {+                fn into_diagnostic(self, #sess: &'a rustc_session::Session) -> rustc_errors::DiagnosticBuilder<'a> {+                    #implementation+                }+            }+        })+    }+}++/// Field information passed to the builder. Deliberately omits attrs to discourage the generate_*+/// methods from walking the attributes themselves.+struct FieldInfo<'a> {+    vis: &'a syn::Visibility,+    binding: &'a synstructure::BindingInfo<'a>,+    ty: &'a syn::Type,+    span: &'a proc_macro2::Span,+}++/// Tracks persistent information required for building up the individual calls to diagnostic+/// methods for the final generated method. This is a separate struct to SessionDerive only to be+/// able to destructure and split self.builder and the self.structure up to avoid a double mut+/// borrow later on.+struct SessionDiagnosticDeriveBuilder<'a> {+    /// Name of the session parameter that's passed in to the as_error method.+    sess: syn::Ident,++    /// Store a map of field name to its corresponding field. This is built on construction of the+    /// derive builder.+    fields: HashMap<String, &'a syn::Field>,++    /// The identifier to use for the generated DiagnosticBuilder instance.+    diag: syn::Ident,++    /// Whether this is a lint or an error. This dictates how the diag will be initialised. Span+    /// stores at what Span the kind was first set at (for error reporting purposes, if the kind+    /// was multiply specified).+    kind: Option<(DiagnosticId, proc_macro2::Span)>,+}++impl<'a> SessionDiagnosticDeriveBuilder<'a> {+    fn generate_structure_code(+        &mut self,+        attr: &syn::Attribute,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        Ok(match attr.parse_meta()? {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                let name = attr.path.segments.last().unwrap().ident.to_string();+                let name = name.as_str();+                match name {+                    "message" => {+                        let diag = &self.diag;+                        quote! {+                            #diag.set_primary_message(#formatted_str);+                        }+                    }+                    attr @ "error" | attr @ "lint" => {+                        self.set_kind_once(+                            if attr == "error" {+                                DiagnosticId::Error(formatted_str)+                            } else if attr == "lint" {+                                DiagnosticId::Lint(formatted_str)+                            } else {+                                unreachable!()+                            },+                            s.span(),+                        )?;+                        // This attribute is only allowed to be applied once, and the attribute+                        // will be set in the initialisation code.+                        quote! {}+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic struct attribute",+                            other+                        )+                    ),+                }+            }+            _ => todo!("unhandled meta kind"),+        })+    }++    #[must_use]+    fn set_kind_once(+        &mut self,+        kind: DiagnosticId,+        span: proc_macro2::Span,+    ) -> Result<(), SessionDiagnosticDeriveError> {+        if self.kind.is_none() {+            self.kind = Some((kind, span));+            Ok(())+        } else {+            let kind_str = |kind: &DiagnosticId| match kind {+                DiagnosticId::Lint(..) => "lint",+                DiagnosticId::Error(..) => "error",+            };++            let existing_kind = kind_str(&self.kind.as_ref().unwrap().0);+            let this_kind = kind_str(&kind);++            let msg = if this_kind == existing_kind {+                format!("`{}` specified multiple times", existing_kind)+            } else {+                format!("`{}` specified when `{}` was already specified", this_kind, existing_kind)+            };+            throw_span_err!(span.unwrap(), &msg);+        }+    }++    fn generate_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let field_binding = &info.binding.binding;++        let option_ty = option_inner_ty(&info.ty);++        let generated_code = self.generate_non_option_field_code(+            attr,+            FieldInfo {+                vis: info.vis,+                binding: info.binding,+                ty: option_ty.unwrap_or(&info.ty),+                span: info.span,+            },+        )?;+        Ok(if option_ty.is_none() {+            quote! { #generated_code }+        } else {+            quote! {+                if let Some(#field_binding) = #field_binding {+                    #generated_code+                }+            }+        })+    }++    fn generate_non_option_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        let field_binding = &info.binding.binding;+        let name = attr.path.segments.last().unwrap().ident.to_string();+        let name = name.as_str();+        // At this point, we need to dispatch based on the attribute key + the+        // type.+        let meta = attr.parse_meta()?;+        Ok(match meta {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                match name {+                    "message" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.set_span(*#field_binding);+                                #diag.set_primary_message(#formatted_str);+                            }+                        } else {+                            throw_span_err!(+                                attr.span().unwrap(),+                                "the `#[message = \"...\"]` attribute can only be applied to fields of type Span"+                            );+                        }

Yeah, this is about the span of the error message when, say, the label attribute is placed on a non-Span field. For this scenario, we're relying on the type error in the code generated by the macro to bubble up and have the span that the generated tokens were set to.

How does it differ for label and message?

The generated code expects a Span field for label, but expects an impl MultiSpan field for message, so having the wrong-typed field for these two causes slightly different errors (an E0308 for if a label field is the wrong type, and E0277 if a message field is the wrong type). E0277 seems to happily point at whatever span I point it at using quote_spanned!, but E0308 ends up pointing at the top-level #[derive(SessionDiagnostic)] tokens (as shown in the link to the stderr above), even if I quote_spanned! with the same span, as below:

https://github.com/jumbatm/rust/blob/5a1969561c8f50bb15a16db17a7bad4c9a813e36/src/librustc_macros/src/session_diagnostic.rs#L390-L400

jumbatm

comment created time in a month

push eventjumbatm/rust

Ayaz Hafiz

commit sha 230393993ffc255d3f20d98400c8a376bd51d1c0

Don't visit foreign function bodies when lowering ast to hir Previously the existence of bodies inside a foreign function block would cause a panic in the hir `NodeCollector` during its collection of crate bodies to compute a crate hash: https://github.com/rust-lang/rust/blob/e59b08e62ea691916d2f063cac5aab4634128022/src/librustc_middle/hir/map/collector.rs#L154-L158 The collector walks the hir tree and creates a map of hir nodes, then attaching bodies in the crate to their owner in the map. For a code like ```rust extern "C" { fn f() { fn g() {} } } ``` The crate bodies include the body of the function `g`. But foreign functions cannot have bodies, and while the parser AST permits a foreign function to have a body, the hir doesn't. This means that the body of `f` is not present in the hir, and so neither is `g`. So when the `NodeCollector` finishes the walking the hir, it has no record of `g`, cannot find an owner for the body of `g` it sees in the crate bodies, and blows up. Why do the crate bodies include the body of `g`? The AST walker has a need a for walking function bodies, and FFIs share the same AST node as functions in other contexts. There are at least two options to fix this: - Don't unwrap the map entry for an hir node in the `NodeCollector` - Modifier the ast->hir lowering visitor to ignore foreign function blocks I don't think the first is preferrable, since we want to know when we can't find a body for an hir node that we thought had one (dropping this information may lead to an invalid hash). So this commit implements the second option. Closes #74120

view details

Ayaz Hafiz

commit sha ab4275cddc3749caf9f20373eb812e6f09bd3309

fixup! Don't visit foreign function bodies when lowering ast to hir

view details

Ayaz Hafiz

commit sha 68aca3baf6566cea3ad2f83a07726c9ee017b9fc

fixup! fixup! Don't visit foreign function bodies when lowering ast to hir

view details

Ayaz Hafiz

commit sha 0c64d32a4a439f373f388f7925048f6f349bd5b2

fixup! Don't visit foreign function bodies when lowering ast to hir

view details

Ayaz Hafiz

commit sha d442bf7162647743f941977a5154676322a5614b

fixup! Don't visit foreign function bodies when lowering ast to hir

view details

Amanieu d'Antras

commit sha 9198e8ad626e257cab11c3c165e09a9a04001a57

Work around LLVM issues with explicit register in inline asm Fixes #74658

view details

LeSeulArtichaut

commit sha 30fa84eceba7982c62ffa89e00401903bf5c0dc8

Add `TyCtxtAt::{ty_error, ty_error_with_message}`

view details

Yuki Okushi

commit sha 50ead683e9c5dbf0cd22325875e9623b5e913486

Add regression test for issue-66768

view details

Aaron Hill

commit sha 0d0546a2364641d8ca9c840b70b437be038b8c9b

Add #[track_caller] to `Session::delay_span_bug` This forwards the caller span to `Handler::delay_span_bug`

view details

Ivan Tham

commit sha 3d1388f514ab18ad798251f511c54097ba5c60ca

Add more examples to Path ends_with We faced a footgun when using ends_with to check extension, showing an example could prevent that.

view details

Greg V

commit sha 2f39477ecffb0dd3a08bf76bfb44aafcdb4aae6a

Add sanitizer support on FreeBSD

view details

Greg V

commit sha ddbc45673b11f706e94fa17730eaa5c113f224d7

Add RUST_STD_FREEBSD_12_ABI env variable Unfortunately, sanitizers do not support versioned symbols[1], so they break filesystem access via the legacy, pre-ino64 ABI. To use sanitizers on FreeBSD >= 12, we need to build the libc crate with LIBC_CI=1 to use the new ABI -- including the libc used for std. But that removes the st_lspare field std was expecting for the deprecated metadata extension. Add a way to skip that field to allow the build to work. [1]: https://github.com/google/sanitizers/issues/628

view details

Ivan Tham

commit sha 8ec348afdd35752677914ba28146d7b82e901817

Remove branch in optimized is_ascii Performs slightly better in short or medium bytes by eliminating the last branch check on `byte_pos == len` and always check the last byte as it is always at most one `usize`. Benchmark, before `libcore`, after `libcore_new`. It improves medium and short by 1ns but regresses unaligned_tail by 2ns, either way we can get unaligned_tail have a tiny chance of 1/8 on a 64 bit machine. I don't think we should bet on that, the probability is worse than dice. test long::case00_libcore ... bench: 38 ns/iter (+/- 1) = 183947 MB/s test long::case00_libcore_new ... bench: 38 ns/iter (+/- 1) = 183947 MB/s test long::case01_iter_all ... bench: 227 ns/iter (+/- 6) = 30792 MB/s test long::case02_align_to ... bench: 40 ns/iter (+/- 1) = 174750 MB/s test long::case03_align_to_unrolled ... bench: 19 ns/iter (+/- 1) = 367894 MB/s test medium::case00_libcore ... bench: 5 ns/iter (+/- 0) = 6400 MB/s test medium::case00_libcore_new ... bench: 4 ns/iter (+/- 0) = 8000 MB/s test medium::case01_iter_all ... bench: 20 ns/iter (+/- 1) = 1600 MB/s test medium::case02_align_to ... bench: 6 ns/iter (+/- 0) = 5333 MB/s test medium::case03_align_to_unrolled ... bench: 5 ns/iter (+/- 0) = 6400 MB/s test short::case00_libcore ... bench: 7 ns/iter (+/- 0) = 1000 MB/s test short::case00_libcore_new ... bench: 6 ns/iter (+/- 0) = 1166 MB/s test short::case01_iter_all ... bench: 5 ns/iter (+/- 0) = 1400 MB/s test short::case02_align_to ... bench: 5 ns/iter (+/- 0) = 1400 MB/s test short::case03_align_to_unrolled ... bench: 5 ns/iter (+/- 1) = 1400 MB/s test unaligned_both::case00_libcore ... bench: 4 ns/iter (+/- 0) = 7500 MB/s test unaligned_both::case00_libcore_new ... bench: 4 ns/iter (+/- 0) = 7500 MB/s test unaligned_both::case01_iter_all ... bench: 26 ns/iter (+/- 0) = 1153 MB/s test unaligned_both::case02_align_to ... bench: 13 ns/iter (+/- 2) = 2307 MB/s test unaligned_both::case03_align_to_unrolled ... bench: 11 ns/iter (+/- 0) = 2727 MB/s test unaligned_head::case00_libcore ... bench: 5 ns/iter (+/- 0) = 6200 MB/s test unaligned_head::case00_libcore_new ... bench: 5 ns/iter (+/- 0) = 6200 MB/s test unaligned_head::case01_iter_all ... bench: 19 ns/iter (+/- 1) = 1631 MB/s test unaligned_head::case02_align_to ... bench: 10 ns/iter (+/- 0) = 3100 MB/s test unaligned_head::case03_align_to_unrolled ... bench: 14 ns/iter (+/- 0) = 2214 MB/s test unaligned_tail::case00_libcore ... bench: 3 ns/iter (+/- 0) = 10333 MB/s test unaligned_tail::case00_libcore_new ... bench: 5 ns/iter (+/- 0) = 6200 MB/s test unaligned_tail::case01_iter_all ... bench: 19 ns/iter (+/- 0) = 1631 MB/s test unaligned_tail::case02_align_to ... bench: 10 ns/iter (+/- 0) = 3100 MB/s test unaligned_tail::case03_align_to_unrolled ... bench: 13 ns/iter (+/- 0) = 2384 MB/s Rough (unfair) maths on improvements for fun: 1ns * 7/8 - 2ns * 1/8 = 0.625ns Inspired by fish and zsh clever trick to highlight missing linefeeds (⏎) and branchless implementation of binary_search in rust.

view details

Denis Vasilik

commit sha 3c2eb18b9ba287284f5f08f8c256154354c55c64

Use intra-doc links

view details

Denis Vasilik

commit sha c4923419c2570e2013e7b946f1a47001f8f9289a

Revert broken link

view details

Denis Vasilik

commit sha 4c5896fbeb1a60d1e100c28fbe6cfe81ee2311fa

Remove intra-doc link as it resolves without reference link Co-authored-by: Joshua Nelson <joshua@yottadb.com>

view details

Alexis Bourget

commit sha aa1fb31bf1a3c919ad9946ae6e2a7a63eb646276

Move to intra doc links in std/src/fs.rs

view details

Mark Rousskov

commit sha e09cca09acf7f146e7df754e74a5fc934af10de4

Add option to use the new symbol mangling in rustc/std

view details

Mateusz Mikuła

commit sha c75f7f90c89907edba2d9488c30dc550d3dad94a

Add LLD flags for MinGW

view details

Ralf Jung

commit sha 7aac3e0400d29c79623e7fefb43f17b6a765a326

pin docs: add some forward references

view details

push time in a month

pull request commentrust-lang/rust

Fix clashing_extern_declarations stack overflow for recursive types.

Cool, this is good to go.

@rustbot modify labels to -S-waiting-on-author, +S-waiting-on-review

jumbatm

comment created time in a month

push eventjumbatm/rust

Tomasz Miąsko

commit sha 91f87bc9bc29461513aaa6252905a7ac0ac303e9

Set CMAKE_SYSTEM_NAME when cross-compiling Configure CMAKE_SYSTEM_NAME when cross-compiling in `configure_cmake`, to tell CMake about target system. Previously this was done only for LLVM step and now applies more generally to steps using cmake.

view details

Stein Somers

commit sha 8668e5b29e78732cb4f4bb84e838fdace70fa3c0

Reverts the fundamental changes in #74762 and #75257

view details

Bastian Kauschke

commit sha cd53760cc7751b65943feb6437af28d5ccb6e770

merge `as_local_hir_id` with `local_def_id_to_hir_id`

view details

Esteban Küber

commit sha 2e9b45e1dd8d3a248e2aea60314787650e3abcc9

Recover gracefully from `struct ` parse errors

view details

Eric Huss

commit sha 73b7a0403235732daa0664bfd1bd3279b7ab5cb6

Fix crate-version with rustdoc in bootstrap.

view details

Eduard-Mihai Burtescu

commit sha a7ad899f9dbce1b4a0beb56650bc72732f204d24

std/sys/unix/time: make it easier for LLVM to optimize `Instant` subtraction.

view details

Tyler Mandry

commit sha 29b6b5feaa86969dc97b42f72fe5837b0d8b523e

Rollup merge of #75376 - tmiasko:cmake-system-name, r=Mark-Simulacrum Set CMAKE_SYSTEM_NAME when cross-compiling Configure CMAKE_SYSTEM_NAME when cross-compiling in `configure_cmake`, to tell CMake about target system. Previously this was done only for LLVM step and now applies more generally to steps using cmake. Helps with #74576.

view details

Tyler Mandry

commit sha 28b11abc2f336288379b6e635e65e23809616487

Rollup merge of #75448 - lcnr:rn-as_local_hir_id, r=davidtwco merge `as_local_hir_id` with `local_def_id_to_hir_id` `as_local_hir_id` was defined as just calling `local_def_id_to_hir_id` and I think that having two different ways to call the same method is somewhat confusing. Don't really care about which of these 2 methods we want to keep. Does this require an MCP, considering that these methods are fairly frequently used?

view details

Tyler Mandry

commit sha e38eaf22d247644e5554d0c200e6df756e469b0a

Rollup merge of #75513 - estebank:confused-parser, r=davidtwco Recover gracefully from `struct` parse errors Currently the parser tries to recover from finding a keyword where a field name was expected, but this causes extra knock down parse errors that are completely irrelevant. Instead, bail out early in the parsing of the field and consume the remaining tokens in the block. This can reduce output significantly. _Improvements based on the narrative in https://fasterthanli.me/articles/i-am-a-java-csharp-c-or-cplusplus-dev-time-to-do-some-rust_

view details

Tyler Mandry

commit sha 29a946203aeebdd0d8466968705694fea9ca866f

Rollup merge of #75545 - eddyb:instant-sub-branchless, r=sfackler std/sys/unix/time: make it easier for LLVM to optimize `Instant` subtraction. This PR is the minimal change necessary to get LLVM to optimize `if self.t.tv_nsec >= other.t.tv_nsec` to branchless instructions (at least on x86_64), inspired by @m-ou-se's own attempts at optimizing `Instant` subtraction. I stumbled over this by looking at the total number of instructions executed by `rustc -Z self-profile`, and found that after disabling ASLR, the largest source of non-determinism remaining was from this `if` taking one branch or the other, depending on the values involved. The reason this code is even called so many times to make a difference, is that `measureme` (the `-Z self-profile` implementation) currently uses `Instant::elapsed` for its event timestamps (of which there can be millions). I doubt it's critical to land this, although perhaps it could slightly improve some forms of benchmarking.

view details

bors

commit sha 45060c2a66dfd667f88bd8b94261b28a58d85bd5

Auto merge of #75549 - tmandry:rollup-sxjwa0w, r=tmandry Rollup of 4 pull requests Successful merges: - #75376 (Set CMAKE_SYSTEM_NAME when cross-compiling) - #75448 (merge `as_local_hir_id` with `local_def_id_to_hir_id`) - #75513 (Recover gracefully from `struct` parse errors) - #75545 (std/sys/unix/time: make it easier for LLVM to optimize `Instant` subtraction.) Failed merges: - #75514 (Replaced `log` with `tracing`) r? @ghost

view details

Eric Huss

commit sha 85a9cfaa3110f204242df8536636b73318ced145

Deal with spaces in the rust version.

view details

bors

commit sha f7aac25850b68ead13831e7c4605dcc7d07e4e9b

Auto merge of #75488 - ssomers:btree_revert_75257, r=Mark-Simulacrum Revert the fundamental changes in #74762 and #75257 Before possibly going over to #75487. Also contains some added and fixed comments. r? @Mark-Simulacrum

view details

bors

commit sha 5205b974d588a41798a7438b91bf26a6f084e0dd

Auto merge of #75539 - ehuss:fix-crate-version-rustdoc-bootstrap, r=Mark-Simulacrum Fix crate-version with rustdoc in bootstrap. Cargo will now automatically use the `--crate-version` flag (see https://github.com/rust-lang/cargo/pull/8509). Cargo has special handling to avoid passing the flag if it is passed in via RUSTDOCFLAGS, but the `rustdoc` wrapper circumvents that check. This causes a problem because rustdoc will fail if the flag is passed in twice. Fix this by using RUSTDOCFLAGS. This will be necessary when 1.47 is promoted to beta, but should be safe to do now.

view details

jumbatm

commit sha 53202948797240a1d4b067b89180fd247d0448de

Add test demonstrating the issue.

view details

jumbatm

commit sha 402658ca44a4bbc1c6333a1e50d8e9d107507829

Fix stack overflow for recursive types. Adds a seen set to structurally_same_type to avoid recursing indefinitely when a reference or pointer member introduces a cycle in the visited types.

view details

jumbatm

commit sha ca4d1ebb40c2a52f5c7f391ee2b0d3efefe2cbb5

Actually introduce a cycle in Reffy test.

view details

jumbatm

commit sha 3771146d377d9c24ae8bd45555ed6e5703b34a59

Remove unnecessary rebinding of def ids.

view details

jumbatm

commit sha 362c948c13ecfcbb9947160326893f7930a967c8

Remove structural equiv check for Array const.

view details

jumbatm

commit sha 931d9b86cad20aca067f57479f4da4a909058875

Reduce indentation by replacing match arm w/ early return.

view details

push time in a month

startedpretzelhammer/rust-blog

started time in a month

push eventjumbatm/rust

jumbatm

commit sha 0e28346a4763230f993c5e0b0dfe061315c3d2b7

Avoid double hashset lookup. Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

push time in a month

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

+#![deny(unused_must_use)]+use quote::format_ident;+use quote::quote;++use proc_macro::Diagnostic;+use syn::spanned::Spanned;++use std::collections::{HashMap, HashSet};++/// Implements #[derive(SessionDiagnostic)], which allows for errors to be specified as a struct, independent+/// from the actual diagnostics emitting code.+/// ```ignore (pseudo-rust)+/// # extern crate rustc_errors;+/// # use rustc_errors::Applicability;+/// # extern crate rustc_span;+/// # use rustc_span::{symbol::Ident, Span};+/// # extern crate rust_middle;+/// # use rustc_middle::ty::Ty;+/// #[derive(SessionDiagnostic)]+/// #[code = "E0505"]+/// #[error = "cannot move out of {name} because it is borrowed"]+/// pub struct MoveOutOfBorrowError<'tcx> {+///     pub name: Ident,+///     pub ty: Ty<'tcx>,+///     #[label = "cannot move out of borrow"]+///     pub span: Span,+///     #[label = "`{ty}` first borrowed here"]+///     pub other_span: Span,+///     #[suggestion(message = "consider cloning here", code = "{name}.clone()")]+///     pub opt_sugg: Option<(Span, Applicability)>+/// }+/// ```+/// Then, later, to emit the error:+///+/// ```ignore (pseudo-rust)+/// sess.emit_err(MoveOutOfBorrowError {+///     expected,+///     actual,+///     span,+///     other_span,+///     opt_sugg: Some(suggestion, Applicability::MachineApplicable),+/// });+/// ```+pub fn session_diagnostic_derive(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {+    // Names for the diagnostic we build and the session we build it from.+    let diag = format_ident!("diag");+    let sess = format_ident!("sess");++    SessionDiagnosticDerive::new(diag, sess, s).into_tokens()+}++// Checks whether the type name of `ty` matches `name`.+//+// Given some struct at a::b::c::Foo, this will return true for c::Foo, b::c::Foo, or+// a::b::c::Foo. This reasonably allows qualified names to be used in the macro.+fn type_matches_path(ty: &syn::Type, name: &[&str]) -> bool {+    if let syn::Type::Path(ty) = ty {+        ty.path+            .segments+            .iter()+            .map(|s| s.ident.to_string())+            .rev()+            .zip(name.iter().rev())+            .all(|(x, y)| &x.as_str() == y)+    } else {+        false+    }+}++/// The central struct for constructing the as_error method from an annotated struct.+struct SessionDiagnosticDerive<'a> {+    structure: synstructure::Structure<'a>,+    builder: SessionDiagnosticDeriveBuilder<'a>,+}++impl std::convert::From<syn::Error> for SessionDiagnosticDeriveError {+    fn from(e: syn::Error) -> Self {+        SessionDiagnosticDeriveError::SynError(e)+    }+}++#[allow(unused)]+enum DiagnosticId {+    Error(proc_macro2::TokenStream),+    Lint(proc_macro2::TokenStream),+}++#[derive(Debug)]+enum SessionDiagnosticDeriveError {+    SynError(syn::Error),+    ErrorHandled,+}++impl SessionDiagnosticDeriveError {+    fn to_compile_error(self) -> proc_macro2::TokenStream {+        match self {+            SessionDiagnosticDeriveError::SynError(e) => e.to_compile_error(),+            SessionDiagnosticDeriveError::ErrorHandled => {+                // Return ! to avoid having to create a blank DiagnosticBuilder to return when an+                // error has already been emitted to the compiler.+                quote! {+                    unreachable!()+                }+            }+        }+    }+}++fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnostic {+    Diagnostic::spanned(span, proc_macro::Level::Error, msg)+}++/// For use methods that return a Result<_, SessionDiagnosticDeriveError>: emit a diagnostic on+/// span $span with msg $msg (and, optionally, perform additional decoration using the FnOnce+/// passed in `diag`). Then, return Err(ErrorHandled).+macro_rules! throw_span_err {+    ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }};+    ($span:expr, $msg:expr, $f:expr) => {{+        return Err(_throw_span_err($span, $msg, $f));+    }};+}++/// When possible, prefer using throw_span_err! over using this function directly. This only exists+/// as a function to constrain `f` to an impl FnOnce.+#[doc(hidden)]+fn _throw_span_err(+    span: impl proc_macro::MultiSpan,+    msg: &str,+    f: impl FnOnce(proc_macro::Diagnostic) -> proc_macro::Diagnostic,+) -> SessionDiagnosticDeriveError {+    let diag = span_err(span, msg);+    f(diag).emit();+    SessionDiagnosticDeriveError::ErrorHandled+}++impl<'a> SessionDiagnosticDerive<'a> {+    fn new(diag: syn::Ident, sess: syn::Ident, structure: synstructure::Structure<'a>) -> Self {+        // Build the mapping of field names to fields. This allows attributes to peek values from+        // other fields.+        let mut fields_map = HashMap::new();++        // Convenience bindings.+        let ast = structure.ast();++        if let syn::Data::Struct(syn::DataStruct { fields, .. }) = &ast.data {+            for field in fields.iter() {+                if let Some(ident) = &field.ident {+                    fields_map.insert(ident.to_string(), field);+                }+            }+        }++        Self {+            builder: SessionDiagnosticDeriveBuilder { diag, sess, fields: fields_map, kind: None },+            structure,+        }+    }+    fn into_tokens(self) -> proc_macro2::TokenStream {+        let SessionDiagnosticDerive { structure, mut builder } = self;++        let ast = structure.ast();+        let attrs = &ast.attrs;++        let implementation = {+            if let syn::Data::Struct(..) = ast.data {+                let preamble = {+                    let preamble = attrs.iter().map(|attr| {+                        builder+                            .generate_structure_code(attr)+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    quote! {+                        #(#preamble)*;+                    }+                };++                let body = structure.each(|field_binding| {+                    let field = field_binding.ast();+                    let result = field.attrs.iter().map(|attr| {+                        builder+                            .generate_field_code(+                                attr,+                                FieldInfo {+                                    vis: &field.vis,+                                    binding: field_binding,+                                    ty: &field.ty,+                                    span: &field.span(),+                                },+                            )+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    return quote! {+                        #(#result);*+                    };+                });+                // Finally, putting it altogether.+                match builder.kind {+                    None => {+                        span_err(ast.span().unwrap(), "`code` not specified")+                        .help("use the [code = \"...\"] attribute to set this diagnostic's error code ")+                        .emit();+                        SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+                    }+                    Some((kind, _)) => match kind {+                        DiagnosticId::Lint(_lint) => todo!(),+                        DiagnosticId::Error(code) => {+                            let (diag, sess) = (&builder.diag, &builder.sess);+                            quote! {+                                let mut #diag = #sess.struct_err_with_code("", rustc_errors::DiagnosticId::Error(#code));+                                #preamble+                                match self {+                                    #body+                                }+                                #diag+                            }+                        }+                    },+                }+            } else {+                span_err(+                    ast.span().unwrap(),+                    "`#[derive(SessionDiagnostic)]` can only be used on structs",+                )+                .emit();+                SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+            }+        };++        let sess = &builder.sess;+        structure.gen_impl(quote! {+            gen impl<'a> rustc_session::SessionDiagnostic<'a> for @Self {+                fn into_diagnostic(self, #sess: &'a rustc_session::Session) -> rustc_errors::DiagnosticBuilder<'a> {+                    #implementation+                }+            }+        })+    }+}++/// Field information passed to the builder. Deliberately omits attrs to discourage the generate_*+/// methods from walking the attributes themselves.+struct FieldInfo<'a> {+    vis: &'a syn::Visibility,+    binding: &'a synstructure::BindingInfo<'a>,+    ty: &'a syn::Type,+    span: &'a proc_macro2::Span,+}++/// Tracks persistent information required for building up the individual calls to diagnostic+/// methods for the final generated method. This is a separate struct to SessionDerive only to be+/// able to destructure and split self.builder and the self.structure up to avoid a double mut+/// borrow later on.+struct SessionDiagnosticDeriveBuilder<'a> {+    /// Name of the session parameter that's passed in to the as_error method.+    sess: syn::Ident,++    /// Store a map of field name to its corresponding field. This is built on construction of the+    /// derive builder.+    fields: HashMap<String, &'a syn::Field>,++    /// The identifier to use for the generated DiagnosticBuilder instance.+    diag: syn::Ident,++    /// Whether this is a lint or an error. This dictates how the diag will be initialised. Span+    /// stores at what Span the kind was first set at (for error reporting purposes, if the kind+    /// was multiply specified).+    kind: Option<(DiagnosticId, proc_macro2::Span)>,+}++impl<'a> SessionDiagnosticDeriveBuilder<'a> {+    fn generate_structure_code(+        &mut self,+        attr: &syn::Attribute,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        Ok(match attr.parse_meta()? {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                let name = attr.path.segments.last().unwrap().ident.to_string();+                let name = name.as_str();+                match name {+                    "error" => {+                        quote! {+                            #diag.set_primary_message(#formatted_str);+                        }+                    }+                    "code" => {+                        self.set_kind_once(DiagnosticId::Error(formatted_str), attr.span())?;+                        // This attribute is only allowed to be applied once, and the attribute+                        // will be set in the initialisation code.+                        quote! {}+                    }+                    "lint" => {+                        self.set_kind_once(DiagnosticId::Lint(formatted_str), attr.span())?;+                        // As with `code`, this attribute is only allowed once.+                        quote! {}+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic struct attribute",+                            other+                        )+                    ),+                }+            }+            _ => todo!("unhandled meta kind"),+        })+    }++    #[must_use]+    fn set_kind_once(+        &mut self,+        kind: DiagnosticId,+        span: proc_macro2::Span,+    ) -> Result<(), SessionDiagnosticDeriveError> {+        if self.kind.is_none() {+            self.kind = Some((kind, span));+            Ok(())+        } else {+            throw_span_err!(span.unwrap(), "`code` specified multiple times");+        }+    }++    fn generate_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let field_binding = &info.binding.binding;++        let option_ty = option_inner_ty(&info.ty);++        let generated_code = self.generate_non_option_field_code(+            attr,+            FieldInfo {+                vis: info.vis,+                binding: info.binding,+                ty: option_ty.unwrap_or(&info.ty),+                span: info.span,+            },+        )?;+        Ok(if option_ty.is_none() {+            quote! { #generated_code }+        } else {+            quote! {+                if let Some(#field_binding) = #field_binding {+                    #generated_code+                }+            }+        })+    }++    fn generate_non_option_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        let field_binding = &info.binding.binding;+        let name = attr.path.segments.last().unwrap().ident.to_string();+        let name = name.as_str();+        // At this point, we need to dispatch based on the attribute key + the+        // type.+        let meta = attr.parse_meta()?;+        Ok(match meta {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                match name {+                    "error" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.set_span(*#field_binding);+                                #diag.set_primary_message(#formatted_str);+                            }+                        } else {+                            quote! {+                                #diag.set_primary_message(#formatted_str);+                            }+                        }+                    }+                    "label" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.span_label(*#field_binding, #formatted_str);+                            }+                        } else {+                            throw_span_err!(+                                attr.span().unwrap(),+                                "The `#[label = ...]` attribute can only be applied to fields of type Span"+                            );+                        }+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic field attribute",+                            other+                        )+                    ),+                }+            }+            syn::Meta::List(list) => {+                match list.path.segments.iter().last().unwrap().ident.to_string().as_str() {+                    suggestion_kind @ "suggestion"+                    | suggestion_kind @ "suggestion_short"+                    | suggestion_kind @ "suggestion_hidden"+                    | suggestion_kind @ "suggestion_verbose" => {+                        // For suggest, we need to ensure we are running on a (Span,+                        // Applicability) pair.+                        let (span, applicability) = (|| {+                            if let syn::Type::Tuple(tup) = &info.ty {+                                let mut span_idx = None;+                                let mut applicability_idx = None;+                                for (idx, elem) in tup.elems.iter().enumerate() {+                                    if type_matches_path(elem, &["rustc_span", "Span"]) {+                                        if span_idx.is_none() {+                                            span_idx = Some(syn::Index::from(idx));+                                        } else {+                                            throw_span_err!(+                                                info.span.clone().unwrap(),+                                                "type of field annotated with `#[suggestion(...)]` contains more than one Span"+                                            );+                                        }+                                    } else if type_matches_path(+                                        elem,+                                        &["rustc_errors", "Applicability"],+                                    ) {+                                        if applicability_idx.is_none() {+                                            applicability_idx = Some(syn::Index::from(idx));+                                        } else {+                                            throw_span_err!(+                                                info.span.clone().unwrap(),+                                                "type of field annotated with `#[suggestion(...)]` contains more than one Applicability"+                                            );+                                        }+                                    }+                                }+                                if let (Some(span_idx), Some(applicability_idx)) =+                                    (span_idx, applicability_idx)+                                {+                                    let binding = &info.binding.binding;+                                    let span = quote!(#binding.#span_idx);+                                    let applicability = quote!(#binding.#applicability_idx);+                                    return Ok((span, applicability));+                                }+                            }+                            throw_span_err!(

I'm all in favour of removing the name-based type checks in favour of just letting custom traits do the heavy lifting. However, doing this, the emitted error points at the #[derive(SessionDiagnostic)], even with quote_spanned! (as with the other case):

https://github.com/jumbatm/rust/blob/0254a1831fd926207b51bc87cd9deb3de7e5ee5e/src/test/ui-fulldeps/session-derive-errors.stderr#L164-L171

On having an on_unimplemented method: wouldn't I need to generate code which calls this method, meaning I'd be emitting the customised diagnostic at runtime? Using compile_error! wouldn't do the trick, either, that would always cause a compile error (regardless of the flow at runtime).

jumbatm

comment created time in a month

create barnchjumbatm/rust

branch : session-diagnostic-derive-span-app

created branch time in a month

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

+#![deny(unused_must_use)]+use quote::format_ident;+use quote::quote;++use proc_macro::Diagnostic;+use syn::spanned::Spanned;++use std::collections::{HashMap, HashSet};++/// Implements #[derive(SessionDiagnostic)], which allows for errors to be specified as a struct, independent+/// from the actual diagnostics emitting code.+/// ```ignore (pseudo-rust)+/// # extern crate rustc_errors;+/// # use rustc_errors::Applicability;+/// # extern crate rustc_span;+/// # use rustc_span::{symbol::Ident, Span};+/// # extern crate rust_middle;+/// # use rustc_middle::ty::Ty;+/// #[derive(SessionDiagnostic)]+/// #[code = "E0505"]+/// #[error = "cannot move out of {name} because it is borrowed"]+/// pub struct MoveOutOfBorrowError<'tcx> {+///     pub name: Ident,+///     pub ty: Ty<'tcx>,+///     #[label = "cannot move out of borrow"]+///     pub span: Span,+///     #[label = "`{ty}` first borrowed here"]+///     pub other_span: Span,+///     #[suggestion(message = "consider cloning here", code = "{name}.clone()")]+///     pub opt_sugg: Option<(Span, Applicability)>+/// }+/// ```+/// Then, later, to emit the error:+///+/// ```ignore (pseudo-rust)+/// sess.emit_err(MoveOutOfBorrowError {+///     expected,+///     actual,+///     span,+///     other_span,+///     opt_sugg: Some(suggestion, Applicability::MachineApplicable),+/// });+/// ```+pub fn session_diagnostic_derive(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {+    // Names for the diagnostic we build and the session we build it from.+    let diag = format_ident!("diag");+    let sess = format_ident!("sess");++    SessionDiagnosticDerive::new(diag, sess, s).into_tokens()+}++// Checks whether the type name of `ty` matches `name`.+//+// Given some struct at a::b::c::Foo, this will return true for c::Foo, b::c::Foo, or+// a::b::c::Foo. This reasonably allows qualified names to be used in the macro.+fn type_matches_path(ty: &syn::Type, name: &[&str]) -> bool {+    if let syn::Type::Path(ty) = ty {+        ty.path+            .segments+            .iter()+            .map(|s| s.ident.to_string())+            .rev()+            .zip(name.iter().rev())+            .all(|(x, y)| &x.as_str() == y)+    } else {+        false+    }+}++/// The central struct for constructing the as_error method from an annotated struct.+struct SessionDiagnosticDerive<'a> {+    structure: synstructure::Structure<'a>,+    builder: SessionDiagnosticDeriveBuilder<'a>,+}++impl std::convert::From<syn::Error> for SessionDiagnosticDeriveError {+    fn from(e: syn::Error) -> Self {+        SessionDiagnosticDeriveError::SynError(e)+    }+}++/// Equivalent to rustc:errors::diagnostic::DiagnosticId, except stores the quoted expression to+/// initialise the code with.+enum DiagnosticId {+    Error(proc_macro2::TokenStream),+    Lint(proc_macro2::TokenStream),+}++#[derive(Debug)]+enum SessionDiagnosticDeriveError {+    SynError(syn::Error),+    ErrorHandled,+}++impl SessionDiagnosticDeriveError {+    fn to_compile_error(self) -> proc_macro2::TokenStream {+        match self {+            SessionDiagnosticDeriveError::SynError(e) => e.to_compile_error(),+            SessionDiagnosticDeriveError::ErrorHandled => {+                // Return ! to avoid having to create a blank DiagnosticBuilder to return when an+                // error has already been emitted to the compiler.+                quote! {+                    unreachable!()+                }+            }+        }+    }+}++fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnostic {+    Diagnostic::spanned(span, proc_macro::Level::Error, msg)+}++/// For methods that return a Result<_, SessionDiagnosticDeriveError>: emit a diagnostic on+/// span $span with msg $msg (and, optionally, perform additional decoration using the FnOnce+/// passed in `diag`). Then, return Err(ErrorHandled).+macro_rules! throw_span_err {+    ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }};+    ($span:expr, $msg:expr, $f:expr) => {{+        return Err(_throw_span_err($span, $msg, $f));+    }};+}++/// When possible, prefer using throw_span_err! over using this function directly. This only exists+/// as a function to constrain `f` to an impl FnOnce.+fn _throw_span_err(+    span: impl proc_macro::MultiSpan,+    msg: &str,+    f: impl FnOnce(proc_macro::Diagnostic) -> proc_macro::Diagnostic,+) -> SessionDiagnosticDeriveError {+    let diag = span_err(span, msg);+    f(diag).emit();+    SessionDiagnosticDeriveError::ErrorHandled+}++impl<'a> SessionDiagnosticDerive<'a> {+    fn new(diag: syn::Ident, sess: syn::Ident, structure: synstructure::Structure<'a>) -> Self {+        // Build the mapping of field names to fields. This allows attributes to peek values from+        // other fields.+        let mut fields_map = HashMap::new();++        // Convenience bindings.+        let ast = structure.ast();++        if let syn::Data::Struct(syn::DataStruct { fields, .. }) = &ast.data {+            for field in fields.iter() {+                if let Some(ident) = &field.ident {+                    fields_map.insert(ident.to_string(), field);+                }+            }+        }++        Self {+            builder: SessionDiagnosticDeriveBuilder { diag, sess, fields: fields_map, kind: None },+            structure,+        }+    }+    fn into_tokens(self) -> proc_macro2::TokenStream {+        let SessionDiagnosticDerive { structure, mut builder } = self;++        let ast = structure.ast();+        let attrs = &ast.attrs;++        let implementation = {+            if let syn::Data::Struct(..) = ast.data {+                let preamble = {+                    let preamble = attrs.iter().map(|attr| {+                        builder+                            .generate_structure_code(attr)+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    quote! {+                        #(#preamble)*;+                    }+                };++                let body = structure.each(|field_binding| {+                    let field = field_binding.ast();+                    let result = field.attrs.iter().map(|attr| {+                        builder+                            .generate_field_code(+                                attr,+                                FieldInfo {+                                    vis: &field.vis,+                                    binding: field_binding,+                                    ty: &field.ty,+                                    span: &field.span(),+                                },+                            )+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    return quote! {+                        #(#result);*+                    };+                });+                // Finally, putting it altogether.+                match builder.kind {+                    None => {+                        span_err(ast.span().unwrap(), "`code` not specified")+                        .help("use the [code = \"...\"] attribute to set this diagnostic's error code ")+                        .emit();+                        SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+                    }+                    Some((kind, _)) => match kind {+                        DiagnosticId::Lint(_lint) => todo!(),+                        DiagnosticId::Error(code) => {+                            let (diag, sess) = (&builder.diag, &builder.sess);+                            quote! {+                                let mut #diag = #sess.struct_err_with_code("", rustc_errors::DiagnosticId::Error(#code));+                                #preamble+                                match self {+                                    #body+                                }+                                #diag+                            }+                        }+                    },+                }+            } else {+                span_err(+                    ast.span().unwrap(),+                    "`#[derive(SessionDiagnostic)]` can only be used on structs",+                )+                .emit();+                SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+            }+        };++        let sess = &builder.sess;+        structure.gen_impl(quote! {+            gen impl<'a> rustc_session::SessionDiagnostic<'a> for @Self {+                fn into_diagnostic(self, #sess: &'a rustc_session::Session) -> rustc_errors::DiagnosticBuilder<'a> {+                    #implementation+                }+            }+        })+    }+}++/// Field information passed to the builder. Deliberately omits attrs to discourage the generate_*+/// methods from walking the attributes themselves.+struct FieldInfo<'a> {+    vis: &'a syn::Visibility,+    binding: &'a synstructure::BindingInfo<'a>,+    ty: &'a syn::Type,+    span: &'a proc_macro2::Span,+}++/// Tracks persistent information required for building up the individual calls to diagnostic+/// methods for the final generated method. This is a separate struct to SessionDerive only to be+/// able to destructure and split self.builder and the self.structure up to avoid a double mut+/// borrow later on.+struct SessionDiagnosticDeriveBuilder<'a> {+    /// Name of the session parameter that's passed in to the as_error method.+    sess: syn::Ident,++    /// Store a map of field name to its corresponding field. This is built on construction of the+    /// derive builder.+    fields: HashMap<String, &'a syn::Field>,++    /// The identifier to use for the generated DiagnosticBuilder instance.+    diag: syn::Ident,++    /// Whether this is a lint or an error. This dictates how the diag will be initialised. Span+    /// stores at what Span the kind was first set at (for error reporting purposes, if the kind+    /// was multiply specified).+    kind: Option<(DiagnosticId, proc_macro2::Span)>,+}++impl<'a> SessionDiagnosticDeriveBuilder<'a> {+    fn generate_structure_code(+        &mut self,+        attr: &syn::Attribute,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        Ok(match attr.parse_meta()? {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                let name = attr.path.segments.last().unwrap().ident.to_string();+                let name = name.as_str();+                match name {+                    "message" => {+                        let diag = &self.diag;+                        quote! {+                            #diag.set_primary_message(#formatted_str);+                        }+                    }+                    attr @ "error" | attr @ "lint" => {+                        self.set_kind_once(+                            if attr == "error" {+                                DiagnosticId::Error(formatted_str)+                            } else if attr == "lint" {+                                DiagnosticId::Lint(formatted_str)+                            } else {+                                unreachable!()+                            },+                            s.span(),+                        )?;+                        // This attribute is only allowed to be applied once, and the attribute+                        // will be set in the initialisation code.+                        quote! {}+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic struct attribute",+                            other+                        )+                    ),+                }+            }+            _ => todo!("unhandled meta kind"),+        })+    }++    #[must_use]+    fn set_kind_once(+        &mut self,+        kind: DiagnosticId,+        span: proc_macro2::Span,+    ) -> Result<(), SessionDiagnosticDeriveError> {+        if self.kind.is_none() {+            self.kind = Some((kind, span));+            Ok(())+        } else {+            let kind_str = |kind: &DiagnosticId| match kind {+                DiagnosticId::Lint(..) => "lint",+                DiagnosticId::Error(..) => "error",+            };++            let existing_kind = kind_str(&self.kind.as_ref().unwrap().0);+            let this_kind = kind_str(&kind);++            let msg = if this_kind == existing_kind {+                format!("`{}` specified multiple times", existing_kind)+            } else {+                format!("`{}` specified when `{}` was already specified", this_kind, existing_kind)+            };+            throw_span_err!(span.unwrap(), &msg);+        }+    }++    fn generate_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let field_binding = &info.binding.binding;++        let option_ty = option_inner_ty(&info.ty);++        let generated_code = self.generate_non_option_field_code(+            attr,+            FieldInfo {+                vis: info.vis,+                binding: info.binding,+                ty: option_ty.unwrap_or(&info.ty),+                span: info.span,+            },+        )?;+        Ok(if option_ty.is_none() {+            quote! { #generated_code }+        } else {+            quote! {+                if let Some(#field_binding) = #field_binding {+                    #generated_code+                }+            }+        })+    }++    fn generate_non_option_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        let field_binding = &info.binding.binding;+        let name = attr.path.segments.last().unwrap().ident.to_string();+        let name = name.as_str();+        // At this point, we need to dispatch based on the attribute key + the+        // type.+        let meta = attr.parse_meta()?;+        Ok(match meta {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                match name {+                    "message" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.set_span(*#field_binding);+                                #diag.set_primary_message(#formatted_str);+                            }+                        } else {+                            throw_span_err!(+                                attr.span().unwrap(),+                                "the `#[message = \"...\"]` attribute can only be applied to fields of type Span"+                            );+                        }

Hmm, though using quote_span worked fine for message, it doesn't work for label:

https://github.com/jumbatm/rust/blob/session-diagnostic-derive-ideal-spans/src/test/ui-fulldeps/session-derive-errors.stderr#L122-L146

I believe this is because E0308 is trying to be a bit cleverer with the span it emits on, but ends up pointing to a Span that's within the generated code, so ends up just pointing to the #[derive(SessionDiagnostic)].

jumbatm

comment created time in a month

push eventjumbatm/rust

jumbatm

commit sha 4572370b22379f91b2d11c0cdc0be39f5fcb818e

Fix failing doc tests.

view details

jumbatm

commit sha 152ae7466c126b2eae88b56bb6bb46578e464fa7

Apply suggestions from code review Co-authored-by: Oliver Scherer <github35764891676564198441@oli-obk.de>

view details

jumbatm

commit sha 24e1d625c802bbce2aea09c6b1adb1c140003630

Move FieldAlreadyDeclared into its own `errors` module.

view details

jumbatm

commit sha 4788ca6cea207bd28d6914cccc3bf3a746d415ca

Remove unnecessary #[doc(hidden)].

view details

jumbatm

commit sha cc86bdd90a61f97c42970e28f0bf358ae48dca97

Rename some attrs, handle duplicate `lint`, `code` - Rename the `#[code = "..."]` attribute to `error`, and add a corresponding `#[lint = "...'}` attribute - Rename `#[error = "..."]` to `message`, so that the same attribute key can be used for both lints and errors

view details

jumbatm

commit sha 5a3d70854588ca755a1d9ef6cff89dd7b0173a85

Error on `message` on non-Span field.

view details

jumbatm

commit sha bf65829f408eb35115f8424dbbdd5ea726a19905

Don't require Applicability for suggestion. Assume Unspecified if it's not provided.

view details

jumbatm

commit sha 7938cd2d9542b032c7b57ba40f0af0b39113aca9

Use Ident instead of String to avoid alloc.

view details

jumbatm

commit sha 38411c1ee4a6e7dc96c91dd6ae7ff2d8469ff3c4

Use quote_spanned!.

view details

jumbatm

commit sha 5a1969561c8f50bb15a16db17a7bad4c9a813e36

Mark tests with ideal Spans.

view details

push time in a month

create barnchjumbatm/rust

branch : session-diagnostic-derive-ideal-spans

created branch time in a month

pull request commentrust-lang/rust

Fix clashing_extern_declarations stack overflow for recursive types.

@rustbot modify labels to -S-waiting-on-author, +S-waiting-on-review

jumbatm

comment created time in a month

push eventjumbatm/rust

jumbatm

commit sha 2e734798a8b8e9d72e64ad03e6bb88a71321f6b4

Actually introduce a cycle in Reffy test.

view details

jumbatm

commit sha f70b81531c1c771fbda1eab4444ad84510e35e66

Remove unnecessary rebinding of def ids.

view details

jumbatm

commit sha 1fd387197985162e849c62a5f2d6e9ee30ad0e0b

Remove structural equiv check for Array const.

view details

jumbatm

commit sha 68b082e43a91e7ef9e887a6b93fc7e505d012cfd

Reduce indentation by replacing match arm w/ early return.

view details

jumbatm

commit sha 928ccdd9e1f494b8cf1b03e2e84e7ab95be58c3f

Don't memoize seen types. That cache is unlikely to be particularly useful within a single invocation of structurally_same_type, especially compared to memoizing results across _all_ invocations of that function.

view details

push time in a month

Pull request review commentrust-lang/rust

Fix clashing_extern_declarations stack overflow for recursive types.

 impl ClashingExternDeclarations {         b: Ty<'tcx>,         ckind: CItemKind,     ) -> bool {-        debug!("structurally_same_type(cx, a = {:?}, b = {:?})", a, b);-        let tcx = cx.tcx;-        if a == b || rustc_middle::ty::TyS::same_type(a, b) {-            // All nominally-same types are structurally same, too.-            true-        } else {-            // Do a full, depth-first comparison between the two.-            use rustc_middle::ty::TyKind::*;-            let a_kind = &a.kind;-            let b_kind = &b.kind;--            let compare_layouts = |a, b| -> bool {-                let a_layout = &cx.layout_of(a).unwrap().layout.abi;-                let b_layout = &cx.layout_of(b).unwrap().layout.abi;-                debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout);-                a_layout == b_layout-            };+        // In order to avoid endlessly recursing on recursive types, we maintain a "seen" set.+        // We'll need to store every combination of types we encounter anyway, so we also memoize+        // the result.+        struct SeenSet<'tcx>(FxHashMap<(Ty<'tcx>, Ty<'tcx>), Option<bool>>);++        enum SeenSetResult {+            /// We've never seen this combination of types.+            Unseen,+            /// We've seen this combination of types, but are still computing the result.+            Computing,+            /// We've seen this combination of types, and have already computed the result.+            Computed(bool),+        }++        impl<'tcx> SeenSet<'tcx> {+            fn new() -> Self {+                SeenSet(FxHashMap::default())+            }+            /// Mark (a, b) as `Computing`.+            fn mark_computing(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {+                self.0.insert((a, b), None);+            }+            /// Mark (a, b) as `Computed(result)`.+            fn mark_computed(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, result: bool) {+                *self.0.get_mut(&(a, b)).expect("Missing prior call to mark_computing") =+                    Some(result);+            }+            fn get(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> SeenSetResult {+                match self.0.get(&(a, b)) {+                    None => SeenSetResult::Unseen,+                    Some(None) => SeenSetResult::Computing,+                    Some(Some(b)) => SeenSetResult::Computed(*b),+                }+            }+        }+        fn structurally_same_type_impl<'tcx>(+            seen_types: &mut SeenSet<'tcx>,+            cx: &LateContext<'tcx>,+            a: Ty<'tcx>,+            b: Ty<'tcx>,+            ckind: CItemKind,+        ) -> bool {+            debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b);+            match seen_types.get(a, b) {+                // If we've already computed the result, just return the memoized result.+                SeenSetResult::Computed(result) => result,+                // We are already in the process of computing structural sameness for this type,+                // meaning we've found a cycle. The types are structurally same, then.+                SeenSetResult::Computing => true,+                // We haven't seen this combination of types at all -- compute their sameness.+                SeenSetResult::Unseen => {+                    seen_types.mark_computing(a, b);+                    let tcx = cx.tcx;+                    let result = if a == b || rustc_middle::ty::TyS::same_type(a, b) {+                        // All nominally-same types are structurally same, too.+                        true+                    } else {+                        // Do a full, depth-first comparison between the two.+                        use rustc_middle::ty::TyKind::*;+                        let a_kind = &a.kind;+                        let b_kind = &b.kind;++                        let compare_layouts = |a, b| -> bool {+                            let a_layout = &cx.layout_of(a).unwrap().layout.abi;+                            let b_layout = &cx.layout_of(b).unwrap().layout.abi;+                            debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout);+                            a_layout == b_layout+                        };++                        #[allow(rustc::usage_of_ty_tykind)]+                        let is_primitive_or_pointer = |kind: &ty::TyKind<'_>| {+                            kind.is_primitive() || matches!(kind, RawPtr(..))+                        }; -            #[allow(rustc::usage_of_ty_tykind)]-            let is_primitive_or_pointer =-                |kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..));--            match (a_kind, b_kind) {-                (Adt(_, a_substs), Adt(_, b_substs)) => {-                    let a = a.subst(cx.tcx, a_substs);-                    let b = b.subst(cx.tcx, b_substs);-                    debug!("Comparing {:?} and {:?}", a, b);--                    if let (Adt(a_def, ..), Adt(b_def, ..)) = (&a.kind, &b.kind) {-                        // Grab a flattened representation of all fields.-                        let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());-                        let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());-                        compare_layouts(a, b)+                        match (a_kind, b_kind) {+                            (Adt(_, a_substs), Adt(_, b_substs)) => {+                                let a = a.subst(cx.tcx, a_substs);+                                let b = b.subst(cx.tcx, b_substs);+                                debug!("Comparing {:?} and {:?}", a, b);++                                if let (Adt(a_def, ..), Adt(b_def, ..)) = (&a.kind, &b.kind) {+                                    // Grab a flattened representation of all fields.+                                    let a_fields =+                                        a_def.variants.iter().flat_map(|v| v.fields.iter());+                                    let b_fields =+                                        b_def.variants.iter().flat_map(|v| v.fields.iter());+                                    compare_layouts(a, b)                             && a_fields.eq_by(                                 b_fields,                                 |&ty::FieldDef { did: a_did, .. },                                  &ty::FieldDef { did: b_did, .. }| {-                                    Self::structurally_same_type(+                                    structurally_same_type_impl(+                                        seen_types,                                         cx,                                         tcx.type_of(a_did),                                         tcx.type_of(b_did),                                         ckind,                                     )                                 },                             )-                    } else {-                        unreachable!()-                    }-                }-                (Array(a_ty, a_const), Array(b_ty, b_const)) => {-                    // For arrays, we also check the constness of the type.-                    a_const.val == b_const.val-                        && Self::structurally_same_type(cx, a_const.ty, b_const.ty, ckind)-                        && Self::structurally_same_type(cx, a_ty, b_ty, ckind)-                }-                (Slice(a_ty), Slice(b_ty)) => Self::structurally_same_type(cx, a_ty, b_ty, ckind),-                (RawPtr(a_tymut), RawPtr(b_tymut)) => {-                    a_tymut.mutbl == b_tymut.mutbl-                        && Self::structurally_same_type(cx, &a_tymut.ty, &b_tymut.ty, ckind)-                }-                (Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {-                    // For structural sameness, we don't need the region to be same.-                    a_mut == b_mut && Self::structurally_same_type(cx, a_ty, b_ty, ckind)-                }-                (FnDef(..), FnDef(..)) => {-                    let a_poly_sig = a.fn_sig(tcx);-                    let b_poly_sig = b.fn_sig(tcx);--                    // As we don't compare regions, skip_binder is fine.-                    let a_sig = a_poly_sig.skip_binder();-                    let b_sig = b_poly_sig.skip_binder();--                    (a_sig.abi, a_sig.unsafety, a_sig.c_variadic)-                        == (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)-                        && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {-                            Self::structurally_same_type(cx, a, b, ckind)-                        })-                        && Self::structurally_same_type(cx, a_sig.output(), b_sig.output(), ckind)-                }-                (Tuple(a_substs), Tuple(b_substs)) => {-                    a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| {-                        Self::structurally_same_type(cx, a_ty, b_ty, ckind)-                    })-                }-                // For these, it's not quite as easy to define structural-sameness quite so easily.-                // For the purposes of this lint, take the conservative approach and mark them as-                // not structurally same.-                (Dynamic(..), Dynamic(..))-                | (Error(..), Error(..))-                | (Closure(..), Closure(..))-                | (Generator(..), Generator(..))-                | (GeneratorWitness(..), GeneratorWitness(..))-                | (Projection(..), Projection(..))-                | (Opaque(..), Opaque(..)) => false,--                // These definitely should have been caught above.-                (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),--                // An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a-                // non-null field.-                (Adt(..), other_kind) | (other_kind, Adt(..))-                    if is_primitive_or_pointer(other_kind) =>-                {-                    let (primitive, adt) =-                        if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) };-                    if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) {-                        ty == primitive-                    } else {-                        compare_layouts(a, b)-                    }+                                } else {+                                    unreachable!()+                                }+                            }+                            (Array(a_ty, a_const), Array(b_ty, b_const)) => {+                                // For arrays, we also check the constness of the type.+                                a_const.val == b_const.val+                                    && structurally_same_type_impl(+                                        seen_types, cx, a_const.ty, b_const.ty, ckind,+                                    )+                                    && structurally_same_type_impl(+                                        seen_types, cx, a_ty, b_ty, ckind,+                                    )+                            }+                            (Slice(a_ty), Slice(b_ty)) => {+                                structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)+                            }+                            (RawPtr(a_tymut), RawPtr(b_tymut)) => {+                                a_tymut.mutbl == b_tymut.mutbl

I see. My reasoning for having them not equal is because I want this case to clash:

mod a {
    extern "C" {
        fn take(_: *const S);
    }
}
mod b {
    extern "C" {
        fn take(_: *mut S);
    }
}

Specifically, I want to guard against the case where take actually mutates the data underneath, but a::take is called with data that was supposed to be immutable -- a conflicting declaration of the mutability of some data should ring some alarm bells.

jumbatm

comment created time in a month

Pull request review commentrust-lang/rust

Fix clashing_extern_declarations stack overflow for recursive types.

 impl ClashingExternDeclarations {         b: Ty<'tcx>,         ckind: CItemKind,     ) -> bool {-        debug!("structurally_same_type(cx, a = {:?}, b = {:?})", a, b);-        let tcx = cx.tcx;-        if a == b || rustc_middle::ty::TyS::same_type(a, b) {-            // All nominally-same types are structurally same, too.-            true-        } else {-            // Do a full, depth-first comparison between the two.-            use rustc_middle::ty::TyKind::*;-            let a_kind = &a.kind;-            let b_kind = &b.kind;--            let compare_layouts = |a, b| -> bool {-                let a_layout = &cx.layout_of(a).unwrap().layout.abi;-                let b_layout = &cx.layout_of(b).unwrap().layout.abi;-                debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout);-                a_layout == b_layout-            };+        // In order to avoid endlessly recursing on recursive types, we maintain a "seen" set.+        // We'll need to store every combination of types we encounter anyway, so we also memoize+        // the result.+        struct SeenSet<'tcx>(FxHashMap<(Ty<'tcx>, Ty<'tcx>), Option<bool>>);++        enum SeenSetResult {+            /// We've never seen this combination of types.+            Unseen,+            /// We've seen this combination of types, but are still computing the result.+            Computing,+            /// We've seen this combination of types, and have already computed the result.+            Computed(bool),

HashSet would definitely suffice. I've only gone with a map here because I figured if I'm needing to store every combination of types encountered anyway, I might as well also store the result once I know it.

To be fair, though, now that I think about it, it's probably unlikely that this cache gets a hit within a single invocation of structurally_same_type... Yeah, I'll get rid of it.

jumbatm

comment created time in a month

PR opened rust-lang/rust

Fix clashing_extern_declarations stack overflow for recursive types.

Fixes #75512 by adding a seen set to structurally_same_type.

+304 -102

0 comment

2 changed files

pr created time in a month

push eventjumbatm/rust

jumbatm

commit sha 3f3815ec141580e4b97738258b97bc753af07152

Fix stack overflow for recursive types. Adds a seen set to structurally_same_type to avoid recursing indefinitely when a reference or pointer member introduces a cycle in the visited types.

view details

push time in a month

create barnchjumbatm/rust

branch : fix-clashing-extern-decl-overflow

created branch time in a month

issue commentrust-lang/rust

Stack overflow in rustc frontend on Windows

Uh oh, that's not good. Thanks for reporting! I'll get on this now.

@rustbot claim

comcma

comment created time in a month

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

+#![deny(unused_must_use)]+use quote::format_ident;+use quote::quote;++use proc_macro::Diagnostic;+use syn::spanned::Spanned;++use std::collections::{HashMap, HashSet};++/// Implements #[derive(SessionDiagnostic)], which allows for errors to be specified as a struct, independent+/// from the actual diagnostics emitting code.+/// ```ignore (pseudo-rust)+/// # extern crate rustc_errors;+/// # use rustc_errors::Applicability;+/// # extern crate rustc_span;+/// # use rustc_span::{symbol::Ident, Span};+/// # extern crate rust_middle;+/// # use rustc_middle::ty::Ty;+/// #[derive(SessionDiagnostic)]+/// #[code = "E0505"]+/// #[error = "cannot move out of {name} because it is borrowed"]+/// pub struct MoveOutOfBorrowError<'tcx> {+///     pub name: Ident,+///     pub ty: Ty<'tcx>,+///     #[label = "cannot move out of borrow"]+///     pub span: Span,+///     #[label = "`{ty}` first borrowed here"]+///     pub other_span: Span,+///     #[suggestion(message = "consider cloning here", code = "{name}.clone()")]+///     pub opt_sugg: Option<(Span, Applicability)>+/// }+/// ```+/// Then, later, to emit the error:+///+/// ```ignore (pseudo-rust)+/// sess.emit_err(MoveOutOfBorrowError {+///     expected,+///     actual,+///     span,+///     other_span,+///     opt_sugg: Some(suggestion, Applicability::MachineApplicable),+/// });+/// ```+pub fn session_diagnostic_derive(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {+    // Names for the diagnostic we build and the session we build it from.+    let diag = format_ident!("diag");+    let sess = format_ident!("sess");++    SessionDiagnosticDerive::new(diag, sess, s).into_tokens()+}++// Checks whether the type name of `ty` matches `name`.+//+// Given some struct at a::b::c::Foo, this will return true for c::Foo, b::c::Foo, or+// a::b::c::Foo. This reasonably allows qualified names to be used in the macro.+fn type_matches_path(ty: &syn::Type, name: &[&str]) -> bool {+    if let syn::Type::Path(ty) = ty {+        ty.path+            .segments+            .iter()+            .map(|s| s.ident.to_string())+            .rev()+            .zip(name.iter().rev())+            .all(|(x, y)| &x.as_str() == y)+    } else {+        false+    }+}++/// The central struct for constructing the as_error method from an annotated struct.+struct SessionDiagnosticDerive<'a> {+    structure: synstructure::Structure<'a>,+    builder: SessionDiagnosticDeriveBuilder<'a>,+}++impl std::convert::From<syn::Error> for SessionDiagnosticDeriveError {+    fn from(e: syn::Error) -> Self {+        SessionDiagnosticDeriveError::SynError(e)+    }+}++/// Equivalent to rustc:errors::diagnostic::DiagnosticId, except stores the quoted expression to+/// initialise the code with.+enum DiagnosticId {+    Error(proc_macro2::TokenStream),+    Lint(proc_macro2::TokenStream),+}++#[derive(Debug)]+enum SessionDiagnosticDeriveError {+    SynError(syn::Error),+    ErrorHandled,+}++impl SessionDiagnosticDeriveError {+    fn to_compile_error(self) -> proc_macro2::TokenStream {+        match self {+            SessionDiagnosticDeriveError::SynError(e) => e.to_compile_error(),+            SessionDiagnosticDeriveError::ErrorHandled => {+                // Return ! to avoid having to create a blank DiagnosticBuilder to return when an+                // error has already been emitted to the compiler.+                quote! {+                    unreachable!()+                }+            }+        }+    }+}++fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnostic {+    Diagnostic::spanned(span, proc_macro::Level::Error, msg)+}++/// For methods that return a Result<_, SessionDiagnosticDeriveError>: emit a diagnostic on+/// span $span with msg $msg (and, optionally, perform additional decoration using the FnOnce+/// passed in `diag`). Then, return Err(ErrorHandled).+macro_rules! throw_span_err {+    ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }};+    ($span:expr, $msg:expr, $f:expr) => {{+        return Err(_throw_span_err($span, $msg, $f));+    }};+}++/// When possible, prefer using throw_span_err! over using this function directly. This only exists+/// as a function to constrain `f` to an impl FnOnce.+fn _throw_span_err(+    span: impl proc_macro::MultiSpan,+    msg: &str,+    f: impl FnOnce(proc_macro::Diagnostic) -> proc_macro::Diagnostic,+) -> SessionDiagnosticDeriveError {+    let diag = span_err(span, msg);+    f(diag).emit();+    SessionDiagnosticDeriveError::ErrorHandled+}++impl<'a> SessionDiagnosticDerive<'a> {+    fn new(diag: syn::Ident, sess: syn::Ident, structure: synstructure::Structure<'a>) -> Self {+        // Build the mapping of field names to fields. This allows attributes to peek values from+        // other fields.+        let mut fields_map = HashMap::new();++        // Convenience bindings.+        let ast = structure.ast();++        if let syn::Data::Struct(syn::DataStruct { fields, .. }) = &ast.data {+            for field in fields.iter() {+                if let Some(ident) = &field.ident {+                    fields_map.insert(ident.to_string(), field);+                }+            }+        }++        Self {+            builder: SessionDiagnosticDeriveBuilder { diag, sess, fields: fields_map, kind: None },+            structure,+        }+    }+    fn into_tokens(self) -> proc_macro2::TokenStream {+        let SessionDiagnosticDerive { structure, mut builder } = self;++        let ast = structure.ast();+        let attrs = &ast.attrs;++        let implementation = {+            if let syn::Data::Struct(..) = ast.data {+                let preamble = {+                    let preamble = attrs.iter().map(|attr| {+                        builder+                            .generate_structure_code(attr)+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    quote! {+                        #(#preamble)*;+                    }+                };++                let body = structure.each(|field_binding| {+                    let field = field_binding.ast();+                    let result = field.attrs.iter().map(|attr| {+                        builder+                            .generate_field_code(+                                attr,+                                FieldInfo {+                                    vis: &field.vis,+                                    binding: field_binding,+                                    ty: &field.ty,+                                    span: &field.span(),+                                },+                            )+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    return quote! {+                        #(#result);*+                    };+                });+                // Finally, putting it altogether.+                match builder.kind {+                    None => {+                        span_err(ast.span().unwrap(), "`code` not specified")+                        .help("use the [code = \"...\"] attribute to set this diagnostic's error code ")+                        .emit();+                        SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+                    }+                    Some((kind, _)) => match kind {+                        DiagnosticId::Lint(_lint) => todo!(),+                        DiagnosticId::Error(code) => {+                            let (diag, sess) = (&builder.diag, &builder.sess);+                            quote! {+                                let mut #diag = #sess.struct_err_with_code("", rustc_errors::DiagnosticId::Error(#code));+                                #preamble+                                match self {+                                    #body+                                }+                                #diag+                            }+                        }+                    },+                }+            } else {+                span_err(+                    ast.span().unwrap(),+                    "`#[derive(SessionDiagnostic)]` can only be used on structs",+                )+                .emit();+                SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+            }+        };++        let sess = &builder.sess;+        structure.gen_impl(quote! {+            gen impl<'a> rustc_session::SessionDiagnostic<'a> for @Self {+                fn into_diagnostic(self, #sess: &'a rustc_session::Session) -> rustc_errors::DiagnosticBuilder<'a> {+                    #implementation+                }+            }+        })+    }+}++/// Field information passed to the builder. Deliberately omits attrs to discourage the generate_*+/// methods from walking the attributes themselves.+struct FieldInfo<'a> {+    vis: &'a syn::Visibility,+    binding: &'a synstructure::BindingInfo<'a>,+    ty: &'a syn::Type,+    span: &'a proc_macro2::Span,+}++/// Tracks persistent information required for building up the individual calls to diagnostic+/// methods for the final generated method. This is a separate struct to SessionDerive only to be+/// able to destructure and split self.builder and the self.structure up to avoid a double mut+/// borrow later on.+struct SessionDiagnosticDeriveBuilder<'a> {+    /// Name of the session parameter that's passed in to the as_error method.+    sess: syn::Ident,++    /// Store a map of field name to its corresponding field. This is built on construction of the+    /// derive builder.+    fields: HashMap<String, &'a syn::Field>,++    /// The identifier to use for the generated DiagnosticBuilder instance.+    diag: syn::Ident,++    /// Whether this is a lint or an error. This dictates how the diag will be initialised. Span+    /// stores at what Span the kind was first set at (for error reporting purposes, if the kind+    /// was multiply specified).+    kind: Option<(DiagnosticId, proc_macro2::Span)>,+}++impl<'a> SessionDiagnosticDeriveBuilder<'a> {+    fn generate_structure_code(+        &mut self,+        attr: &syn::Attribute,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        Ok(match attr.parse_meta()? {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                let name = attr.path.segments.last().unwrap().ident.to_string();+                let name = name.as_str();+                match name {+                    "message" => {+                        let diag = &self.diag;+                        quote! {+                            #diag.set_primary_message(#formatted_str);+                        }+                    }+                    attr @ "error" | attr @ "lint" => {+                        self.set_kind_once(+                            if attr == "error" {+                                DiagnosticId::Error(formatted_str)+                            } else if attr == "lint" {+                                DiagnosticId::Lint(formatted_str)+                            } else {+                                unreachable!()+                            },+                            s.span(),+                        )?;+                        // This attribute is only allowed to be applied once, and the attribute+                        // will be set in the initialisation code.+                        quote! {}+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic struct attribute",+                            other+                        )+                    ),+                }+            }+            _ => todo!("unhandled meta kind"),+        })+    }++    #[must_use]+    fn set_kind_once(+        &mut self,+        kind: DiagnosticId,+        span: proc_macro2::Span,+    ) -> Result<(), SessionDiagnosticDeriveError> {+        if self.kind.is_none() {+            self.kind = Some((kind, span));+            Ok(())+        } else {+            let kind_str = |kind: &DiagnosticId| match kind {+                DiagnosticId::Lint(..) => "lint",+                DiagnosticId::Error(..) => "error",+            };++            let existing_kind = kind_str(&self.kind.as_ref().unwrap().0);+            let this_kind = kind_str(&kind);++            let msg = if this_kind == existing_kind {+                format!("`{}` specified multiple times", existing_kind)+            } else {+                format!("`{}` specified when `{}` was already specified", this_kind, existing_kind)+            };+            throw_span_err!(span.unwrap(), &msg);+        }+    }++    fn generate_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let field_binding = &info.binding.binding;++        let option_ty = option_inner_ty(&info.ty);++        let generated_code = self.generate_non_option_field_code(+            attr,+            FieldInfo {+                vis: info.vis,+                binding: info.binding,+                ty: option_ty.unwrap_or(&info.ty),+                span: info.span,+            },+        )?;+        Ok(if option_ty.is_none() {+            quote! { #generated_code }+        } else {+            quote! {+                if let Some(#field_binding) = #field_binding {+                    #generated_code+                }+            }+        })+    }++    fn generate_non_option_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        let field_binding = &info.binding.binding;+        let name = attr.path.segments.last().unwrap().ident.to_string();+        let name = name.as_str();+        // At this point, we need to dispatch based on the attribute key + the+        // type.+        let meta = attr.parse_meta()?;+        Ok(match meta {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                match name {+                    "message" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.set_span(*#field_binding);+                                #diag.set_primary_message(#formatted_str);+                            }+                        } else {+                            throw_span_err!(+                                attr.span().unwrap(),+                                "the `#[message = \"...\"]` attribute can only be applied to fields of type Span"+                            );+                        }

Actually, I realised I can use quote_span! instead to get the span in the right place:

error[E0277]: the trait bound `rustc_span::MultiSpan: std::convert::From<std::string::String>` is not satisfied
  --> $DIR/session-derive-errors.rs:95:5
   |
LL | /     #[message = "this message is applied to a String field"]
LL | |
LL | |     name: String,
   | |________________^ the trait `std::convert::From<std::string::String>` is not implemented for `rustc_span::MultiSpan`
   |
   = help: the following implementations were found:
             <rustc_span::MultiSpan as std::convert::From<rustc_span::Span>>
             <rustc_span::MultiSpan as std::convert::From<std::vec::Vec<rustc_span::Span>>>
   = note: required because of the requirements on the impl of `std::convert::Into<rustc_span::MultiSpan>` for `std::string::String`
jumbatm

comment created time in a month

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

+#![deny(unused_must_use)]+use quote::format_ident;+use quote::quote;++use proc_macro::Diagnostic;+use syn::spanned::Spanned;++use std::collections::{HashMap, HashSet};++/// Implements #[derive(SessionDiagnostic)], which allows for errors to be specified as a struct, independent+/// from the actual diagnostics emitting code.+/// ```ignore (pseudo-rust)+/// # extern crate rustc_errors;+/// # use rustc_errors::Applicability;+/// # extern crate rustc_span;+/// # use rustc_span::{symbol::Ident, Span};+/// # extern crate rust_middle;+/// # use rustc_middle::ty::Ty;+/// #[derive(SessionDiagnostic)]+/// #[code = "E0505"]+/// #[error = "cannot move out of {name} because it is borrowed"]+/// pub struct MoveOutOfBorrowError<'tcx> {+///     pub name: Ident,+///     pub ty: Ty<'tcx>,+///     #[label = "cannot move out of borrow"]+///     pub span: Span,+///     #[label = "`{ty}` first borrowed here"]+///     pub other_span: Span,+///     #[suggestion(message = "consider cloning here", code = "{name}.clone()")]+///     pub opt_sugg: Option<(Span, Applicability)>+/// }+/// ```+/// Then, later, to emit the error:+///+/// ```ignore (pseudo-rust)+/// sess.emit_err(MoveOutOfBorrowError {+///     expected,+///     actual,+///     span,+///     other_span,+///     opt_sugg: Some(suggestion, Applicability::MachineApplicable),+/// });+/// ```+pub fn session_diagnostic_derive(s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {+    // Names for the diagnostic we build and the session we build it from.+    let diag = format_ident!("diag");+    let sess = format_ident!("sess");++    SessionDiagnosticDerive::new(diag, sess, s).into_tokens()+}++// Checks whether the type name of `ty` matches `name`.+//+// Given some struct at a::b::c::Foo, this will return true for c::Foo, b::c::Foo, or+// a::b::c::Foo. This reasonably allows qualified names to be used in the macro.+fn type_matches_path(ty: &syn::Type, name: &[&str]) -> bool {+    if let syn::Type::Path(ty) = ty {+        ty.path+            .segments+            .iter()+            .map(|s| s.ident.to_string())+            .rev()+            .zip(name.iter().rev())+            .all(|(x, y)| &x.as_str() == y)+    } else {+        false+    }+}++/// The central struct for constructing the as_error method from an annotated struct.+struct SessionDiagnosticDerive<'a> {+    structure: synstructure::Structure<'a>,+    builder: SessionDiagnosticDeriveBuilder<'a>,+}++impl std::convert::From<syn::Error> for SessionDiagnosticDeriveError {+    fn from(e: syn::Error) -> Self {+        SessionDiagnosticDeriveError::SynError(e)+    }+}++/// Equivalent to rustc:errors::diagnostic::DiagnosticId, except stores the quoted expression to+/// initialise the code with.+enum DiagnosticId {+    Error(proc_macro2::TokenStream),+    Lint(proc_macro2::TokenStream),+}++#[derive(Debug)]+enum SessionDiagnosticDeriveError {+    SynError(syn::Error),+    ErrorHandled,+}++impl SessionDiagnosticDeriveError {+    fn to_compile_error(self) -> proc_macro2::TokenStream {+        match self {+            SessionDiagnosticDeriveError::SynError(e) => e.to_compile_error(),+            SessionDiagnosticDeriveError::ErrorHandled => {+                // Return ! to avoid having to create a blank DiagnosticBuilder to return when an+                // error has already been emitted to the compiler.+                quote! {+                    unreachable!()+                }+            }+        }+    }+}++fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnostic {+    Diagnostic::spanned(span, proc_macro::Level::Error, msg)+}++/// For methods that return a Result<_, SessionDiagnosticDeriveError>: emit a diagnostic on+/// span $span with msg $msg (and, optionally, perform additional decoration using the FnOnce+/// passed in `diag`). Then, return Err(ErrorHandled).+macro_rules! throw_span_err {+    ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }};+    ($span:expr, $msg:expr, $f:expr) => {{+        return Err(_throw_span_err($span, $msg, $f));+    }};+}++/// When possible, prefer using throw_span_err! over using this function directly. This only exists+/// as a function to constrain `f` to an impl FnOnce.+fn _throw_span_err(+    span: impl proc_macro::MultiSpan,+    msg: &str,+    f: impl FnOnce(proc_macro::Diagnostic) -> proc_macro::Diagnostic,+) -> SessionDiagnosticDeriveError {+    let diag = span_err(span, msg);+    f(diag).emit();+    SessionDiagnosticDeriveError::ErrorHandled+}++impl<'a> SessionDiagnosticDerive<'a> {+    fn new(diag: syn::Ident, sess: syn::Ident, structure: synstructure::Structure<'a>) -> Self {+        // Build the mapping of field names to fields. This allows attributes to peek values from+        // other fields.+        let mut fields_map = HashMap::new();++        // Convenience bindings.+        let ast = structure.ast();++        if let syn::Data::Struct(syn::DataStruct { fields, .. }) = &ast.data {+            for field in fields.iter() {+                if let Some(ident) = &field.ident {+                    fields_map.insert(ident.to_string(), field);+                }+            }+        }++        Self {+            builder: SessionDiagnosticDeriveBuilder { diag, sess, fields: fields_map, kind: None },+            structure,+        }+    }+    fn into_tokens(self) -> proc_macro2::TokenStream {+        let SessionDiagnosticDerive { structure, mut builder } = self;++        let ast = structure.ast();+        let attrs = &ast.attrs;++        let implementation = {+            if let syn::Data::Struct(..) = ast.data {+                let preamble = {+                    let preamble = attrs.iter().map(|attr| {+                        builder+                            .generate_structure_code(attr)+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    quote! {+                        #(#preamble)*;+                    }+                };++                let body = structure.each(|field_binding| {+                    let field = field_binding.ast();+                    let result = field.attrs.iter().map(|attr| {+                        builder+                            .generate_field_code(+                                attr,+                                FieldInfo {+                                    vis: &field.vis,+                                    binding: field_binding,+                                    ty: &field.ty,+                                    span: &field.span(),+                                },+                            )+                            .unwrap_or_else(|v| v.to_compile_error())+                    });+                    return quote! {+                        #(#result);*+                    };+                });+                // Finally, putting it altogether.+                match builder.kind {+                    None => {+                        span_err(ast.span().unwrap(), "`code` not specified")+                        .help("use the [code = \"...\"] attribute to set this diagnostic's error code ")+                        .emit();+                        SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+                    }+                    Some((kind, _)) => match kind {+                        DiagnosticId::Lint(_lint) => todo!(),+                        DiagnosticId::Error(code) => {+                            let (diag, sess) = (&builder.diag, &builder.sess);+                            quote! {+                                let mut #diag = #sess.struct_err_with_code("", rustc_errors::DiagnosticId::Error(#code));+                                #preamble+                                match self {+                                    #body+                                }+                                #diag+                            }+                        }+                    },+                }+            } else {+                span_err(+                    ast.span().unwrap(),+                    "`#[derive(SessionDiagnostic)]` can only be used on structs",+                )+                .emit();+                SessionDiagnosticDeriveError::ErrorHandled.to_compile_error()+            }+        };++        let sess = &builder.sess;+        structure.gen_impl(quote! {+            gen impl<'a> rustc_session::SessionDiagnostic<'a> for @Self {+                fn into_diagnostic(self, #sess: &'a rustc_session::Session) -> rustc_errors::DiagnosticBuilder<'a> {+                    #implementation+                }+            }+        })+    }+}++/// Field information passed to the builder. Deliberately omits attrs to discourage the generate_*+/// methods from walking the attributes themselves.+struct FieldInfo<'a> {+    vis: &'a syn::Visibility,+    binding: &'a synstructure::BindingInfo<'a>,+    ty: &'a syn::Type,+    span: &'a proc_macro2::Span,+}++/// Tracks persistent information required for building up the individual calls to diagnostic+/// methods for the final generated method. This is a separate struct to SessionDerive only to be+/// able to destructure and split self.builder and the self.structure up to avoid a double mut+/// borrow later on.+struct SessionDiagnosticDeriveBuilder<'a> {+    /// Name of the session parameter that's passed in to the as_error method.+    sess: syn::Ident,++    /// Store a map of field name to its corresponding field. This is built on construction of the+    /// derive builder.+    fields: HashMap<String, &'a syn::Field>,++    /// The identifier to use for the generated DiagnosticBuilder instance.+    diag: syn::Ident,++    /// Whether this is a lint or an error. This dictates how the diag will be initialised. Span+    /// stores at what Span the kind was first set at (for error reporting purposes, if the kind+    /// was multiply specified).+    kind: Option<(DiagnosticId, proc_macro2::Span)>,+}++impl<'a> SessionDiagnosticDeriveBuilder<'a> {+    fn generate_structure_code(+        &mut self,+        attr: &syn::Attribute,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        Ok(match attr.parse_meta()? {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                let name = attr.path.segments.last().unwrap().ident.to_string();+                let name = name.as_str();+                match name {+                    "message" => {+                        let diag = &self.diag;+                        quote! {+                            #diag.set_primary_message(#formatted_str);+                        }+                    }+                    attr @ "error" | attr @ "lint" => {+                        self.set_kind_once(+                            if attr == "error" {+                                DiagnosticId::Error(formatted_str)+                            } else if attr == "lint" {+                                DiagnosticId::Lint(formatted_str)+                            } else {+                                unreachable!()+                            },+                            s.span(),+                        )?;+                        // This attribute is only allowed to be applied once, and the attribute+                        // will be set in the initialisation code.+                        quote! {}+                    }+                    other => throw_span_err!(+                        attr.span().unwrap(),+                        &format!(+                            "`#[{} = ...]` is not a valid SessionDiagnostic struct attribute",+                            other+                        )+                    ),+                }+            }+            _ => todo!("unhandled meta kind"),+        })+    }++    #[must_use]+    fn set_kind_once(+        &mut self,+        kind: DiagnosticId,+        span: proc_macro2::Span,+    ) -> Result<(), SessionDiagnosticDeriveError> {+        if self.kind.is_none() {+            self.kind = Some((kind, span));+            Ok(())+        } else {+            let kind_str = |kind: &DiagnosticId| match kind {+                DiagnosticId::Lint(..) => "lint",+                DiagnosticId::Error(..) => "error",+            };++            let existing_kind = kind_str(&self.kind.as_ref().unwrap().0);+            let this_kind = kind_str(&kind);++            let msg = if this_kind == existing_kind {+                format!("`{}` specified multiple times", existing_kind)+            } else {+                format!("`{}` specified when `{}` was already specified", this_kind, existing_kind)+            };+            throw_span_err!(span.unwrap(), &msg);+        }+    }++    fn generate_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let field_binding = &info.binding.binding;++        let option_ty = option_inner_ty(&info.ty);++        let generated_code = self.generate_non_option_field_code(+            attr,+            FieldInfo {+                vis: info.vis,+                binding: info.binding,+                ty: option_ty.unwrap_or(&info.ty),+                span: info.span,+            },+        )?;+        Ok(if option_ty.is_none() {+            quote! { #generated_code }+        } else {+            quote! {+                if let Some(#field_binding) = #field_binding {+                    #generated_code+                }+            }+        })+    }++    fn generate_non_option_field_code(+        &mut self,+        attr: &syn::Attribute,+        info: FieldInfo<'_>,+    ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {+        let diag = &self.diag;+        let field_binding = &info.binding.binding;+        let name = attr.path.segments.last().unwrap().ident.to_string();+        let name = name.as_str();+        // At this point, we need to dispatch based on the attribute key + the+        // type.+        let meta = attr.parse_meta()?;+        Ok(match meta {+            syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => {+                let formatted_str = self.build_format(&s.value(), attr.span());+                match name {+                    "message" => {+                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {+                            quote! {+                                #diag.set_span(*#field_binding);+                                #diag.set_primary_message(#formatted_str);+                            }+                        } else {+                            throw_span_err!(+                                attr.span().unwrap(),+                                "the `#[message = \"...\"]` attribute can only be applied to fields of type Span"+                            );+                        }

The error message without intervention looks like this:

error[E0277]: the trait bound `rustc_span::MultiSpan: std::convert::From<std::string::String>` is not satisfied
  --> $DIR/session-derive-errors.rs:92:10
   |
LL | #[derive(SessionDiagnostic)]
   |          ^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::string::String>` is not implemented for `rustc_span::MultiSpan`
   |
   = help: the following implementations were found:
             <rustc_span::MultiSpan as std::convert::From<rustc_span::Span>>
             <rustc_span::MultiSpan as std::convert::From<std::vec::Vec<rustc_span::Span>>>
   = note: required because of the requirements on the impl of `std::convert::Into<rustc_span::MultiSpan>` for `std::string::String`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

The message itself is fine, but the span it's on isn't particularly helpful, unfortunately. I wonder if there's some way I can just correct the span..

jumbatm

comment created time in a month

push eventjumbatm/rust

jumbatm

commit sha 6006416d417513614604aa80a4210aab53994f3d

Use Ident instead of String to avoid alloc.

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 19dc6d5d15544b82ae9c27e0616afd8012b6a315

Rename some attrs, handle duplicate `lint`, `code` - Rename the `#[code = "..."]` attribute to `error`, and add a corresponding `#[lint = "...'}` attribute - Rename `#[error = "..."]` to `message`, so that the same attribute key can be used for both lints and errors

view details

jumbatm

commit sha 13ea274af45c2ef5d4d48c04aa41fc95f3f7f180

Error on `message` on non-Span field.

view details

jumbatm

commit sha eaeb687c372d88e5ecbedcf2da2c900598b5c59e

Don't require Applicability for suggestion. Assume Unspecified if it's not provided.

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 1635175846b689f6c3f373b95faa5eb78f619204

fixup! Apply suggestions from code review

view details

jumbatm

commit sha fe5af93f23c0aa89e539c182d43ba362eb61b19b

Move FieldAlreadyDeclared into its own `errors` module.

view details

jumbatm

commit sha 600ae169fdb2b534b974684a883f8e8c0c681451

Remove unnecessary #[doc(hidden)].

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha dd14193bb7a020dd70c11bfac253d0700387d2c2

Apply suggestions from code review Co-authored-by: Oliver Scherer <github35764891676564198441@oli-obk.de>

view details

push time in 2 months

PR opened rust-lang/rust

Deny clashing extern declarations by default.

Changes the clashing_extern_declarations lint to be deny by default, as the lint addresses a soundness issue (see #70496).

Note that this change should go through a crater-check run before being merged (as mentioned in https://github.com/rust-lang/rust/pull/70946#issuecomment-632084879).

r? @nagisa

+4 -39

0 comment

4 changed files

pr created time in 2 months

push eventjumbatm/rust

Tim Diekmann

commit sha 076ef66ba2f647a627806f376c23b332fb04d3ff

Remove in-place allocation and revert to separate methods for zeroed allocations Fix docs

view details

Tim Diekmann

commit sha b01fbc437eae177cd02e7798f2f1454c1c6ed6e5

Simplify implementations of `AllocRef` for `Global` and `System`

view details

Tim Diekmann

commit sha 9cd9286e20e6fe4cdb7e298fa5ec966eb26fa32b

Update doc-comment for grow_zeroed

view details

Tim Diekmann

commit sha db7d07b83bee302be977468caa6931f651b4f77a

Remove a trailing whitespace

view details

Tim Diekmann

commit sha 24ddf76ed7bc453826e6e843cd0ca289e02185f1

Merge branch 'master' into remove-in-place-alloc

view details

Tim Diekmann

commit sha 6395659168a760b31365e925dc5be5a201ac10ae

Apply suggestions from code review Co-authored-by: Amanieu d'Antras <amanieu@gmail.com>

view details

Bastian Kauschke

commit sha 06dbd06e4deab2255d310d38ed0ea28becf43664

forbid `#[track_caller]` on main

view details

Nicholas Nethercote

commit sha eeb4b83289e09956e0dda174047729ca87c709fe

Remove two fields from `SubstFolder`. They're only used in error messages printed if there's an internal compiler error, and the cost of maintaining them is high enough to show up in profiles.

view details

Yuki Okushi

commit sha cd7204ef394d1e53bb967086186e9b8664d7e268

Forbid non-derefable types explicitly in unsizing casts

view details

Ivan Tham

commit sha c577d71e03cebb03d079670e8b9ce995fb79560b

Remove log alias from librustdoc

view details

Guillaume Gomez

commit sha 0275cd74096b71f6c641b06e73e6cb359303d6cc

Clean up E0745

view details

bors

commit sha 5f6bd6ec0ac422991b89bb8643eaa5d9d46eed11

Auto merge of #74850 - TimDiekmann:remove-in-place-alloc, r=Amanieu Remove in-place allocation and revert to separate methods for zeroed allocations closes rust-lang/wg-allocators#58

view details

Felix Yan

commit sha 6d75d7c0843dc0f2b64b4427e3290222ef558227

Correct a typo in interpret/memory.rs

view details

Tim Diekmann

commit sha ab9362ad9a9b4b93951ccb577224dda367923226

Replace `Memoryblock` with `NonNull<[u8]>`

view details

bors

commit sha d08eb98698cbce56e599324fb83d55eef2cac408

Auto merge of #75133 - nnethercote:rm-SubstFolder-fields, r=matthewjasper Remove two fields from `SubstFolder`. They're only used in error messages printed if there's an internal compiler error, and the cost of maintaining them is high enough to show up in profiles. r? @matthewjasper

view details

Tim Diekmann

commit sha 929e37d4bfb2d6c99094a8a89c5feda47d25bbbe

Revert renaming of "memory block"

view details

Tim Diekmann

commit sha 93d98328d161bcdf002f9d2f7f916f01c6fce3b1

Revert missing "memory block"

view details

David Wood

commit sha 5f89f02c4e7d06dcb94434b8b30ce457b06eda5c

mir: use `FiniteBitSet<u32>` in polymorphization This commit changes polymorphization to return a `FiniteBitSet<u32>` rather than a `FiniteBitSet<u64>` because most functions do not use anywhere near sixty-four generic parameters so keeping a `u64` around is unnecessary in most cases. Signed-off-by: David Wood <david@davidtw.co>

view details

Rich Kadel

commit sha e0dc8dec273b4cba44a91c1b4433e3dcd117919f

Completes support for coverage in external crates The prior PR corrected for errors encountered when trying to generate the coverage map on source code inlined from external crates (including macros and generics) by avoiding adding external DefIds to the coverage map. This made it possible to generate a coverage report including external crates, but the external crate coverage was incomplete (did not include coverage for the DefIds that were eliminated. The root issue was that the coverage map was converting Span locations to source file and locations, using the SourceMap for the current crate, and this would not work for spans from external crates (compliled with a different SourceMap). The solution was to convert the Spans to filename and location during MIR generation instead, so precompiled external crates would already have the correct source code locations embedded in their MIR, when imported into another crate.

view details

David Wood

commit sha 70b49c7bddec33e6972610e024fcbb3576aa9be3

metadata: skip empty polymorphization bitset This commit skips encoding empty polymorphization results - while polymorphization is disabled, this should be every polymorphization result; but when polymorphization is re-enabled, this would help with non-generic functions and those which do use all their parameters (most functions). Signed-off-by: David Wood <david@davidtw.co>

view details

push time in 2 months

create barnchjumbatm/rust

branch : deny-clashing-extern-declarations

created branch time in 2 months

Pull request review commentrust-lang/rust

Add derive macro for specifying diagnostics using attributes.

 fn convert_variant(             let fid = tcx.hir().local_def_id(f.hir_id);             let dup_span = seen_fields.get(&f.ident.normalize_to_macros_2_0()).cloned();             if let Some(prev_span) = dup_span {-                struct_span_err!(-                    tcx.sess,-                    f.span,-                    E0124,-                    "field `{}` is already declared",-                    f.ident-                )-                .span_label(f.span, "field already declared")-                .span_label(prev_span, format!("`{}` first declared here", f.ident))-                .emit();+                #[derive(SessionDiagnostic)]+                #[code = "E0124"]+                struct FieldAlreadyDeclared {+                    field_name: String,+                    #[error = "field `{field_name}` is already declared"]+                    #[label = "field already declared"]+                    span: Span,+                    #[label = "`{field_name}` first declared here"]+                    prev_span: Span,+                }++                tcx.sess.emit_err(FieldAlreadyDeclared {+                    field_name: f.ident.to_string(),+                    span: f.span,+                    prev_span,+                });

Here's an existing diagnostic I've replaced, which demonstrates an actual usage of the derive macro.

jumbatm

comment created time in 2 months

PR opened rust-lang/rust

Add derive macro for specifying diagnostics using attributes.

Introduces #[derive(SessionDiagnostic)], a derive macro for specifying structs that can be converted to Diagnostics using directions given by attributes on the struct and its fields. Currently, the following attributes have been implemented:

  • #[code = "..."] -- this sets the Diagnostic's error code, and must be provided on the struct iself (ie, not on a field). Equivalent to calling code.
  • #[error = "..."] -- this sets the Diagnostic's primary error message.
  • #[label = "..."] -- this must be applied to fields of type Span, and is equivalent to span_label
  • #[suggestion(..)] -- this allows a suggestion message to be supplied. This attribute must be applied to a field of type (Span, Applicability), and is equivalent to calling span_suggestion. Valid arguments are:
    • message = "..." -- this sets the suggestion message.
    • (Optional) code = "..." -- this suggests code for the suggestion. Defaults to empty.

suggestionalso comes with other variants: #[suggestion_short(..)], #[suggestion_hidden(..)] and #[suggestion_verbose(..)] which all take the same keys.

Within the strings passed to each attribute, fields can be referenced without needing to be passed explicitly into the format string -- eg, #[error = "{ident} already declared"] will set the error message to format!("{} already declared", &self.ident). Any fields on the struct can be referenced in this way.

Additionally, for any of these attributes, Option fields can be used to only optionally apply the decoration -- for example:

#[derive(SessionDiagnostic)]
#[code = "E0123"]
struct SomeKindOfError {
    ...
    #[suggestion(message = "informative error message")]
    opt_sugg: Option<(Span, Applicability)>
    ...
}

will not emit a suggestion if opt_sugg is None.

This PR is still a work in progress, but I'd like to get some feedback first on the convenience and usability of this derive macro from a user point of view. This is also the first derive macro I've written, so I'm very open to any suggestions regarding the code structure and cleanliness.

Closes #61132.

r? @oli-obk

+1030 -10

0 comment

10 changed files

pr created time in 2 months

push eventjumbatm/rust

Alex Crichton

commit sha 2c1b0467e02a763a61335b8acb3c29524bcb9e6d

rustc: Improving safe wasm float->int casts This commit improves code generation for WebAssembly targets when translating floating to integer casts. This improvement is only relevant when the `nontrapping-fptoint` feature is not enabled, but the feature is not enabled by default right now. Additionally this improvement only affects safe casts since unchecked casts were improved in #74659. Some more background for this issue is present on #73591, but the general gist of the issue is that in LLVM the `fptosi` and `fptoui` instructions are defined to return an `undef` value if they execute on out-of-bounds values; they notably do not trap. To implement these instructions for WebAssembly the LLVM backend must therefore generate quite a few instructions before executing `i32.trunc_f32_s` (for example) because this WebAssembly instruction traps on out-of-bounds values. This codegen into wasm instructions happens very late in the code generator, so what ends up happening is that rustc inserts its own codegen to implement Rust's saturating semantics, and then LLVM also inserts its own codegen to make sure that the `fptosi` instruction doesn't trap. Overall this means that a function like this: #[no_mangle] pub unsafe extern "C" fn cast(x: f64) -> u32 { x as u32 } will generate this WebAssembly today: (func $cast (type 0) (param f64) (result i32) (local i32 i32) local.get 0 f64.const 0x1.fffffffep+31 (;=4.29497e+09;) f64.gt local.set 1 block ;; label = @1 block ;; label = @2 local.get 0 f64.const 0x0p+0 (;=0;) local.get 0 f64.const 0x0p+0 (;=0;) f64.gt select local.tee 0 f64.const 0x1p+32 (;=4.29497e+09;) f64.lt local.get 0 f64.const 0x0p+0 (;=0;) f64.ge i32.and i32.eqz br_if 0 (;@2;) local.get 0 i32.trunc_f64_u local.set 2 br 1 (;@1;) end i32.const 0 local.set 2 end i32.const -1 local.get 2 local.get 1 select) This PR improves the situation by updating the code generation for float-to-int conversions in rustc, specifically only for WebAssembly targets and only for some situations (float-to-u8 still has not great codegen). The fix here is to use basic blocks and control flow to avoid speculatively executing `fptosi`, and instead LLVM's raw intrinsic for the WebAssembly instruction is used instead. This effectively extends the support added in #74659 to checked casts. After this commit the codegen for the above Rust function looks like: (func $cast (type 0) (param f64) (result i32) (local i32) block ;; label = @1 local.get 0 f64.const 0x0p+0 (;=0;) f64.ge local.tee 1 i32.const 1 i32.xor br_if 0 (;@1;) local.get 0 f64.const 0x1.fffffffep+31 (;=4.29497e+09;) f64.le i32.eqz br_if 0 (;@1;) local.get 0 i32.trunc_f64_u return end i32.const -1 i32.const 0 local.get 1 select) For reference, in Rust 1.44, which did not have saturating float-to-integer casts, the codegen LLVM would emit is: (func $cast (type 0) (param f64) (result i32) block ;; label = @1 local.get 0 f64.const 0x1p+32 (;=4.29497e+09;) f64.lt local.get 0 f64.const 0x0p+0 (;=0;) f64.ge i32.and i32.eqz br_if 0 (;@1;) local.get 0 i32.trunc_f64_u return end i32.const 0) So we're relatively close to the original codegen, although it's slightly different because the semantics of the function changed where we're emulating the `i32.trunc_sat_f32_s` instruction rather than always replacing out-of-bounds values with zero. There is still work that could be done to improve casts such as `f32` to `u8`. That form of cast still uses the `fptosi` instruction which generates lots of branch-y code. This seems less important to tackle now though. In the meantime this should take care of most use cases of floating-point conversion and as a result I'm going to speculate that this... Closes #73591

view details

Erik Desjardins

commit sha c596e01b8ea34bb46444005425cd5aa825515f7b

add track_caller to RefCell::{borrow, borrow_mut} So panic messages point at the offending borrow.

view details

carbotaniuman

commit sha 784dd22aac3f58eebc73ff54ae0ea43682392e68

add `unsigned_abs` to signed integers

view details

Stein Somers

commit sha f5c47fa44d64b7ae529147f9b0122b7ecda1bd92

Move bulk of BTreeMap::insert method down to new method on handle

view details

Lukas Wirth

commit sha 35d6a2ef2ba71d5ea120c2879825968babcf9a89

Lint path statements to use drop for drop types

view details

Vadim Petrochenkov

commit sha 0eacf02f01b4ea084a4f970e487ce6d3a6a20f90

tests: Ignore src/test/debuginfo/rc_arc.rs on Windows It requires loading pretty-printers, but GDB doesn't load them on Windows

view details

Stein Somers

commit sha 532e7f49fc6719528d37f69373aec821b09cd478

Separate off a leafy insert function instead of lying, and split split similarly

view details

Tomasz Miąsko

commit sha 82651db9b2f6ecb16c773e8afa301c862118bb82

Fix change detection in CfgSimplifier::collapse_goto_chain Check that the old target is different from the new collapsed one, before concluding that anything changed.

view details

Tomasz Miąsko

commit sha 7f9f2ff9f40ed46a209cf232429120333fe42455

Remove redundant assignment from CfgSimplifier

view details

Joshua Nelson

commit sha e97e6fbe343d0afac795e6c13201ce31047dc219

Fix logging for rustdoc

view details

Yuki Okushi

commit sha 2e5c50195aa0345e174ff9970ec58b7e154c0132

Do not trigger `unused_braces` for `while let`

view details

bors

commit sha 1b0ff9e7d0620daa86a80bf92f6b661f7699984e

Auto merge of #75068 - petrochenkov:ignore-debinfo, r=Mark-Simulacrum tests: Ignore src/test/debuginfo/rc_arc.rs on Windows It requires loading pretty-printers (`src\etc\gdb_load_rust_pretty_printers.py`), but GDB doesn't load them on Windows. Not sure how this passes through CI, due to an old GDB version perhaps?

view details

bors

commit sha dbc2ef25fb5e15445de38f19ba75547a6cf35cae

Auto merge of #75076 - tmiasko:simplify-goto, r=oli-obk Fix change detection in CfgSimplifier::collapse_goto_chain Check that the old target is different from the new collapsed one, before concluding that anything changed. Fixes #75074 Fixes #75051

view details

kennytm

commit sha fd7596c9a538b3c51f2d55c2d5f6ef881e6ba742

fix broken git commit in stdarch

view details

bors

commit sha c186aed59ab590eb586751afaf6b9e0ea9b78099

Auto merge of #75092 - kennytm:fix-75009, r=pietroalbini Fix broken git commit in stdarch Follow-up on #75009, point to the real master commit.

view details

David Sonder

commit sha f130e18c01a0108af23710418d8fb9eddb7647e1

Enable docs on in the x86_64-unknown-linux-musl manifest Add the rust-docs component to toolchain x86_64-unknown-linux-musl, which allows people using rustup on their musl-based linux distribution to download the rust-docs. Generating and uploading the docs was enabled in b5d143b.

view details

Mark Rousskov

commit sha d2fc809fdb2e92581a0ecd70dec3e179dbd3439a

Disable building rust-analyzer on riscv64 riscv64 has an LLVM bug that makes rust-analyzer not build.

view details

bors

commit sha 829d69b9c6bfc535a92fc290ec9391a0d5af6c81

Auto merge of #74827 - ssomers:btree_cleanup_insert, r=Mark-Simulacrum Move bulk of BTreeMap::insert method down to new method on handle Adjust the boundary between the map and node layers for insertion: do more in the node layer, keep root manipulation and pointer dereferencing separate. No change in undefined behaviour or performance. r? @Mark-Simulacrum

view details

Aaron Hill

commit sha 6deda6a6a05e6e6ace8fb015d610c6355efb0fd7

Stabilize Ident::new_raw Tracking issue: #54723 This is a continuation of PR #59002

view details

Vadim Petrochenkov

commit sha 0a88346be64d0c64771d72ada8583e5795416556

rustc_ast: `(Nested)MetaItem::check_name` -> `has_name` For consistency with `Attribute::has_name` which doesn't mark the attribute as used either. Replace all uses of `check_name` with `has_name` outside of rustc

view details

push time in 2 months

push eventjumbatm/rust

Aaron Hill

commit sha ac9dfc3e7785c9bba96ebac4fd51726189e1bf91

Normalize opaque types when converting `ParamEnv` to `Reveal::All` Fixes #65918

view details

Aaron Hill

commit sha 117a60e1f5045e317d3f76ce60be28d18c694608

Erase regions in try_eval_bits

view details

Aaron Hill

commit sha 90aee14eb95ac0b9ddb7cf5db6d003155e94800c

Skip computing param_env and size if not needed

view details

Aaron Hill

commit sha 5e2e927e0107916b825b164c82be44877ac6ab54

Fix rebase fallout

view details

Pietro Albini

commit sha cb76f821942053091706b7bb2c4dc416bb09bfb9

ci: avoid symlinking the build directory on self-hosted builders

view details

Pietro Albini

commit sha fe5a40eb14f233554a30c038cf8944b2d2adf9ff

ci: add aarch64-gnu as a fallible auto builder

view details

Guillaume Gomez

commit sha 403164569170e3f5c06db8b66257ac61db7cff4b

Clean up E0728 explanation

view details

Andy Russell

commit sha 0b320086425937b17bda5ee9e856ac6441d71d96

report kind of deprecated item in message This is important for fields, which are incorrectly referred to as "items".

view details

Alan Somers

commit sha 013e1a6e9f73125734cb919d9b6220b3a4710d67

Enable the profiler on FreeBSD FreeBSD has been doing this in our own package builds for two months now. https://svnweb.freebsd.org/ports?view=revision&revision=535771

view details

Stein Somers

commit sha c4f4639e1a2eb07d17e7393a1c7f0594f0c11faf

Remove into_slices and its unsafe block

view details

Alexis Bourget

commit sha 36bb5e8a4247888c7e1ce5a06ba3aaf5dc9cafd5

Clarify the doc for MaybeUninit::zeroed on incorrect use

view details

Alex Crichton

commit sha 06d565c967bfb7c6ff52a991bbe47b4a2a25de3e

std: Switch from libbacktrace to gimli This commit is a proof-of-concept for switching the standard library's backtrace symbolication mechanism on most platforms from libbacktrace to gimli. The standard library's support for `RUST_BACKTRACE=1` requires in-process parsing of object files and DWARF debug information to interpret it and print the filename/line number of stack frames as part of a backtrace. Historically this support in the standard library has come from a library called "libbacktrace". The libbacktrace library seems to have been extracted from gcc at some point and is written in C. We've had a lot of issues with libbacktrace over time, unfortunately, though. The library does not appear to be actively maintained since we've had patches sit for months-to-years without comments. We have discovered a good number of soundness issues with the library itself, both when parsing valid DWARF as well as invalid DWARF. This is enough of an issue that the libs team has previously decided that we cannot feed untrusted inputs to libbacktrace. This also doesn't take into account the portability of libbacktrace which has been difficult to manage and maintain over time. While possible there are lots of exceptions and it's the main C dependency of the standard library right now. For years it's been the desire to switch over to a Rust-based solution for symbolicating backtraces. It's been assumed that we'll be using the Gimli family of crates for this purpose, which are targeted at safely and efficiently parsing DWARF debug information. I've been working recently to shore up the Gimli support in the `backtrace` crate. As of a few weeks ago the `backtrace` crate, by default, uses Gimli when loaded from crates.io. This transition has gone well enough that I figured it was time to start talking seriously about this change to the standard library. This commit is a preview of what's probably the best way to integrate the `backtrace` crate into the standard library with the Gimli feature turned on. While today it's used as a crates.io dependency, this commit switches the `backtrace` crate to a submodule of this repository which will need to be updated manually. This is not done lightly, but is thought to be the best solution. The primary reason for this is that the `backtrace` crate needs to do some pretty nontrivial filesystem interactions to locate debug information. Working without `std::fs` is not an option, and while it might be possible to do some sort of trait-based solution when prototyped it was found to be too unergonomic. Using a submodule allows the `backtrace` crate to build as a submodule of the `std` crate itself, enabling it to use `std::fs` and such. Otherwise this adds new dependencies to the standard library. This step requires extra attention because this means that these crates are now going to be included with all Rust programs by default. It's important to note, however, that we're already shipping libbacktrace with all Rust programs by default and it has a bunch of C code implementing all of this internally anyway, so we're basically already switching already-shipping functionality to Rust from C. * `object` - this crate is used to parse object file headers and contents. Very low-level support is used from this crate and almost all of it is disabled. Largely we're just using struct definitions as well as convenience methods internally to read bytes and such. * `addr2line` - this is the main meat of the implementation for symbolication. This crate depends on `gimli` for DWARF parsing and then provides interfaces needed by the `backtrace` crate to turn an address into a filename / line number. This crate is actually pretty small (fits in a single file almost!) and mirrors most of what `dwarf.c` does for libbacktrace. * `miniz_oxide` - the libbacktrace crate transparently handles compressed debug information which is compressed with zlib. This crate is used to decompress compressed debug sections. * `gimli` - not actually used directly, but a dependency of `addr2line`. * `adler32`- not used directly either, but a dependency of `miniz_oxide`. The goal of this change is to improve the safety of backtrace symbolication in the standard library, especially in the face of possibly malformed DWARF debug information. Even to this day we're still seeing segfaults in libbacktrace which could possibly become security vulnerabilities. This change should almost entirely eliminate this possibility whilc also paving the way forward to adding more features like split debug information. Some references for those interested are: * Original addition of libbacktrace - #12602 * OOM with libbacktrace - #24231 * Backtrace failure due to use of uninitialized value - #28447 * Possibility to feed untrusted data to libbacktrace - #21889 * Soundness fix for libbacktrace - #33729 * Crash in libbacktrace - #39468 * Support for macOS, never merged - ianlancetaylor/libbacktrace#2 * Performance issues with libbacktrace - #29293, #37477 * Update procedure is quite complicated due to how many patches we need to carry - #50955 * Libbacktrace doesn't work on MinGW with dynamic libs - #71060 * Segfault in libbacktrace on macOS - #71397 Switching to Rust will not make us immune to all of these issues. The crashes are expected to go away, but correctness and performance may still have bugs arise. The gimli and `backtrace` crates, however, are actively maintained unlike libbacktrace, so this should enable us to at least efficiently apply fixes as situations come up.

view details

Paul Sajna

commit sha 7baa87fccf2d9788530e6efc762d326d47d68617

bump libc version to 0.2.74

view details

Simon Sapin

commit sha d8bcf75206e88e07cabd95b87418fe98c5fa2b95

Make `Vec::leak` a method instead of an associated function. The reason for `Box::leak` not to be a method (`Deref` to an arbitrary `T` which might have its own, different `leak` method) does not apply.

view details

Simon Sapin

commit sha 7d759f539f363125511f1edd9ad30934367f409b

Stabilize `Vec::leak`

view details

Manish Goregaokar

commit sha abaf38ccb08d64a2a2c6b5d66dca2b58c2427664

Rename intra_doc_link_resolution_failure -> intra_doc_link_resolution_failures

view details

Manish Goregaokar

commit sha 48de8ac0416853aaf76fcbe721efe9f11e27bd9d

Rename usage of intra_doc_link_resolution_failure

view details

Manish Goregaokar

commit sha da0b10c4fb2ff230fd68e3096c467da5dd82e89e

Register renamed lint

view details

Bastian Kauschke

commit sha 870b7cbb11d799bcabc6eb5a919a27821c981bc1

improve chunks + windows err on size 0

view details

Bastian Kauschke

commit sha d405347f095a20d832261bbf777c8214d7e61dc9

adds `slice::array_chunks`

view details

push time in 2 months

create barnchjumbatm/rust

branch : session-diagnostic-derive

created branch time in 2 months

delete branch jumbatm/rust

delete branch : session-diagnostic

delete time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 016930058786a2e492df6dfc916561be06e356e8

quote preamble earlier to avoid collect.

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 2bb3b817d3db4633e8094552c9990f7fe7d30efe

quote! preamble earlier to avoid collect.

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha c8f7274953d0ec2ece9ff5ec37050c82d978a9ed

Handle #[suggestion]

view details

jumbatm

commit sha 987f9b13d9c74c111b0f5b56dc60d161b978ce0a

Allow Option<..> fields.

view details

jumbatm

commit sha 0fc899d3d42717c365e7901ccd4932862fde1e76

Address FIXME about duplicated logic.

view details

jumbatm

commit sha 5dbd4b04ffcb92446353c914fd8ab2ebfcc3f0da

Add build method to SessionDeriveBuilder. This lets SessionDeriveBuilder fully encapsulate the process of converting an annotated synstructure::Structure into its tokens.

view details

jumbatm

commit sha f09516bad923fd3f3d0f49bf5e6c5cee6f24c864

Fix up doc tests.

view details

jumbatm

commit sha b539f8c0ba3596963e05a1e9acda1c5acec9984c

Add stderr.

view details

jumbatm

commit sha e819d336b67dd75228fc68b60581aea03b04a1b0

Rename to_tokens to to_compile_error

view details

jumbatm

commit sha 09b2a907d54490f3c185803883a0c8998f1d5c64

Rename AsSessionError to SessionDiagnostic.

view details

jumbatm

commit sha 6c6104e94de29fad0c61369836a1b90d8bcd81fd

Add throw_span_err!

view details

jumbatm

commit sha c48589a81d963f975024ba593cf3a38afb3be848

Fix up tests.

view details

jumbatm

commit sha 956e997fdc6f0d9105ad3eca166f15601bc8b3a0

Prefer emitting diagnostics immediately.

view details

jumbatm

commit sha ba47b7de64f8dea75f23736328e17880bc6602ab

Clean up error for unrecognised attr list types.

view details

jumbatm

commit sha 74b12e32c04556c24e387e182229f95d1a3d78d3

Rename to SessionDiagnosticDerive[Builder]

view details

jumbatm

commit sha b6fb5dde918a4c5bb4680e1f0ca20e5d457b2107

Add build method to SessionDeriveBuilder.

view details

jumbatm

commit sha 209b3b13bbadb1b3a2f9cefcf5d161dd0f2c3dfe

Make throw_span_err take an impl MultiSpan.

view details

jumbatm

commit sha 9a148b99952561871632eaa146f81b8cdc58585d

Move *Info structs closer to Builder.

view details

jumbatm

commit sha 68fe09c4fb6407619f3b573e322e2affae690a37

Emit diagnostic when applied on enums.

view details

jumbatm

commit sha 2189055cccad23602bd25549184ab82bfe5e8cf7

Run RustFmt

view details

jumbatm

commit sha 6c6031f5579b5be47992606ee8b3941059346427

Remove allows at top of file and fix fallout.

view details

jumbatm

commit sha a6aa810b56cd2d8f21eed65d5f73d79a702aca31

Mark emit_err example as pseudo-Rust.

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 102d9b6c6635da12797b4b6b0ad0ce391392cdc0

Emit diagnostic when applied on enums.

view details

jumbatm

commit sha 7570de29088ca1144b3072eea137b946e1ff1f17

Run RustFmt

view details

push time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 36dafc7d66dc4d2a3b1f40a87755b3e96cc7b1ce

Move *Info structs closer to Builder.

view details

push time in 2 months

push eventjumbatm/rust

Guillaume Gomez

commit sha 633d1a5af96db7eccb8aeeb07ff31b06aaf07b5f

Clean up E0720 explanation

view details

Dan Aloni

commit sha 28e27566782e5f2636b9c93a172c19024630233d

librustc_typeck: use diag item instead of string compare

view details

Dan Aloni

commit sha d077767ee72221f2a436692ef85115381671a765

Update src/librustc_typeck/check/op.rs Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

Bastian Kauschke

commit sha 49b1971263971db49e821f81bb54991b7de5ab43

add const generics

view details

Rich Kadel

commit sha 12ddd6073abecb7a515a43bee37408596e322345

Fixed coverage map issues; better aligned with LLVM APIs Found some problems with the coverage map encoding when testing with more than one counter per function. While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming. This should be easier to follow and easier to maintain.

view details

Guillaume Gomez

commit sha 1d2e3fff69b654c3dfd6a810e193db29bb1868fa

Clean up E0730 explanation

view details

Ximin Luo

commit sha 1f25a4b3ae87327f045fbfec82b5af4c8da6ecd6

config.toml.example: Update remap-debuginfo doc to be more general & accurate

view details

Guillaume Gomez

commit sha f22a34e84d4dba9b17bb3e68051ee82bd85f3c94

Clean up E0734 explanation

view details

Joseph Ryan

commit sha c692ed468c8dc4b9f549ef839b4b490e3b84d19c

Move `Error` and `RenderInfo` out of `html` module

view details

Joseph Ryan

commit sha 5bc97946ca35a789b690668bb6b27ca41bfeb5b2

Refactor html backend to use generic interface

view details

Joseph Ryan

commit sha 6a4396b98c6fcb405429a9798a9ab6554f015b7e

Extract `Cache` and other types from `html` module

view details

Joseph Ryan

commit sha a7909522547cb35b32a4f11b78b2b54864189295

Pull out more types from html

view details

Joseph Ryan

commit sha 65bf5d5248635152262344770591c367ba6a9890

TODO -> FIXME

view details

Joseph Ryan

commit sha 3d707a008e0822471de4adad047b5cefd281f3ac

Make requested changes

view details

Nathaniel McCallum

commit sha 25670749b44a9c7a4cfd3fbf780bbe3344a9a6c5

Suppress debuginfo on naked function arguments A function that has no prologue cannot be reasonably expected to support debuginfo. In fact, the existing code (before this patch) would generate invalid instructions that caused crashes. We can solve this easily by just not emitting the debuginfo in this case. Fixes https://github.com/rust-lang/rust/issues/42779 cc https://github.com/rust-lang/rust/issues/32408

view details

Joseph Ryan

commit sha cee8023c690158daf4f6c3d8bf2d32297fdfed0c

More requested changes

view details

Tomasz Miąsko

commit sha 821d50aa0cc73c1ec2fb09bab8a69e1c3ca93f23

Make closures and generators a must use types Warn about unused expressions with closure or generator type. This follows existing precedence of must use annotations present on `FnOnce`, `FnMut`, `Fn` traits, which already indirectly apply to closures in some cases, e.g.,: ```rust fn f() -> impl FnOnce() { || {} } fn main() { // an existing warning: unused implementer of `std::ops::FnOnce` that must be used: f(); // a new warning: unused closure that must be used: || {}; } ```

view details

Who? Me?!

commit sha 62fd2c81e36f0efadf4c5fc8e5576bcdfb66ac18

Update outdated readme

view details

Joshua Nelson

commit sha d34a1b0c1b4b22cc61b5956c07d89517bf278af8

Don't duplicate builder code - Add Builder::new_internal

view details

Joshua Nelson

commit sha 0192fa4786db80d2c9888af98e7ceec47d327887

Make the default stage dependent on the subcommand ### x.py build/test: stage 1 I've seen very few people who actually use full stage 2 builds on purpose. These compile rustc and libstd twice and don't give you much more information than a stage 1 build (except in rare cases like https://github.com/rust-lang/rust/pull/68692#discussion_r376392145). For new contributors, this makes the build process even more daunting than it already is. As long as CI is changed to use `--stage 2` I see no downside here. ### x.py bench/dist/install: stage 2 These commands have to do with a finished, optimized version of rustc. It seems very rare to want to use these with a stage 1 build. ### x.py doc: stage 0 Normally when you document things you're just fixing a typo. In this case there is no need to build the whole rust compiler, since the documentation will usually be the same when generated with the beta compiler or with stage 1. Note that for this release cycle only there will be a significant different between stage0 and stage1 docs: https://github.com/rust-lang/rust/pull/73101. However most of the time this will not be the case.

view details

push time in 2 months

PR opened rust-lang/rust

[beta] Make ClashingExternDeclarations Allow by default.

As per https://github.com/rust-lang/rust/pull/73990#issuecomment-666457338, this PR changes clashing_extern_declarations to allow-by-default to sidestep current false positives & negatives on the beta branch.

Note that the changes to fix the issue properly have been merged to master (see #73990), but those changes will have to arrive on the next release train.

+1 -1

0 comment

1 changed file

pr created time in 2 months

create barnchjumbatm/rust

branch : allow-clashing-extern-decl

created branch time in 2 months

pull request commentrust-lang/rust

Fix incorrect clashing_extern_declarations warnings.

I've just done another rebase -- @nagisa, are you available to review and approve? I'd like to get this merged soon so that these fixes can be backported to beta, and so I can try a crater check run with this lint as deny-by-default.

jumbatm

comment created time in 2 months

push eventjumbatm/rust

Guillaume Gomez

commit sha 633d1a5af96db7eccb8aeeb07ff31b06aaf07b5f

Clean up E0720 explanation

view details

Dan Aloni

commit sha 28e27566782e5f2636b9c93a172c19024630233d

librustc_typeck: use diag item instead of string compare

view details

Dan Aloni

commit sha d077767ee72221f2a436692ef85115381671a765

Update src/librustc_typeck/check/op.rs Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

Bastian Kauschke

commit sha 49b1971263971db49e821f81bb54991b7de5ab43

add const generics

view details

Rich Kadel

commit sha 12ddd6073abecb7a515a43bee37408596e322345

Fixed coverage map issues; better aligned with LLVM APIs Found some problems with the coverage map encoding when testing with more than one counter per function. While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming. This should be easier to follow and easier to maintain.

view details

Ximin Luo

commit sha 1f25a4b3ae87327f045fbfec82b5af4c8da6ecd6

config.toml.example: Update remap-debuginfo doc to be more general & accurate

view details

Joseph Ryan

commit sha c692ed468c8dc4b9f549ef839b4b490e3b84d19c

Move `Error` and `RenderInfo` out of `html` module

view details

Joseph Ryan

commit sha 5bc97946ca35a789b690668bb6b27ca41bfeb5b2

Refactor html backend to use generic interface

view details

Joseph Ryan

commit sha 6a4396b98c6fcb405429a9798a9ab6554f015b7e

Extract `Cache` and other types from `html` module

view details

Joseph Ryan

commit sha a7909522547cb35b32a4f11b78b2b54864189295

Pull out more types from html

view details

Joseph Ryan

commit sha 65bf5d5248635152262344770591c367ba6a9890

TODO -> FIXME

view details

Joseph Ryan

commit sha 3d707a008e0822471de4adad047b5cefd281f3ac

Make requested changes

view details

Joseph Ryan

commit sha cee8023c690158daf4f6c3d8bf2d32297fdfed0c

More requested changes

view details

Tomasz Miąsko

commit sha 821d50aa0cc73c1ec2fb09bab8a69e1c3ca93f23

Make closures and generators a must use types Warn about unused expressions with closure or generator type. This follows existing precedence of must use annotations present on `FnOnce`, `FnMut`, `Fn` traits, which already indirectly apply to closures in some cases, e.g.,: ```rust fn f() -> impl FnOnce() { || {} } fn main() { // an existing warning: unused implementer of `std::ops::FnOnce` that must be used: f(); // a new warning: unused closure that must be used: || {}; } ```

view details

Who? Me?!

commit sha 62fd2c81e36f0efadf4c5fc8e5576bcdfb66ac18

Update outdated readme

view details

Joshua Nelson

commit sha d34a1b0c1b4b22cc61b5956c07d89517bf278af8

Don't duplicate builder code - Add Builder::new_internal

view details

Joshua Nelson

commit sha 0192fa4786db80d2c9888af98e7ceec47d327887

Make the default stage dependent on the subcommand ### x.py build/test: stage 1 I've seen very few people who actually use full stage 2 builds on purpose. These compile rustc and libstd twice and don't give you much more information than a stage 1 build (except in rare cases like https://github.com/rust-lang/rust/pull/68692#discussion_r376392145). For new contributors, this makes the build process even more daunting than it already is. As long as CI is changed to use `--stage 2` I see no downside here. ### x.py bench/dist/install: stage 2 These commands have to do with a finished, optimized version of rustc. It seems very rare to want to use these with a stage 1 build. ### x.py doc: stage 0 Normally when you document things you're just fixing a typo. In this case there is no need to build the whole rust compiler, since the documentation will usually be the same when generated with the beta compiler or with stage 1. Note that for this release cycle only there will be a significant different between stage0 and stage1 docs: https://github.com/rust-lang/rust/pull/73101. However most of the time this will not be the case.

view details

Joshua Nelson

commit sha f7dcfcd45bd019acf8c914c204ccae519c420adc

Don't build rustc without std - Set rustc to build only when explicitly asked for This allows building the stage2 rustc artifacts, which nothing depends on. Previously the behavior was as follows (where stageN <-> stage(N-1) artifacts, except for stage0 libstd): - `x.py build --stage 0`: - stage0 libstd - stage1 rustc (but without putting rustc in stage0/) This leaves you without any rustc at all except for the beta compiler (https://github.com/rust-lang/rust/issues/73519). This is never what you want. - `x.py build --stage 1`: - stage0 libstd - stage1 rustc - stage1 libstd - stage1 rustdoc - stage2 rustc This leaves you with a broken stage2 rustc which doesn't even have libcore and is effectively useless. Additionally, it compiles rustc twice, which is not normally what you want. - `x.py build --stage 2`: - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 rustdoc and tools This builds all tools in release mode. This is the correct usage for CI, but takes far to long for development. Now the behavior is as follows: - `x.py build --stage 0`: - stage0 libstd This is suitable for contributors only working on the standard library, as it means rustc never has to be compiled. - `x.py build --stage 1`: - stage0 libstd - stage1 rustc - stage1 libstd - stage1 rustdoc This is suitable for contributors working on the compiler. It ensures that you have a working rustc and libstd without having to pass `src/libstd` in addition. - `x.py build --stage 2`: - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 libstd - stage2 rustdoc This is suitable for debugging errors which only appear with the stage2 compiler. - `x.py build --stage 2 src/libstd src/rustc` - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 libstd - stage2 rustdoc, tools, etc. - stage2 rustc artifacts ('stage3') This is suitable for CI, which wants all tools in release mode. However, most of the use cases for this should use `x.py dist` instead, which builds all the tools without each having to be named individually.

view details

Joshua Nelson

commit sha 01c6256178fb126d668045f3a1297e0f3491e985

Change debuginfo to default to 1 if `debug = true` is set From [a conversation in discord](https://discordapp.com/channels/442252698964721669/443151243398086667/719200989269327882): > Linking seems to consume all available RAM, leading to the OS to swap memory to disk and slowing down everything in the process Compiling itself doesn't seem to take up as much RAM, and I'm only looking to check whether a minimal testcase can be compiled by rustc, where the runtime performance isn't much of an issue > do you have debug = true or debuginfo-level = 2 in config.toml? > if so I think that results in over 2GB of debuginfo nowadays and is likely the culprit > which might mean we're giving out bad advice :( Anecdotally, this sped up my stage 1 build from 15 to 10 minutes. This still adds line numbers, it only removes variable and type information. - Improve wording for debuginfo description Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>

view details

Joshua Nelson

commit sha 74b373426a79af2b21b8d266a881753e338cfd2e

Fix most bootstrap tests Uses --stage 2 for all the existing tests

view details

push time in 2 months

push eventjumbatm/rust

Caio

commit sha 187aea7c34adf06b0db39f688d60d3fdac8e7e3e

Impl Default for ranges

view details

flip1995

commit sha f7acea2683c6124854bfe20e7127e4dfba344d3e

Register redundant_field_names and non_expressive_names as early passes

view details

flip1995

commit sha 485229c4a3d6a2fbe40f5a6976a33144a27497c6

Fix fallout in redundant_field_names

view details

flip1995

commit sha efd3dcff97f67f376e354c047133ce9044c52991

Fix fallout in similar_names

view details

Eduardo Broto

commit sha bb37a0f948b02e6434dbe3ea615960052d37f784

Avoid triggering similar names on code from expansion

view details

Alexis Bourget

commit sha 2853448426ce76926baa7e6e6173c15228e4951a

Document the ref keyword

view details

Alexis Bourget

commit sha 249e07b237bd3049eb7fd94afe450b7c09b6a3d9

Short documentation for the false keyword

view details

Stefan Lankes

commit sha 6813c1c69baf870a479c70e23ad0550d1d9aa9be

revise RwLock, which is derived from the wasm implementation - increasing the readability of `Condvar` - simplify the interface to the libos HermitCore

view details

Stefan Lankes

commit sha 3acc3ef10d2099a4b3118e8c705b36f4bbaf6f64

minor changes to pass the format check

view details

Stefan Lankes

commit sha beb1b1fa5b1047c7caf8a1d499725df3c1ad8cad

reorder crates to pass the format check

view details

Alexis Bourget

commit sha ba6857d801b6217a190e92e43cacd8468ff2d72a

Document the trait keyword

view details

Stefan Lankes

commit sha f9c609164251abc136eb9bda55c92cb99adb5c86

remove some compiler warnings

view details

Trevor Spiteri

commit sha 6dfe144bdd4413ac55cbb2ad2edfb1daa0c4bf15

stabilize const_nonzero_int_methods

view details

Trevor Spiteri

commit sha 9739b512a892628534e730ffcd9756b3218c8de8

stabilize some const_checked_int_methods

view details

Trevor Spiteri

commit sha c1c674c2dbfe3f6dc47d11368c1b5ee4ab008799

stabilize const_saturating_int_methods

view details

Trevor Spiteri

commit sha 056d925167318636fcf975c8ffb81efebdc9bca3

stabilize const_int_sign

view details

Trevor Spiteri

commit sha 2a84e313df095fd0e81b9348b68bd9b1d1caa551

stabilize const_ascii_ctype_on_intrinsics

view details

Adam Perry

commit sha d275739c09f266479d6db388cbf55ba6ca791b9d

Derive common traits for panic::Location. Add documentation about the host/target behavior of Location::file.

view details

Jamie Cunliffe

commit sha fc52b47e8013da325fc0a0f5d3897143243ba206

va_args implementation for AAPCS. Implement the va args in codegen for AAPCS, this will be used as the default va_args implementation for AArch64 rather than the va_args llvm-ir as it currently is. Copyright (c) 2020, Arm Limited.

view details

Alexis Bourget

commit sha 837a761b398a6ff6a97f7f61e390dae9efbeab79

Document the where keyword

view details

push time in 2 months

create barnchjumbatm/rust

branch : session-diagnostic

created branch time in 2 months

delete branch jumbatm/rust

delete branch : as-error

delete time in 2 months

issue commentrust-lang/rust

Make diagnostics emitting independent of the happy code path

I'm still actively working on this. Sorry I've been taking so long -- I'll hurry up and get a PR in soon.

@rustbot claim

oli-obk

comment created time in 2 months

push eventjumbatm/rust

Mohsen Zohrevandi

commit sha c4b02659c16d2ad0ac36d2c8602edd002e559f7a

Enable some timeouts in SGX platform This would partially resolve https://github.com/fortanix/rust-sgx/issues/31

view details

Mohsen Zohrevandi

commit sha d7dc64bdfea4fbf8974774800ab51e04eaa4f082

Handle spurious wakeups in wait_timeout_sgx

view details

Mohsen Zohrevandi

commit sha c5d1fcd2309b6903fed82aba6e0fdc2fa85bc874

Allow more ui tests for SGX

view details

Mohsen Zohrevandi

commit sha 3442d23c1a12f1f01a0e07b6bec72b58998f49ef

Improve wait_timeout_sgx, simplify usercalls::wait

view details

Alex Crichton

commit sha fde8d11ca12e83fe2b07a536956f4a2725b24485

Don't pollute docs/suggestions with libstd deps Currently dependency crates of the standard library can sometimes leak into error messages such as when traits to import are suggested. Additionally they can leak into documentation such as in the list of "all traits implemented by `u32`". The dependencies of the standard library, however, are intended to be private. The dependencies of the standard library can't actually be stabl-y imported nor is the documentation that relevant since you can't import them on stable either. This commit updates both the compiler and rustdoc to ignore unstable traits in these two scenarios. Specifically the suggestion for traits to import ignore unstable traits, and similarly the list of traits implemented by a type excludes unstable traits. This commit is extracted from #73441 where the addition of some new dependencies to the standard library was showed to leak into various error messages and documentation. The intention here is to go ahead and land these changes ahead of that since it will likely take some time to land.

view details

Guillaume Gomez

commit sha 99c15133638c42253592a9bbe705ff215c9dd563

Small cleanup for E0705 explanation

view details

Guillaume Gomez

commit sha 13a6aeff77064820de0c412ea8bd914ba2696fe1

Clean up E0715 explanation

view details

joacar01

commit sha 582071c1ebd5ec19ded8648223e9108b5ce65d85

Ignoring test case: [codegen] repr-transparent-aggregates-1.rs for aarch64 Copyright (c) 2020, Arm Limited.

view details

Benoît du Garreau

commit sha e7d9944e205dc59f1174b584cd8ed41deced9646

Add feature const_option

view details

Mohsen Zohrevandi

commit sha c457b67af394c37826f75d73cca10319ee96b910

Remove unnecessary check in SGX wait usercall

view details

Guillaume Gomez

commit sha 818aaa7b588ffcb27b0987a38794e61c2050324b

Clean up E0716 explanation

view details

Guillaume Gomez

commit sha 69d5fc1a9f89c80dd9e16a43dff58f320b373630

Clean up E0710 explanation

view details

Eric Huss

commit sha 9b6b400084fe617e2549d539963294a9ea178c46

Remove some `ignore-stage1` annotations.

view details

Andy Russell

commit sha 95bf7b7dacca320d0965e3f9052ecbb9c4fc59bd

add regression test for #61216 Fixes #61216.

view details

Nicholas Nethercote

commit sha 6582240d1296516ea02882c8bb092688d2f43f20

Remove `Compiler::compile()`. It's unused.

view details

Yuki Okushi

commit sha 85072e330394440776ace5ae612e3ced32ef6348

Update reference to CONTRIBUTING.md

view details

Guillaume Gomez

commit sha b0884c098bc3704f7ec9381ac1670eb923845127

Move #[doc(alias)] check in rustc

view details

Dylan MacKenzie

commit sha efe634f14c20661216c57322b319c1cac1f9704f

Add `reachable` and friends to `mir::traversal` module

view details

Joshua M. Clulow

commit sha 8368a35f834dc56519683ba3d98576ec3e905eb4

build dist for x86_64-unknown-illumos This change creates a new Docker image, "dist-x86_64-illumos", and sets things up to build the full set of "dist" packages for illumos hosts, so that illumos users can use "rustup" to install packages. It also adjusts the manifest builder to expect complete toolchains for this platform.

view details

Eric Huss

commit sha 24abe1646e24caca79cd649f71cd4806a488ee7d

Disable 44056 test with debug on macos.

view details

push time in 2 months

create barnchjumbatm/jumbatm

branch : master

created branch time in 2 months

created repositoryjumbatm/jumbatm

created time in 2 months

push eventjumbatm/rust

Teddy_Wang

commit sha 40ee620e51c86c72e3c2b65df71f5f0a4a79797f

Added a lint for .map(|x| x)

view details

CAD97

commit sha 7779a11448927e208ed6eb9bb609dd23595f77ce

Use step_unchecked more liberally

view details

flip1995

commit sha 80bcbf521c7ff95e38a7567432b5519cc18e5b2a

Merge commit 'c2c07fa9d095931eb5684a42942a7b573a0c5238' into clippyup

view details

Teddy_Wang

commit sha fb4f9a0ad7a4656beb01c85b02b3e6ef15d914ec

Fix pattern match of ExprKind::MethodCall

view details

bors

commit sha 583d64493484f72425ecac55eaf5eddbba10b132

Auto merge of #5694 - wangtheo:issue-5626, r=matthiaskrgr #5626: lint iterator.map(|x| x) changelog: adds a new lint for iterator.map(|x| x) (see https://github.com/rust-lang/rust-clippy/issues/5626) The code also lints for result.map(|x| x) and option.map(|x| x). Also, I'm not sure if I'm checking for type adjustments correctly and I can't think of an example where .map(|x| x) would apply type adjustments.

view details

Ayaz Hafiz

commit sha 7c1b3aa0ddb81954a804455ca45fcf09fdb17dd8

Record span of `const` kw in GenericParamKind Context: this is needed to fix https://github.com/rust-lang/rustfmt/issues/4263, which currently records the span of a const generic param incorrectly because the location of the `const` kw is not known. I am not sure how to add tests for this; any guidance in how to do so would be appreciated :slightly_smiling_face:

view details

Eduardo Broto

commit sha 5987c7d4041ce5d72c8412d2ad73fe3b63308b51

cmp_owned: avoid FP when PartialEq is not implemented symmetrically

view details

Eduardo Broto

commit sha b498e1d71537a79e7aff5378da625aca8b4eef96

cmp_owned: reverse operands if necessary

view details

Tim Nielens

commit sha 6bf5434e19ce6d2a501589d1fcbc0d1748c531a6

copy_on_clone - add machine applicability

view details

bors

commit sha a14eab389f6e9f8bdaffbba184b20220041b036f

Auto merge of #5745 - montrivo:copy_on_clone, r=phansch clone_on_copy - add machine applicability Fix #4826. Change the applicability of the lint clone_on_copy. Split a test file and run rustfix on the clone_on_copy part. changelog: clone_on_copy - add machine applicability

view details

bors

commit sha 46d33043d5de0403a2a3dab9e7817041999bf9dd

Auto merge of #5701 - ebroto:4874_cmp_owned_fp, r=flip1995 cmp_owned: handle when PartialEq is not implemented symmetrically changelog: Handle asymmetrical implementations of PartialEq in [`cmp_owned`]. Fixes #4874

view details

Guillaume Gomez

commit sha 3e48aaea03aef6e6e7ac678d11995a2a39ba9d99

Clean up E0704 error explanation

view details

Carol (Nichols || Goulding)

commit sha fa0f1d3e5353df04e3d2e68e65810ca1a231c220

Change a noun to a verb to make the sentence complete

view details

bors

commit sha 88fec89c16312de60ca7ab6d660b1ae8917b35f8

Auto merge of #5748 - carols10cents:tiny-docs-fix, r=flip1995 Change a noun to a verb to make the sentence complete changelog: Fixed some grammar in the documentation for `await_holding_lock`. Just a tiny little thing I found while using clippy <3

view details

Eduard-Mihai Burtescu

commit sha f5ce0e5fe960d09db01cf912c475cd1a52131120

rustc_lint: only query `typeck_tables_of` when a lint needs it.

view details

Manish Goregaokar

commit sha a671ea4d3f9d416d9520d2ea902cb9f48eb35898

Rollup merge of #73597 - ayazhafiz:i/const-span, r=ecstatic-morse Record span of `const` kw in GenericParamKind Context: this is needed for a fix of https://github.com/rust-lang/rustfmt/issues/4263, which currently records the span of a const generic param incorrectly because the location of the `const` kw is not known. I am not sure how to add tests for this; any guidance in how to do so would be appreciated :slightly_smiling_face:

view details

bors

commit sha 81810fa8f400b1d941b8bf14b2d085cf0a045ae1

Auto merge of #73756 - Manishearth:rollup-aehswb2, r=Manishearth Rollup of 13 pull requests Successful merges: - #72620 (Omit DW_AT_linkage_name when it is the same as DW_AT_name) - #72967 (Don't move cursor in search box when using arrows to navigate results) - #73102 (proc_macro: Stop flattening groups with dummy spans) - #73297 (Support configurable deny-warnings for all in-tree crates.) - #73507 (Cleanup MinGW LLVM linkage workaround) - #73588 (Fix handling of reserved registers for ARM inline asm) - #73597 (Record span of `const` kw in GenericParamKind) - #73629 (Make AssocOp Copy) - #73681 (Update Chalk to 0.14) - #73707 (Fix links in `SliceIndex` documentation) - #73719 (emitter: column width defaults to 140) - #73729 (disable collectionbenches for android) - #73748 (Add code block to code in documentation of `List::rebase_onto`) Failed merges: r? @ghost

view details

Guillaume Gomez

commit sha 98a3b07213d695668081126a880fe7ac5dd9cd4e

Add missing Stdin and StdinLock exampels

view details

Dylan MacKenzie

commit sha 3c5ee3300f6c88f3d984d62ce704d17b7432f29c

Update tests

view details

Dario Gonzalez

commit sha 9448ed4c1f8b586c9c90a78c12afc4c826041d5a

Obviate #[allow(improper_ctypes_definitions)] Modifies the return type for `fn entry` so that allowing improper_ctypes_definitions is no longer necessary. This change is derived from a similar pattern in `libstd/sys/sgx/abi/usercalls/raw.rs` with `UsercallReturn`.

view details

push time in 2 months

pull request commentrust-lang/rust

Fix incorrect clashing_extern_declarations warnings.

Note that I've also added a few additional commits; they fix an assertion failure and false negative I noticed while working on this.

jumbatm

comment created time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 470d759a7e734ab6f1e1db7f88f0fb22f49b6eaf

Fix missed same-sized member clash in ClashingExternDeclarations.

view details

push time in 2 months

create barnchjumbatm/rust

branch : clashing-extern-decl-same-sized-field

created branch time in 2 months

push eventjumbatm/rust

jumbatm

commit sha 91829105986895ea69ac8970edbc1fa5233d100b

Handle structs with zst members.

view details

push time in 2 months

pull request commentrust-lang/rust

Fix incorrect clashing_extern_declarations warnings.

The changes have been applied. This is good to go.

jumbatm

comment created time in 2 months

push eventjumbatm/rust

Yoshua Wuyts

commit sha a31f103fd27bde3f83b9dd54af8e41d64e5001f4

Add core::future::{poll_fn, PollFn}

view details

Alexis Bourget

commit sha 049f6eaa792fbbf2b727fc278ddd23d1e11d57bd

Fixing broken link for the Eq trait

view details

MaulingMonkey

commit sha f8eb81ba4e85b02d90cfc33fcba0a6a7d5cbf810

Modify type names on MSVC to make tuples .natvis compatible. - Mangles (T0, T1) as tuple<T0, T1>, possibly unblocking rust-lang/rust#70052 "Update hashbrown to 0.8.0" - Prettifies Rust tuples similar to VS2017's std::tuple - Improves debuginfo test coverage

view details

MaulingMonkey

commit sha 24a728a8eb4832568509eb757c2374934a76cb98

debuginfo: Define int/float types in terms of MSVC-recognized types. PDB debug information doesn't appear to be emitted for basic types. By defining u32 as a typedef for unsigned __int32 when targeting MSVC, we allow CDB and other debuggers to recognize "u32" as a type/expression. This in turn unblocks rust-lang#70052 "Update hashbrown to 0.8.0" by allowing $T1 ..= $T3 to resolve, which would otherwise fail to resolve when builtin types fail to parse.

view details

Oliver Scherer

commit sha 7e682d3f6f5761471e05fefc21e5de6ce4a52444

Stabilize casts and coercions to `&[T]` in const fn

view details

Dodo

commit sha a065096ff40f7910fd58aa36a76be6cb1c5f1d4d

stabilize const mem::forget

view details

Vadim Petrochenkov

commit sha 8e256b19d529ebf9021030e17791e23a1212ff1e

parser: Break float tokens into parts in tuple field positions

view details

David Tolnay

commit sha 40a21707b4c0e7e5a8cb5a03ddebecdd59ab705c

Add test of tuple nested indexing

view details

David Tolnay

commit sha 0432f63acf5b08c23ad206a87e3ad4a2a171cf7f

Test even deeper nested indexing

view details

David Tolnay

commit sha 776deb6b9f326f5ba5984e4d55cb5010a17ce559

Test a range, which is not nested indexing

view details

David Tolnay

commit sha 6dfa549fb5719034b829955384e1e198f4d66c04

Add tests in which the token really is a float

view details

David Tolnay

commit sha 3814eec087c6e5695c92956b7a738f4c2ffd7649

Add test for tuple indexed with float in macro input

view details

David Tolnay

commit sha 63f95a4858bbe8cef9a6e1b0e7e5273255d60926

Add test for errors triggered on parts of decomposed index

view details

Vadim Petrochenkov

commit sha 64a88db762bc13b37508d44e09731a3b8349110a

Update dtolnay's tests that now work

view details

Vadim Petrochenkov

commit sha 52bdaaa0edb2824af1610b67664f06580335fd78

Add some requested tests

view details

Ralf Jung

commit sha fb9fa5ba3ee08171e7d2ff35d28ec0dd93b0287b

adjust ub-enum test to be endianess-independent

view details

Tomasz Miąsko

commit sha bcef848a6971217d4b8df50c17e047174018d316

Explain effects of debugging options from config.toml Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>

view details

Thom Chiovoloni

commit sha 980d8e1a0b18e89129cce23bb5a46c6a498dc5d2

Optimize is_ascii for &str and &[u8]

view details

Thom Chiovoloni

commit sha 63e2e2e32674ebe662b927c139931ffd8a352313

Avoid `vec!` allocation in `is_ascii_slice_*` benches

view details

Eduard-Mihai Burtescu

commit sha f25811e34bf89c3dde760d826ad4662c245be202

Replace early-bound normalization hack with per-query key/value type aliases.

view details

push time in 2 months

push eventjumbatm/rust

Alexis Bourget

commit sha 6e8251742071d56545b6ce160ed71bb60597ee01

Documenting the separate behaviors of edition 2015 and 2018

view details

Alexis Bourget

commit sha 59701360dc0c76bfa45204d307ac5055f8bff538

Fix some small mistakes

view details

Ralf Jung

commit sha 54d95ed25aa45f94b2a3d0a0e3a3323852878ecd

catch InvalidUninitBytes during validation

view details

Ralf Jung

commit sha c3fc4f0420b642a0e0041bb13492df2d4a68ae80

catch errors more locally around read_discriminant

view details

Ralf Jung

commit sha 751b594cc843a28c660a662db1a822a759af9603

const validation: add test for uninit bool

view details

Ralf Jung

commit sha 319c7f77dedf671b01194adb257dbe662c73df32

fmt

view details

Andy Russell

commit sha 792f2dedd7d910d35f91f32aa222b05d91cb0c65

libstd: remove some mutable statics in sys::unix

view details

bors

commit sha 51eeabf505804fb3f2621626f5c39973640c514c

Auto merge of #73562 - poliorcetics:e0432-to-edition2018, r=GuillaumeGomez Update E0432 long description with the separate behaviors of editions 2015 and 2018 Fixes #64668. I restarted from the work done in #71413.

view details

Eric Huss

commit sha 561d5acb9e6a968be8532a50611e9aa41e25a001

Fix occasional bootstrap panic in docs.

view details

bors

commit sha e1beee4992ad4b235fc700bf7af1ee86f894ea53

Auto merge of #74059 - RalfJung:miri-uninit-validation, r=oli-obk Miri value validation: fix handling of uninit memory Fixes https://github.com/rust-lang/miri/issues/1456 Fixes https://github.com/rust-lang/miri/issues/1467 r? @oli-obk

view details

bors

commit sha 8ac1525e091d3db28e67adcbbd6db1e1deaa37fb

Auto merge of #74006 - euclio:sys-unix-static-mut, r=oli-obk libstd: remove some mutable statics in sys::unix My understanding is that this achieves the same behavior and performance with safe code.

view details

bors

commit sha 1d919c9377f4602d991ca1c7ba852e7555943740

Auto merge of #74124 - ehuss:fix-doc-dry-run-up-to-date, r=Mark-Simulacrum Fix occasional bootstrap panic in docs. I am occasionally running into this panic when running `x.py`: > thread 'main' panicked at 'source "/Users/eric/Proj/rust/rust/build/x86_64-apple-darwin/md-doc/unstable-book" failed to get metadata: No such file or directory (os error 2)', src/build_helper/lib.rs:173:19 I have not been able to figure out the exact sequence of commands that leads to this error (I tried for quite a while to reproduce it). I think it may involve updating my tree, but I am uncertain. An artificial way to trigger it is to build the documentation, and then delete the `md-doc` directory manually. The cause is that bootstrap does a "dry run" before every command, and in this case `up_to_date` panics because the destination exists (`build/x86_64-apple-darwin/doc/unstable-book/index.html `) but the source does not (`build/x86_64-apple-darwin/md-doc/unstable-book`). I am uncertain if it is important that the last line `builder.run(…)` needs to be called during the dry run. This patch seems to fix the issue, though.

view details

jumbatm

commit sha 84a9ed7ad4ca24d50a58b125cec07063a2b99934

Add additional clashing_extern_decl cases.

view details

jumbatm

commit sha a19ab02fe5e6b790e41618985ae7159e3cfe81c8

Don't emit clashing decl lint for FFI-safe enums. An example of an FFI-safe enum conversion is when converting Option<NonZeroUsize> to usize. Because the Some value must be non-zero, rustc can use 0 to represent the None variant, making this conversion is safe. Furthermore, it can be relied on (and removing this optimisation already would be a breaking change).

view details

jumbatm

commit sha 690062f716bfbbf396afad7c9b5e0d7a32bacfa8

Apply suggested wording changes from code review. Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com>

view details

jumbatm

commit sha c9ccc99337157f8c582817e3efeefbe88803f334

Address code review comments. - Make `is_repr_nullable_ptr` freestanding again to avoid usage of ImproperCTypesVisitor in ClashingExternDeclarations (and don't accidentally revert the ParamEnv::reveal_all() fix from a week earlier) - Revise match condition for 1 Adt, 1 primitive - Generalise check for non-null type so that it would also work for ranges which exclude any single value (all bits set, for example) - Make is_repr_nullable_ptr return the representable type instead of just a boolean, to avoid adding an additional, independent "source of truth" about the FFI-compatibility of Option-like enums. Also, rename to `repr_nullable_ptr`.

view details

push time in 3 months

startedmun-lang/mun

started time in 3 months

pull request commentrust-lang/rust

Fix incorrect clashing_extern_declarations warnings.

Alright, this good for re-review -- I have repr_nullable_ptr returning the corresponding FFI-safe type as I mentioned earlier.

jumbatm

comment created time in 3 months

push eventjumbatm/rust

jumbatm

commit sha f84b951e2c90d99579227cb8cf2ad255dda82a29

Address code review comments. - Make `is_repr_nullable_ptr` freestanding again to avoid usage of ImproperCTypesVisitor in ClashingExternDeclarations (and don't accidentally revert the ParamEnv::reveal_all() fix from a week earlier) - Revise match condition for 1 Adt, 1 primitive - Generalise check for non-null type so that it would also work for ranges which exclude any single value (all bits set, for example) - Make is_repr_nullable_ptr return the representable type instead of just a boolean, to avoid adding an additional, independent "source of truth" about the FFI-compatibility of Option-like enums. Also, rename to `repr_nullable_ptr`.

view details

push time in 3 months

more