profile
viewpoint

rust-lang/nomicon 380

The Dark Arts of Advanced and Unsafe Rust Programming

rust-lang/reference 257

The Rust Reference

matthewjasper/book 0

The Rust Programming Language

matthewjasper/cargo 0

The Rust package manager

matthewjasper/compiler-explorer 0

Run compilers interactively from your web browser and interact with the assembly

matthewjasper/intellij-rust 0

Rust plugin for the IntelliJ Platform: https://intellij-rust.github.io/

matthewjasper/miri 0

An interpreter for Rust's mid-level intermediate representation

matthewjasper/nomicon 0

The Dark Arts of Advanced and Unsafe Rust Programming

matthewjasper/reference 0

The Rust Reference

matthewjasper/rust 0

A safe, concurrent, practical language.

Pull request review commentrust-lang/rust

Consider methods on fundamental `impl` when method is not found on numeric type

 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {                     let mut candidates = all_traits(self.tcx).into_iter().filter_map(|info| {                         self.associated_item(info.def_id, item_name, Namespace::ValueNS)                     });-                    if let (true, false, SelfSource::MethodCall(expr), Some(_)) = (+                    // There are methods that are defined on the fundamental types and won't be
                    // There are methods that are defined on the primitive types and won't be

I was initially confused thinking that this was about #[fundamental]

estebank

comment created time in 10 hours

pull request commentrust-lang/rust

Normalize MIR locals' types for generator layout computation.

@bors r+

oli-obk

comment created time in 10 hours

pull request commentrust-lang/rust

Replace "rc"/"arc" lang items with Rc/Arc diagnostic items.

@bors r+

eddyb

comment created time in 21 hours

pull request commentrust-lang/rust

Have the per-query caches store the results on arenas

This appears to be a slight perf regression.

cjgillot

comment created time in 5 days

Pull request review commentrust-lang/rust

typeck/type_of: let wfcheck handle generics in opaque types' substs.

 fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {                 for (i, arg) in substs.iter().enumerate() {                     let arg_is_param = match arg.unpack() {                         GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),-                        GenericArgKind::Lifetime(lt) => !matches!(lt, ty::ReStatic),+                        GenericArgKind::Lifetime(lt) => {+                            matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))+                        }

I don't think that we currently ever go from a placeholder back to a bound region/type.

eddyb

comment created time in 5 days

pull request commentrust-lang/rust

Have the per-query caches store the results on arenas

@bors try @rust-timer queue

cjgillot

comment created time in 6 days

PR opened rust-lang/rust

Unerase regions in infer_placeholder_type

closes #70608

+19 -4

0 comment

3 changed files

pr created time in 7 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha a12ebd3027e9c2b63f3d94c122c9d95d2d3ac739

unerase regions in `infer_placeholder_type`

view details

push time in 7 days

create barnchmatthewjasper/rust

branch : infer-const-type-regions

created branch time in 8 days

issue commentrust-lang/rust

regression: assertion failed: data.is_empty()

I think that this is fixed by #69591

Mark-Simulacrum

comment created time in 12 days

pull request commentrust-lang/rust

Fix warning for unused variables in or pattern (issue #67691)

multipart_suggestion is correct. You;ll have to remove run-rustfix from the test and leave a FIXME.

sapir

comment created time in 13 days

pull request commentrust-lang/rust

Remove `ReClosureBound`

@bors r=nikomatsakis

matthewjasper

comment created time in 18 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha c3b98813c42ae0a0da402f1a933ad7c24b1c1c43

Remove `ReClosureBound`

view details

push time in 18 days

pull request commentrust-lang/rust

Make `needs_drop` less pessimistic on generators

@bors r+

jonas-schievink

comment created time in 18 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha 68df0181ee6dd8f8c950864b26287bca7f36b5de

Remove `ReClosureBound`

view details

push time in 18 days

PR opened rust-lang/rust

Remove `ReClosureBound`

We now substitute external names for regions in the query response.

r? @nikomatsakis

+47 -123

0 comment

20 changed files

pr created time in 19 days

delete branch matthewjasper/rust

delete branch : erase-more

delete time in 19 days

Pull request review commentrust-lang/rust

Use hygiene for AST passes

 impl<'a> MutVisitor for TestHarnessGenerator<'a> {     }      fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {-        let ident = i.ident;-        if ident.name != kw::Invalid {-            self.cx.path.push(ident);-        }-        debug!("current path: {}", path_name_i(&self.cx.path));-         let mut item = i.into_inner();         if is_test_case(&item) {             debug!("this is a test item");              let test = Test {                 span: item.span,-                path: self.cx.path.clone(),+                ident: item.ident,             };-            self.cx.test_cases.push(test);-            self.tests.push(item.ident);+            self.tests.push(test);         }          // We don't want to recurse into anything other than mods, since         // mods or tests inside of functions will break things

I think that it should work for modules inside expressions of we visited them. Is a bit more work for tests that are directly in blocks.

matthewjasper

comment created time in 20 days

issue commentrust-lang/rust

Unnecessary 'cannot bind by-move with sub-bindings' with `bindings_after_at`

This is the same as

fn foo(x: NonCopyStruct) {
    let y = x;
    let NonCopyStruct { copy_field: z } = x;
}
comex

comment created time in 20 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha 2aa1a9490ae1e27c6471179242aca00dd95e6a0b

Remove `ReClosureBound`

view details

push time in 21 days

create barnchmatthewjasper/rust

branch : remove-closurebound

created branch time in 21 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha 0f0f254a9c90c4fe47897554948f82e44033f37a

Use erased regions in MIR

view details

push time in 21 days

Pull request review commentrust-lang/rust

Remove the erase regions MIR transform

 fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {                 let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() {                     let va_list_did =                         tcx.require_lang_item(lang_items::VaListTypeLangItem, Some(arg.span));-                    let region = tcx.mk_region(ty::ReScope(region::Scope {-                        id: body.value.hir_id.local_id,-                        data: region::ScopeData::CallSite,-                    }));

I'm working on it.

matthewjasper

comment created time in 21 days

PR opened rust-lang/rust

Remove the erase regions MIR transform

We now ensure that MIR never contains unerased regions in the first place.

+64 -110

0 comment

11 changed files

pr created time in 21 days

pull request commentrust-lang/rust

Prefetch some queries used by the metadata encoder

@bors r+

Zoxc

comment created time in 22 days

Pull request review commentrust-lang/rust

Erase regions in writeback

 error[E0512]: cannot transmute between types of different sizes, or dependently- LL |     transmute(x)    |     ^^^^^^^^^    |-   = note: source type: `<C as TypeConstructor<'a>>::T` (size can vary because of <C as TypeConstructor>::T)-   = note: target type: `<C as TypeConstructor<'b>>::T` (size can vary because of <C as TypeConstructor>::T)+   = note: `<C as TypeConstructor>::T` does not have a fixed size

We don't allow transmutes between type projections at all it seems:

pub trait TypeConstructor {
    type T;
}

unsafe fn transmute_lifetime<C>(x: C::T)
where C: TypeConstructor {
    transmute::<C::T, C::T>(x); // ERROR !
}
matthewjasper

comment created time in 22 days

push eventmatthewjasper/rust

Matthew Jasper

commit sha 5ba7e72b3a3163951dfdd480da72f50d0b4ea601

Use erased regions in MIR

view details

push time in 22 days

create barnchmatthewjasper/rust

branch : erase-more

created branch time in 22 days

delete branch matthewjasper/rust

delete branch : erase-the-world

delete time in 22 days

delete branch matthewjasper/rust

delete branch : metahygiene

delete time in 23 days

delete branch matthewjasper/rust

delete branch : fix-region-flags

delete time in 23 days

pull request commentrust-lang/rust

Update hashbrown to 0.7.1

min_specialization is in the next nightly. I would prefer either min_specialization to be used if possible or a sepatate feature flag if not.

Amanieu

comment created time in 24 days

pull request commentrust-lang/rust

Erase regions in writeback

@bors r=nikomatsakis

matthewjasper

comment created time in 24 days

delete branch matthewjasper/rust

delete branch : min-spec

delete time in 24 days

push eventmatthewjasper/rust

Kornel

commit sha 8de1ec9ce0a53b8ad9987e923e833c82fda05603

Make error message clearer about creating new module

view details

Vadim Petrochenkov

commit sha eafeb9a2676e16ed322e9e0695b5ce9407f5de8d

expand/builtin_macros: Minor cleanup

view details

David Tolnay

commit sha 3ba89e87503e25aece0318a9851f8dba5ccd94a2

Remove quotes around unknown fn placeholder in backtrace

view details

David Tolnay

commit sha db75b6a91f67008ec789d9934f8a73e09fd0d472

Add quotes around filename in Backtrace debug

view details

David Tolnay

commit sha 1f1ca877b7002e3ac45916df5415fde1584775ab

Change disabled and unsupported backtraces to print using placeholder style

view details

David Tolnay

commit sha a9cc010c4883bafba1304f6fd581343f5b1b3ba2

Make it possible to instantiate hardcoded Backtrace from test

view details

David Tolnay

commit sha 33600e4d2d7a61f7dcb1b278bb1ccb8f04690db3

Add test of Debug representation of Backtrace

view details

David Tolnay

commit sha a2364dc85fb505487c272988b8c5073a3f6fef2a

Write backtrace fmt test using relative paths For some reason the absolute paths were formatted differently on the armhf-gnu target. thread '<unnamed>' panicked at 'assertion failed: `(left == right)` left: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"./rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"./rust/rt.rs\", line: 400 },\n]"`, right: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"/rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"/rust/rt.rs\", line: 400 },\n]"`', src/libstd/backtrace.rs:486:5

view details

Ayush Kumar Mishra

commit sha 7b75c346d56e07634effc56acebac8c0698773b1

Add long error explanation for E0628 #61137

view details

Vadim Petrochenkov

commit sha 552a8875bd5520c2e8c01ab05a12c304c730c5b9

expand: Implement support for retrying macro expansions

view details

Vadim Petrochenkov

commit sha 2e6528961c44a4f3841fd319af71f1d1a6af029c

builtin_macros: Add attribute macro `#[cfg_accessible(path)]`

view details

Oliver Scherer

commit sha 02dbb35b2b6ed869f14a8aecaf9dad5c72d5cb0b

Deduplicate and clean up pretty printing logic

view details

Oliver Scherer

commit sha 02f4eeb7cb78f1cf7bcfe18db3b700b02576ca55

Address review comments around `type_ascribed_value`

view details

Oliver Scherer

commit sha 3b82edd279e2055a65135a2469b3ad539c5665e3

Print braces only in print_ty mode

view details

Oliver Scherer

commit sha 4ddb4bdaad8c0359e18ffcfe769020d0b20b1937

Eliminate all ParamEnv::empty uses in pretty printing

view details

Oliver Scherer

commit sha e22ddfd80d840f310d00fc756ab298caa181a326

Don't print leading zeros on hex dumps constants

view details

Oliver Scherer

commit sha b837e7173236b27ba76660864cd160aacbe66c57

Reduce special casing in the const pretty printer

view details

Oliver Scherer

commit sha b2e93a41a653ea96954ae3780ea7d4c0368ed9c3

Print leading zeros for non pointers

view details

Oliver Scherer

commit sha 1191eb45859041b467d4e0bd8accca3e164b1dad

Prefer fall through to code repetition

view details

Oliver Scherer

commit sha 154f3f19ab10723ef3afd7b6166384356df631dc

Don't print all zsts as their type as it makes no sense for more complex examples (e.g. structs)

view details

push time in 24 days

pull request commentrust-lang/rust

Make macro metavars respect (non-)hygiene

@bors r=petrochenkov

matthewjasper

comment created time in 24 days

push eventmatthewjasper/rust

Kornel

commit sha 8de1ec9ce0a53b8ad9987e923e833c82fda05603

Make error message clearer about creating new module

view details

Dan Aloni

commit sha 0605abe3bb7b602cbe70a72797fdd6ca90d76e92

Use GetSystemTimePreciseAsFileTime if it is available

view details

David Tolnay

commit sha 3ba89e87503e25aece0318a9851f8dba5ccd94a2

Remove quotes around unknown fn placeholder in backtrace

view details

David Tolnay

commit sha db75b6a91f67008ec789d9934f8a73e09fd0d472

Add quotes around filename in Backtrace debug

view details

David Tolnay

commit sha 1f1ca877b7002e3ac45916df5415fde1584775ab

Change disabled and unsupported backtraces to print using placeholder style

view details

David Tolnay

commit sha a9cc010c4883bafba1304f6fd581343f5b1b3ba2

Make it possible to instantiate hardcoded Backtrace from test

view details

David Tolnay

commit sha 33600e4d2d7a61f7dcb1b278bb1ccb8f04690db3

Add test of Debug representation of Backtrace

view details

David Tolnay

commit sha a2364dc85fb505487c272988b8c5073a3f6fef2a

Write backtrace fmt test using relative paths For some reason the absolute paths were formatted differently on the armhf-gnu target. thread '<unnamed>' panicked at 'assertion failed: `(left == right)` left: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"./rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"./rust/rt.rs\", line: 400 },\n]"`, right: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"/rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"/rust/rt.rs\", line: 400 },\n]"`', src/libstd/backtrace.rs:486:5

view details

Ayush Kumar Mishra

commit sha 7b75c346d56e07634effc56acebac8c0698773b1

Add long error explanation for E0628 #61137

view details

Oliver Middleton

commit sha 965888adc20f46799f382065142dbb0e27905d9c

Add Node.js to PR CI image This should allow the `rustdoc-js` and `rustdoc-js-std` test suites to run automatically on PRs.

view details

Ayush Mishra

commit sha 1305ae6813d66a5c2898f67224d20d00604f37a7

Update src/librustc_error_codes/error_codes/E0628.md Co-Authored-By: Dylan DPC <dylan.dpc@gmail.com>

view details

Ayush Mishra

commit sha f7fcb589cf88bdd10f8573554de065142f9e5e70

Update src/librustc_error_codes/error_codes/E0628.md Co-Authored-By: Dylan DPC <dylan.dpc@gmail.com>

view details

Ayush Kumar Mishra

commit sha 00c6abe92fdde4d2385413b656ad34e883c54fbc

Minor change

view details

Ayush Kumar Mishra

commit sha c33c88bcbd5d9d41262f23d637fcad1ec3ab7c53

Minor change

view details

Oliver Middleton

commit sha 3f58ab6e24af34265229f701d48eb240cc06d751

Allow `rustdoc-js` and `rustdoc-js-std` to use none default build dir location

view details

Kornel

commit sha a5a786d00c1490aaca066df88f8fe2b1cfd8ac75

Block version-specific docs from search engines Stable, beta and nightly URLs remain

view details

Ayush Kumar Mishra

commit sha 4bd6ebcc31bc68925742d2cb21095b5c76e7976c

Add long error explanation for E0634 #61137

view details

Amanieu d'Antras

commit sha 864d05bc8a366daaa52807b37bb1ad86127bc23a

Add a workaround for catch_unwind in stage1 mingw target Fixes #70001

view details

John Kåre Alsaker

commit sha cfa1d4e383d050e79868b9a6f8e1c57f1ab7dd13

Add HIR queries

view details

John Kåre Alsaker

commit sha 21386e1355a1aa5b8709d969d7fef878b4602491

Collect the new maps

view details

push time in 25 days

pull request commentrust-lang/rust

Make macro metavars respect (non-)hygiene

@bors r=petrochenkov

matthewjasper

comment created time in 25 days

push eventmatthewjasper/rust

Nicholas Nethercote

commit sha 54d1c50c7e7b4c4c7dca6c85c6965c886922b449

Remove `sip::Hasher::short_write`. `sip::Hasher::short_write` is currently unused. It is called by `sip::Hasher::write_{u8,usize}`, but those methods are also unused, because `DefaultHasher`, `SipHasher` and `SipHasher13` don't implement any of the `write_xyz` methods, so all their write operations end up calling `sip::Hasher::write`. (I confirmed this by inserting a `panic!` in `sip::Hasher::short_write` and running the tests -- they all passed.) The alternative would be to add all the missing `write_xyz` methods. This does give some significant speed-ups, but it hurts compile times a little in some cases. See #69152 for details. This commit does the conservative thing and doesn't change existing behaviour.

view details

Tomasz Miąsko

commit sha e1a54725081227a3866669c167bee4c0559f5362

Emit 1-based column numbers in debuginfo The debuginfo column numbers are 1-based. The value 0 indicates that no column has been specified. Translate 0-based column numbers to 1-based when emitting debug information.

view details

Tomasz Miąsko

commit sha 0c51f2f5a580a7e239accd0cc5f3da2e8cdf6f8c

Use byte offsets when emitting debuginfo columns

view details

Tomasz Miąsko

commit sha 8e93a01824a2239f1c588c7c0b884c8a2662e929

Test that column information is not emitted for MSVC targets

view details

Ryan Lopopolo

commit sha 2a29726fcd09fac350e0a8c0d1dd78a8ae6de0ed

Implement From<&mut str> for String

view details

Andreas Molzer

commit sha 51b93966240acffdbe3fbb898bb647a03b146e09

Add unborrow to reset RefCell borrow state This method is complementary for the feature refcell_leak added in an earlier PR. It allows reverting the effects of leaking a borrow guard by statically proving that such a guard could not longer exist. This was not added to the existing `get_mut` out of concern of impacting the complexity of the otherwise pure pointer cast and because the name `get_mut` poorly communicates the intent of resetting remaining borrows.

view details

Dan Aloni

commit sha 0605abe3bb7b602cbe70a72797fdd6ca90d76e92

Use GetSystemTimePreciseAsFileTime if it is available

view details

Ryan Lopopolo

commit sha 18feaa3fa25f11e403478b562fa1db356b32c818

Add stable feature name

view details

Ryan Lopopolo

commit sha 533784d3a247595393ce24c9940945838913a0fe

Add docs for From::<&mut str>::from String impl

view details

Vadim Petrochenkov

commit sha e809e0214ea9a43cc798379da4e8b303ed1000c3

ast: `Mac`/`Macro` -> `MacCall`

view details

Mark Mansi

commit sha c8b527ed99ce06c3506ee0bb65aae3026e6b1dde

change method -> associated function

view details

Mark Mansi

commit sha b6518f0f66d2b24f0e65ca51f952457fd74a909a

update tests

view details

Oliver Middleton

commit sha 965888adc20f46799f382065142dbb0e27905d9c

Add Node.js to PR CI image This should allow the `rustdoc-js` and `rustdoc-js-std` test suites to run automatically on PRs.

view details

Mark Mansi

commit sha 4b46271841d75ee8b45b7b4db2ce531a764785fa

Remove a couple of Rc's from RegionInferenceContext

view details

Mark Mansi

commit sha 508d4a24d1f4ba79bfa01fd6af919609ebeaccbe

Remove another Rc from RegionInferenceContext

view details

Mark Mansi

commit sha da4e33a9e659071ae5e7418242dea38d951a260d

move frozen to rustc_data_structures

view details

Mark Mansi

commit sha a58b17f2b5e57baa45ffb5b8c979faa3191bc05a

update rustdocs for frozen

view details

KRAAI, MATTHEW [VISUS]

commit sha 40ffcc2911ef0a1d32395481338d60ad9d81afaa

Add self to .mailmap

view details

Vadim Petrochenkov

commit sha 01a0c6d441a8630fe179420525e42920ab69d976

rustc_metadata: Remove `rmeta::MacroDef` Use `ast::MacroDef` instead. Also remove `Session::imported_macro_spans`, external macros have spans now.

view details

Oliver Middleton

commit sha 3f58ab6e24af34265229f701d48eb240cc06d751

Allow `rustdoc-js` and `rustdoc-js-std` to use none default build dir location

view details

push time in 25 days

push eventmatthewjasper/rust

Sebastian Imlay

commit sha 35c4aae99ece980c7c594940724f0728fcccf226

Added tvOS as a backend

view details

Markus Westerlind

commit sha 851a701f90081fbc83fa151e9f272cea2a990779

Reuse a Vec in mir simplification

view details

Markus Westerlind

commit sha dec8166abc6675627819723b10301e395f3876d5

Use Vec::append

view details

Markus Westerlind

commit sha 33513fad8089956adcbb5b9803f56de1a8e94b57

Avoid an intermediate Vec in mir simplify

view details

Markus Westerlind

commit sha 2440998666cb9fe5f35c1de9ef44849b71870fc3

perf(mir): Reserve enough space for the merged blocks before appending

view details

Sebastian Imlay

commit sha a2661695e8953199a746895e2e65225a9922753b

Merge branch 'master' of github.com:rust-lang/rust into add-tvSO-target

view details

Sebastian Imlay

commit sha 6b17330ef4f9a97bd539b55edb4e7ccdb6c00133

Merged apple_tvos_base and apple_ios_base into apple_sdk_base.

view details

Markus Westerlind

commit sha 84c024d92f34206d0f02ab814c6e5bd3abb876c3

Clarify mir block merging

view details

Sebastian Imlay

commit sha 259977158e19acccc1bbc71c8cc4449ad40a8bef

fmt

view details

LeSeulArtichaut

commit sha 79b8ad84c84481a43704213cd0948d2ba0ea63b4

Implement `Copy` for `IoSlice`

view details

Nicholas Nethercote

commit sha 54d1c50c7e7b4c4c7dca6c85c6965c886922b449

Remove `sip::Hasher::short_write`. `sip::Hasher::short_write` is currently unused. It is called by `sip::Hasher::write_{u8,usize}`, but those methods are also unused, because `DefaultHasher`, `SipHasher` and `SipHasher13` don't implement any of the `write_xyz` methods, so all their write operations end up calling `sip::Hasher::write`. (I confirmed this by inserting a `panic!` in `sip::Hasher::short_write` and running the tests -- they all passed.) The alternative would be to add all the missing `write_xyz` methods. This does give some significant speed-ups, but it hurts compile times a little in some cases. See #69152 for details. This commit does the conservative thing and doesn't change existing behaviour.

view details

Tomasz Miąsko

commit sha e1a54725081227a3866669c167bee4c0559f5362

Emit 1-based column numbers in debuginfo The debuginfo column numbers are 1-based. The value 0 indicates that no column has been specified. Translate 0-based column numbers to 1-based when emitting debug information.

view details

Tomasz Miąsko

commit sha 0c51f2f5a580a7e239accd0cc5f3da2e8cdf6f8c

Use byte offsets when emitting debuginfo columns

view details

Tomasz Miąsko

commit sha 8e93a01824a2239f1c588c7c0b884c8a2662e929

Test that column information is not emitted for MSVC targets

view details

Mark Rousskov

commit sha d45ce5aed63fb58385705016dfaff1832a58d7c8

Inline catching panics into std::catch_unwind This allows LLVM to inline the happy path, such that catching unwinding is zero-cost when no panic occurs. This also allows us to match the code generated by C++ try/catch.

view details

Mark Rousskov

commit sha 1920f817caf65e5ffb95628b15cedb8aa54a8ae8

Avoid over-aligning the return value in the -Cpanic=abort case

view details

Amanieu d'Antras

commit sha 919c5fe6b9e052eb243e0e7ceb99d2e6986b4115

Test catch_unwind vanishing We execpt the try intrinsic to be a direct call if in -Cpanic=abort mode, and that catch_unwind optimizes out if calling a function that does not unwind.

view details

Mark Rousskov

commit sha dd6c3b7c3900f58f5b97a6cec379328e855287ed

Ignore PAL lint for std::panicking

view details

Mark Rousskov

commit sha bdcc02360f34fe773c38f8ae86111fb831f8ec9e

Mark cleanup cold

view details

Amanieu d'Antras

commit sha 5b682354f2c8bf2c825b6229a6a125435f2053dd

Fix some minor issues

view details

push time in 25 days

pull request commentrust-lang/rust

Erase regions in writeback

@bors r=nikomatsakis

matthewjasper

comment created time in a month

pull request commentrust-lang/rust

Implement a feature for a sound specialization subset

@bors r=nikomatsakis

matthewjasper

comment created time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha ebb61f7e4694221e3c7742009990886dde691fe0

Update tests for erasing regions in typeck

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 220bffc44264625f9a40af8b99a9cff9d4120ec2

Update tests for erasing regions in typeck

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 39ee66ab82fc38a13d046ac1caa1eb55edfa8901

Consider well-formed predicates in min-specialization

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 32d330df30c079c8d0bcdeff9049152a65c36b31

Avoid ICEs when we emit errors constructing the specialization graph

view details

Matthew Jasper

commit sha 0bbbe719e831c585e0e7bdd33b2432ac5ecb1b31

Implement soundness check for min_specialization

view details

Matthew Jasper

commit sha 4377ac3e2f58f923062e6e945f06a9a93fcc70df

Use min_specialization in libstd and libproc_macro

view details

Matthew Jasper

commit sha 5760af97e58fe9af30bececd1699485ed02d506c

Consider well-formed predicates in min-specialization

view details

push time in a month

push eventmatthewjasper/rust

Sebastian Imlay

commit sha 35c4aae99ece980c7c594940724f0728fcccf226

Added tvOS as a backend

view details

Linus Färnstrand

commit sha 271ba5a3ea59f25ebc7ba3b9a2e620a833e50b33

Stabilize assoc_int_consts

view details

Linus Färnstrand

commit sha 35298349c3efd75cd8050f9f23e4bf1409d96118

Add "soft deprecation" notice to old min/max_value() docs

view details

Linus Färnstrand

commit sha 97bdd31b0eab51d0a51b8746123f910cd868dff3

Add "soft deprecation" notice to old MIN/MAX docs

view details

Linus Färnstrand

commit sha fd71fbe8d51dc291f87fdb6beb12e174a304bd0c

Remove reference from integer docs to their modules

view details

Linus Färnstrand

commit sha cf255c6dc1a9c41bf8e98865d85f8577ce8d2056

Use new preferred consts in int docs

view details

Linus Färnstrand

commit sha 5e17f31d94a0e2f1e69d5c4bd5171cf48ff9e5b0

Replace min/max_value() with MIN/MAX in integer docs

view details

Linus Färnstrand

commit sha 847a0dd845dbc74b4d49adf873c585519e356b4e

Remove uint_macros that was identical to int_macros

view details

Linus Färnstrand

commit sha c67de2570f881a0601f15c7c15e1fb9a26f2d3bf

Add notice about using new consts in new code on float modules

view details

Linus Färnstrand

commit sha 086927480be716a14f9c68954d417b544066184b

Add notice about using new consts in new code on int modules

view details

Linus Färnstrand

commit sha 83191c2da6da6c13466f7f30568cdea02c761ca0

Update float documentation to use associated consts

view details

Linus Färnstrand

commit sha b2dc6187699d99436f6183218d928be09d439578

Add usage recommendation to old float constants

view details

spunit262

commit sha 30d4f1b78d997fb555388cb8ebea474ffb85794c

Don't give invalid suggestion on desugared span.

view details

Markus Westerlind

commit sha 851a701f90081fbc83fa151e9f272cea2a990779

Reuse a Vec in mir simplification

view details

Markus Westerlind

commit sha dec8166abc6675627819723b10301e395f3876d5

Use Vec::append

view details

Markus Westerlind

commit sha 33513fad8089956adcbb5b9803f56de1a8e94b57

Avoid an intermediate Vec in mir simplify

view details

Markus Westerlind

commit sha 2440998666cb9fe5f35c1de9ef44849b71870fc3

perf(mir): Reserve enough space for the merged blocks before appending

view details

Sebastian Imlay

commit sha a2661695e8953199a746895e2e65225a9922753b

Merge branch 'master' of github.com:rust-lang/rust into add-tvSO-target

view details

Sebastian Imlay

commit sha 6b17330ef4f9a97bd539b55edb4e7ccdb6c00133

Merged apple_tvos_base and apple_ios_base into apple_sdk_base.

view details

David Ross

commit sha 940f65782cc5df7fecad27b38cc25b6d1eeaf2e8

Parse & reject postfix operators after casts This adds parsing for expressions like 'x as Ty[0]' which will immediately error out, but still give the rest of the parser a valid parse tree to continue.

view details

push time in a month

push eventmatthewjasper/rust

Sebastian Imlay

commit sha 35c4aae99ece980c7c594940724f0728fcccf226

Added tvOS as a backend

view details

Markus Westerlind

commit sha 851a701f90081fbc83fa151e9f272cea2a990779

Reuse a Vec in mir simplification

view details

Markus Westerlind

commit sha dec8166abc6675627819723b10301e395f3876d5

Use Vec::append

view details

Markus Westerlind

commit sha 33513fad8089956adcbb5b9803f56de1a8e94b57

Avoid an intermediate Vec in mir simplify

view details

Markus Westerlind

commit sha 2440998666cb9fe5f35c1de9ef44849b71870fc3

perf(mir): Reserve enough space for the merged blocks before appending

view details

Sebastian Imlay

commit sha a2661695e8953199a746895e2e65225a9922753b

Merge branch 'master' of github.com:rust-lang/rust into add-tvSO-target

view details

Sebastian Imlay

commit sha 6b17330ef4f9a97bd539b55edb4e7ccdb6c00133

Merged apple_tvos_base and apple_ios_base into apple_sdk_base.

view details

Markus Westerlind

commit sha 84c024d92f34206d0f02ab814c6e5bd3abb876c3

Clarify mir block merging

view details

Sebastian Imlay

commit sha 259977158e19acccc1bbc71c8cc4449ad40a8bef

fmt

view details

Trevor Spiteri

commit sha d15a98b87815850ef9dd11564e896b6f19b724c3

Stabilize const for integer {to,from}_{be,le,ne}_bytes methods All of these functions can be implemented simply and naturally as const functions, e.g. u32::from_le_bytes can be implemented as (bytes[0] as u32) | (bytes[1] as u32) << 8 | (bytes[2] as u32) << 16 | (bytes[3] as u32) << 24 So stabilizing the constness will not expose that internally they are implemented using transmute which is not const in stable.

view details

LeSeulArtichaut

commit sha 79b8ad84c84481a43704213cd0948d2ba0ea63b4

Implement `Copy` for `IoSlice`

view details

Trevor Spiteri

commit sha 87f0dc63a864c6d9a3c34aa4052762dbcd316c91

use unions instead of transmute and add const safety comments

view details

Guillaume Gomez

commit sha 1244ced9580b942926afc06815e0691cf3f4a846

Remove "important traits" feature

view details

Guillaume Gomez

commit sha 13c6d5819aae3c0de6a90e7f17ea967bf4487cbb

Remove spotlight usage

view details

Ralf Jung

commit sha 503026b622d1095770178fbe606a4ba783216992

mem::zeroed/uninit: panic on types that do not permit zero-initialization

view details

Ralf Jung

commit sha 6fd909b2b1dd2789e0f1af79283c6105fa502ca3

reference tracking issue

view details

Ralf Jung

commit sha d78c4aa62ec0382d85e88b44cce2c087c5357f53

use valid_range_exclusive for correct overflow handling

view details

Ralf Jung

commit sha df6a3a0ed216a8548130f9b431964531a1bc7633

test some more things that should not panic

view details

Ralf Jung

commit sha b133d6776fde22e944eb7f266ee165ffcf7cdb09

make it even more conservative, and note some FIXMEs

view details

Ralf Jung

commit sha 6e66f586a0da51fbd4cafa2e1da914cf07c65503

fmt

view details

push time in a month

pull request commentrust-lang/rust

resolve/hygiene: `macro_rules` are not "legacy"

@bors r=eddyb,matthewjasper

petrochenkov

comment created time in a month

pull request commentrust-lang/rust

Remove a few `Rc`s from RegionInferenceCtxt

@bors r+

mark-i-m

comment created time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors r+

cjgillot

comment created time in a month

pull request commentrust-lang/rust

Change "method" to "associated function"

@bors r+ cc @rust-lang/wg-diagnostics

mark-i-m

comment created time in a month

Pull request review commentrust-lang/rust

Evaluate repeat expression lengths as late as possible

 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {             }              Rvalue::Repeat(operand, len) => {-                if *len > 1 {+                if len.try_eval_usize(tcx, self.param_env).map_or(false, |len| len > 1) {

Yes, we should check that the element type is Copy unless we know that the length is 0 or 1.

oli-obk

comment created time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors retry

cjgillot

comment created time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors retry

cjgillot

comment created time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors r+

cjgillot

comment created time in a month

pull request commentrust-lang/rust

Erase regions in writeback

@bors r=nikomatsakis

matthewjasper

comment created time in a month

pull request commentrust-lang/rust

Make macro metavars respect (non-)hygiene

@bors r=petrochenkov

matthewjasper

comment created time in a month

PR opened rust-lang/rust

Ensure HAS_FREE_LOCAL_NAMES is set for ReFree beta-nominated

This fixes a bug introduced by #69469. I don't have any ideas on how to reate a regression test for this.

+29 -26

0 comment

2 changed files

pr created time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha f4eb6ed6b407bcbbd7311a2983ff661b2cd15393

Ensure HAS_FREE_LOCAL_NAMES is set for ReFree

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 54f72021269cf1cbf251ce5f7fca351521eed34b

Erase regions in writeback Also skip duplicated region solving entirely with `-Zborrowck=mir`.

view details

Matthew Jasper

commit sha f8a08a965cbd3d4bcdeafbb53697a198a57bf9f5

Update tests for erasing regions in typeck

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 2f145f618bd5c4ca1c1bdf3979553f5877930dab

Make macro metavars respect (non-)hygiene

view details

push time in a month

pull request commentrust-lang/rust

Increase verbosity when suggesting subtle code changes

@bors r+

estebank

comment created time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors r+

cjgillot

comment created time in a month

pull request commentrust-lang/rust

Rename DefKind::Method and TraitItemKind::Method

toolstate week is over @bors r+

mark-i-m

comment created time in a month

create barnchmatthewjasper/rust

branch : fix-region-flags

created branch time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors r+

cjgillot

comment created time in a month

push eventmatthewjasper/rust

David Ross

commit sha 0cf204930a2ecaa5f7416602fca6054d4fd44b6b

Keep better fix suggestion if type ascription is likely unintended

view details

David Ross

commit sha f82ca8b0efa64bc33ed811b34c83a21aeb2950d1

Add more error cases to issue 35813 tests

view details

David Ross

commit sha 5dd646435ba882574e677acf58113880a6570949

Fix related type ascription tests.

view details

David Ross

commit sha e3eefe266756449ebe3b2c1bb177f0130569b3b2

Remove extra debug print in unreachable!

view details

David Ross

commit sha c2d7ffb8a9906f5c7b6a1cf6a739cf4d7d732c2b

Remove trailing whitespace

view details

bors

commit sha 8040bc983669fcc3fe358dfc9772ea2ecde0ae1b

Auto merge of #69156 - ecstatic-morse:unified-dataflow-impls2, r=eddyb Use `ResultsCursor` for `elaborate_drops` Some cleanup after #68241. The old code was using a custom cursor-like struct called `InitializationData`.

view details

David Ross

commit sha 8ef3da0858c5a76fd1756b9efcf82eeb9491fb64

Fix test stderr after rebasing on master.

view details

Camille GILLOT

commit sha d5691209b6d5fe5e47560b1db7b822dbeb0880fd

Move librustc/{traits,infer} to librustc_infer.

view details

Camille GILLOT

commit sha 187a9741d3cd63dd78571e2a0e08344aef05f51b

Make librustc compile.

view details

Camille GILLOT

commit sha f07e8891458259bb4373bb6aa59d158304f637b1

Make librustc_infer compile.

view details

Camille GILLOT

commit sha 4b57cb3cbed8674aa480bff450affa62ac6b75bf

Make librustc_typeck compile.

view details

Hiroki Noda

commit sha 67068f35dd41409c8e79710f1335cc9dc64f1860

macOS: avoid calling pthread_self() twice

view details

Camille GILLOT

commit sha 1637aab15e175b5e0dc14947ffa946804420d414

Make librustc_mir compile.

view details

Camille GILLOT

commit sha 2519f4a0a336993fc2e494a194807c56060256b3

Make librustc_traits compile.

view details

Camille GILLOT

commit sha bee6a5ac1274201e7da2081a5aff6b3b1f407185

Other crates.

view details

Camille GILLOT

commit sha 795673ae2060198cdb09c6ded8d303c244dac6fd

Remove librustc_infer crate re-exports.

view details

Camille GILLOT

commit sha 0b93cfc1ee3d61987e9f3229370d79acd51544a1

Prune features.

view details

Camille GILLOT

commit sha 5d5720835329230c60cb7b4f56e2a9b234dae6cf

Gate macro use.

view details

Camille GILLOT

commit sha e88500b5e18bbbad2323944d3c23f8a4465eb147

Prune rustc dependencies.

view details

Jonas Schievink

commit sha bb482ebf2870bae6e1b69822f1c7d7d9d4b33103

suspend -> yield

view details

push time in a month

pull request commentrust-lang/rust

expand: Implement something similar to `#[cfg(accessible(path))]`

@bors r+

petrochenkov

comment created time in a month

Pull request review commentrust-lang/rust

expand: Implement something similar to `#[cfg(accessible(path))]`

+//! Implementation of the `#[cfg_accessible(path)]` attribute macro.++use rustc_ast::ast;+use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};+use rustc_feature::AttributeTemplate;+use rustc_parse::validate_attr;+use rustc_span::symbol::sym;+use rustc_span::Span;++crate struct Expander;++fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {+    match mi.meta_item_list() {+        None => {}+        Some([]) => ecx.span_err(mi.span, "`cfg_accessible` path is not specified"),+        Some([_, .., l]) => ecx.span_err(l.span(), "multiple `cfg_accessible` paths are specified"),+        Some([nmi]) => match nmi.meta_item() {+            None => ecx.span_err(nmi.span(), "`cfg_accessible` path cannot be a literal"),+            Some(mi) => {+                if !mi.is_word() {

This method could do with a better name

petrochenkov

comment created time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 39824fe63732e499076f92c161b949099f13a71c

Make macro metavars respect (non-)hygiene

view details

push time in a month

delete branch matthewjasper/rust

delete branch : query-response-relate

delete time in a month

pull request commentrust-lang/rust

Split librustc::{traits,infer} to their respective crates

@bors r+ rollup=never (size)

cjgillot

comment created time in a month

pull request commentrust-lang/rust

VariantSizeDifferences: bail on SizeOverflow

@bors r- failed in #69909

Centril

comment created time in a month

pull request commentrust-lang/rust

fix #62456

@bors r+ rollup

contrun

comment created time in a month

push eventmatthewjasper/rust

Daniel Henry-Mantilla

commit sha 60274a95fef57a18113f7c48be68be31ece860eb

Added From<Vec<NonZeroU8>> for CString Updated tracking issue number Added safeguards for transmute_vec potentially being factored out elsewhere Clarified comment about avoiding mem::forget Removed unneeded unstable guard Added back a stability annotation for CI Minor documentation improvements Thanks to @Centril's code review Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com> Improved layout checks, type annotations and removed unaccurate comment Removed unnecessary check on array layout Adapt the stability annotation to the new 1.41 milestone Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com> Simplify the implementation. Use `Vec::into_raw_parts` instead of a manual implementation of `Vec::transmute`. If `Vec::into_raw_parts` uses `NonNull` instead, then the code here will need to be adjusted to take it into account (issue #65816) Reduce the whitespace of safety comments

view details

Mark Rousskov

commit sha 178de46116b4fc8c1d9b30007f5e5ed24c809881

Add primitive module to libcore/std This re-exports the primitive types from libcore at `core::primitive` to allow macro authors to have a reliable location to use them from.

view details

Dylan MacKenzie

commit sha b23d910d570b392b1740ef1bb888f04194fe82c1

Skip `Drop` terminators for enum variants without drop glue When doing drop elaboration for an `enum` that may or may not be moved out of (an open drop), we check the discriminant of the `enum` to see whether the live variant has any drop flags and then check the drop flags to see whether we need to drop each field. Sometimes, however, the live variant has no move paths. In this case, we still emit a drop terminator for the entire enum after checking the enum discriminant. This commit skips emitting the drop terminator when the "otherwise" variants, those without move paths, have no drop glue. This was frequently the case with `Option`, as the `None` variant has no drop glue and no move path.

view details

Michael Bradshaw

commit sha 348278a7fd5fd459f555dd763e71e12c23c1661a

Stabilize Once::is_completed

view details

Stein Somers

commit sha b685985ea40ab1faa8cb888bf001779e44a8c716

Refine and extend benchmarks of mutable BTreeSet methods

view details

Dylan MacKenzie

commit sha c981d67b509f1ba16c97683ad6dc430429899e49

[!] Use `rustc_inherit_overflow_checks` in `next_power_of_two` I believe the previous code was calling `ops::Add::add` instead of the `+` operator to get this behavior.

view details

Dylan MacKenzie

commit sha 2afa99379d9623e50efd290e609447bdc5059af8

Use bespoke macro instead of `?` inside const fns

view details

Dylan MacKenzie

commit sha 269bf89865536964546242589bb186a8a7e3c566

Make integer power methods const

view details

Dylan MacKenzie

commit sha 7fe5eaf7d8cb23ceb71d8e509be13d20ef836114

Test integer exponentiation in a const context

view details

Dylan MacKenzie

commit sha f6d4720f26c92e9905c98b4ee2db832927e30a8a

Make `u8::is_ascii` a stable `const fn` `char::is_ascii` is already a stable `const fn`, so there is no reason for `u8::is_ascii` to be unstable.

view details

Dylan MacKenzie

commit sha bf732a11ecc319e0c0a840196bde1b5daccbdc85

Test `u8::is_ascii` alongside `char::is_ascii`

view details

Erin Power

commit sha 81e40278bd0ad707a3be2396a076f151d1ff1072

Update RELEASES.md for 1.42.0

view details

XAMPPRocky

commit sha 26fdcbbc2810474770bb7f87d410a1e34b142b87

Update RELEASES.md

view details

Pyry Kontio

commit sha 86bf96291d8222dbec9e07461404ecb189be0a98

Implement split_inclusive for slice and str, an splitting iterator that includes the matched part in the iterated substrings as a terminator.

view details

Pyry Kontio

commit sha 5c9dc57cb587761561e85574c821a6f9c0c7cc67

Don't return empty slice on last iteration with matched terminator. Test reverse iteration.

view details

XAMPPRocky

commit sha 7ab01b24674b88ff4927b0eb445a582fb9e12aba

Update RELEASES.md Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>

view details

XAMPPRocky

commit sha 32daa2aa38fafd731ddc27374dece22f38069bc8

Update RELEASES.md

view details

Esteban Küber

commit sha 683ebc2dec0a5b88eb3eaf146e6855ea299d17b8

On mismatched argument count point at arguments

view details

LeSeulArtichaut

commit sha abcbf7c09d50421fb790d023740108016e4114de

Document stable versions of `f32` and `f64` intrinsics Fix links

view details

LeSeulArtichaut

commit sha 216f100dfcd00891ea1f6684df77fc87711453ed

Document stable versions of `type_name` and `type_id`

view details

push time in a month

Pull request review commentrust-lang/rust

Implement a feature for a sound specialization subset

+//! # Minimal Specialization+//!+//! This module contains the checks for sound specialization used when the+//! `min_specialization` feature is enabled. This requires that the impl is+//! *always applicable*.+//!+//! If `impl1` specializes `impl2` then `impl1` is always applicable if we know+//! that all the bounds of `impl2` are satisfied, and all of the bounds of+//! `impl1` are satisfied for some choice of lifetimes then we know that+//! `impl1` applies for any choice of lifetimes.+//!+//! ## Basic approach+//!+//! To enforce this requirement on specializations we take the following+//! approach:+//!+//! 1. Match up the substs for `impl2` so that the implemented trait and+//!    self-type match those for `impl1`.+//! 2. Check for any direct use of `'static` in the substs of `impl2`.+//! 3. Check that all of the generic parameters of `impl1` occur at most once+//!    in the *unconstrained* substs for `impl2`. A parameter is constrained if+//!    its value is completely determined by an associated type projection+//!    predicate.+//! 4. Check that all predicates on `impl1` also exist on `impl2` (after+//!    matching substs).+//!+//! ## Example+//!+//! Suppose we have the following always applicable impl:+//!+//! ```rust+//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }+//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }+//! ```+//!+//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is+//! constrained to be `<I as Iterator>::Item`, so we check only+//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The+//! predicates of `impl1` are only `T: Sized`, which is also a predicate of+//! `impl2`. So this specialization is sound.+//!+//! ## Extensions+//!+//! Unfortunately not all specializations in the standard library are allowed+//! by this. So there are two extensions to these rules that allow specializing+//! on some traits.+//!+//! ### rustc_specialization_trait+//!+//! If a trait is always applicable, then it's sound to specialize on it. We+//! check trait is always applicable in the same way as impls, except that step+//! 4 is now "all predicates on `impl1` are always applicable". We require that+//! `specialization` or `min_specialization` is enabled to implement these+//! traits.+//!+//! ### rustc_specialization_marker+//!+//! There are also some specialization on traits with no methods, including the+//! stable `FusedIterator` trait. We allow marking marker traits with an+//! unstable attribute that means we ignore them in point 3 of the checks+//! above. This is unsound but we allow it in the short term since it can't+//! cause use after frees with purely safe code in the same way as specializing+//! on traits with methods can.++use crate::constrained_generic_params as cgp;++use rustc::infer::outlives::env::OutlivesEnvironment;+use rustc::infer::{InferCtxt, SuppressRegionErrors};+use rustc::middle::region::ScopeTree;+use rustc::traits::specialization_graph::Node;+use rustc::traits::{self, translate_substs};+use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};+use rustc::ty::trait_def::TraitSpecializationKind;+use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};+use rustc_data_structures::fx::FxHashSet;+use rustc_hir as hir;+use rustc_hir::def_id::DefId;+use rustc_span::Span;++pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {+    if let Some(node) = parent_specialization_node(tcx, impl_def_id) {+        tcx.infer_ctxt().enter(|infcx| {+            check_always_applicable(&infcx, impl_def_id, node, span);+        });+    }+}++fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {+    let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;+    let trait_def = tcx.trait_def(trait_ref.def_id);++    let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;++    let always_applicable_trait =+        matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);+    if impl2_node.is_from_trait() && !always_applicable_trait {+        // Implementing a normal trait isn't a specialization.+        return None;+    }+    Some(impl2_node)+}++/// Check that `impl1` is a sound specialization+fn check_always_applicable(+    infcx: &InferCtxt<'_, '_>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) {+    if let Some((impl1_substs, impl2_substs)) =+        get_impl_substs(infcx, impl1_def_id, impl2_node, span)+    {+        let impl2_def_id = impl2_node.def_id();+        debug!(+            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",+            impl1_def_id, impl2_def_id, impl2_substs+        );++        let tcx = infcx.tcx;++        let parent_substs = unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs);++        check_static_lifetimes(tcx, &parent_substs, span);+        check_duplicate_params(tcx, impl1_substs, &parent_substs, span);++        check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);+    }+}++// Get substs for the two impls so that they have the same `TraitRef`.+fn get_impl_substs<'tcx>(+    infcx: &InferCtxt<'_, 'tcx>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {+    let tcx = infcx.tcx;+    let param_env = tcx.param_env(impl1_def_id);++    let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);+    let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);++    // Conservatively use an empty `ParamEnv`.+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());+    infcx.resolve_regions_and_report_errors(+        impl1_def_id,+        &ScopeTree::default(),+        &outlives_env,+        SuppressRegionErrors::default(),+    );+    let impl2_substs = match infcx.fully_resolve(&impl2_substs) {+        Ok(s) => s,+        Err(_) => {+            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();+            return None;+        }+    };+    Some((impl1_substs, impl2_substs))+}++/// Returns a list of all of the unconstrained subst of the given impl.+fn unconstrained_parent_impl_substs<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl_def_id: DefId,+    impl_substs: SubstsRef<'tcx>,+) -> Vec<GenericArg<'tcx>> {+    let mut seen_params = FxHashSet::default();+    let mut constrained_params = FxHashSet::default();++    let impl2_identity_substs = InternalSubsts::identity_for_item(tcx, impl_def_id);+    let impl2_generic_predicates = tcx.predicates_of(impl_def_id);+    let impl2_identity_predicates =+        impl2_generic_predicates.instantiate(tcx, impl2_identity_substs);++    for predicate in impl2_identity_predicates.predicates.iter() {+        if let ty::Predicate::Projection(proj) = predicate {+            let projection_ty = proj.skip_binder().projection_ty;+            let projected_ty = proj.skip_binder().ty;+            seen_params.extend(cgp::parameters_for(&projection_ty, true));+            for param in cgp::parameters_for(&projected_ty, false) {+                if !seen_params.contains(&param) {+                    constrained_params.insert(param.0);+                }+            }+            seen_params.extend(cgp::parameters_for(&projected_ty, true));+        }+    }++    impl_substs+        .iter()+        .enumerate()+        .filter(|(idx, _)| !constrained_params.contains(&(*idx as u32)))+        .map(|(_, arg)| *arg)+        .collect()+}++fn check_duplicate_params<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl1_substs: SubstsRef<'tcx>,+    parent_substs: &Vec<GenericArg<'tcx>>,+    span: Span,+) {+    let mut base_params = cgp::parameters_for(parent_substs, true);+    base_params.sort_by_key(|param| param.0);+    if let (_, [duplicate, ..]) = base_params.partition_dedup() {+        let param = impl1_substs[duplicate.0 as usize];+        tcx.sess+            .struct_span_err(span, &format!("specializing impl repeats parameter `{}`", param))+            .emit();+    }+}++fn check_static_lifetimes<'tcx>(+    tcx: TyCtxt<'tcx>,+    parent_substs: &Vec<GenericArg<'tcx>>,+    span: Span,+) {+    if tcx.any_free_region_meets(parent_substs, |r| *r == ty::ReStatic) {+        tcx.sess.struct_span_err(span, &format!("cannot specialize on `'static` lifetime")).emit();+    }+}++fn check_predicates<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl1_def_id: DefId,+    impl1_substs: SubstsRef<'tcx>,+    impl2_node: Node,+    impl2_substs: SubstsRef<'tcx>,+    span: Span,+) {+    let impl1_predicates = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);+    let mut impl2_predicates = if impl2_node.is_from_trait() {+        // Always applicable traits have to be always applicable without any+        // assumptions.+        InstantiatedPredicates::empty()+    } else {+        tcx.predicates_of(impl2_node.def_id()).instantiate(tcx, impl2_substs)+    };+    debug!(+        "check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)",+        impl1_predicates, impl2_predicates,+    );++    // Since impls of always applicable traits don't get to assume anything, we+    // can also assume their supertraits apply.+    let always_applicable_traits: Vec<_> = impl1_predicates+        .predicates+        .iter()+        .filter(|predicate| {+            matches!(+                trait_predicate_kind(tcx, predicate),+                Some(TraitSpecializationKind::AlwaysApplicable)+            )+        })+        .copied()+        .collect();+    impl2_predicates.predicates.extend(traits::elaborate_predicates(tcx, always_applicable_traits));++    for predicate in impl1_predicates.predicates {

This is implemented now.

matthewjasper

comment created time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha c9cd389dd690725c15d5dd0cf030376ea7fdeccb

Consider well-formed predicates in min-specialization

view details

push time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha 83ef0cdfdc7bf11c0b2b1d259f95375a16885ecf

Consider well-formed predicates in min-specialization

view details

push time in a month

pull request commentrust-lang/rust

fix #62456

r=me with comments addressed

contrun

comment created time in a month

Pull request review commentrust-lang/rust

fix #62456

+#![feature(const_generics)]

File should not be marked as executable.

contrun

comment created time in a month

Pull request review commentrust-lang/rust

fix #62456

 use rustc::ty; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::Ty; use rustc::ty::TypeFoldable;-use rustc::ty::{AdtKind, Visibility};+use rustc::{+    mir::interpret::ErrorHandled,

This should be in its own use item.

contrun

comment created time in a month

Pull request review commentrust-lang/rust

fix #62456

 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {         };          if element_ty.references_error() {-            tcx.types.err-        } else if let Ok(count) = count {-            tcx.mk_ty(ty::Array(t, count))-        } else {-            tcx.types.err+            return tcx.types.err;+        }+        match count {+            Ok(count) => tcx.mk_ty(ty::Array(t, count)),+            Err(ErrorHandled::TooGeneric) => {+                self.tcx.sess.span_err(+                    tcx.def_span(count_def_id),+                    "array lengths can't depend on generic parameters",+                );+                tcx.types.err+            }+            _ => tcx.types.err,
            Err(ErrorHandled::Reported) => tcx.types.err,
contrun

comment created time in a month

pull request commentrust-lang/rust

miri: ICE on invalid terminators

Abort is used instead of Resume for functions annotated with #[unwind(aborts)] when compiling with -Cpanic=unwind.

RalfJung

comment created time in a month

Pull request review commentrust-lang/blog.rust-lang.org

blog post: recent & future pattern matching improvements

+---+layout: post+title: "Recent and future pattern matching improvements"+author: Mazdak "Centril" Farrokhzad+description: "Reviewing recent pattern matching improvements"+team: the language <https://www.rust-lang.org/governance/teams/lang> and compiler <https://www.rust-lang.org/governance/teams/compiler> teams+---++[ch_6]: https://doc.rust-lang.org/book/ch06-00-enums.html+[ch_18]: https://doc.rust-lang.org/book/ch18-00-patterns.html+[ref_match]: https://doc.rust-lang.org/reference/expressions/match-expr.html+[ref_pat]: https://doc.rust-lang.org/reference/patterns.html+[ref_place]: https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions++Much of writing software revolves around checking if some data has some shape ("pattern"), extracting information from it, and then reacting if there was a match. To facilitate this, many modern languages, Rust included, support what is known as "pattern matching".++> If you are new to Rust or want to refresh your knowledge, you may first want to read chapters [6, Enums and Pattern Matching][ch_6] and [18, Patterns and Matching][ch_18] in the book, or read more about [`match` expressions][ref_match] and [patterns][ref_pat] in the reference.++Pattern matching in Rust works by checking if a [*place*][ref_place] in memory (the "data") matches a certain *pattern*. In this post, we will look at some recent improvements to patterns soon available in stable Rust as well as some more in already available in nightly.++## Subslice patterns, `[head, tail @ ..]`++[fixed_slice]: https://blog.rust-lang.org/2018/05/10/Rust-1.26.html#basic-slice-patterns+[recover_attrs_no_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.recover_attrs_no_item+[pr_subslice]: https://github.com/rust-lang/rust/pull/67712++Lists, are one of the most basic and common data structures found in software. In Rust, lists are usually a contiguous sequence of elements in memory, or a *slice*.++Since slices are so commonplace, it is important that working with them is easy. To that end, we stabilized [*fixed-length slice patterns* in Rust 1.26.0][fixed_slice]. So now it is possible to e.g., write `let [a, b, c] = my_array;` to destructure an array of 3 elements. Oftentimes, however, we're working with a slice of unknown length, so given only fixed-length slice patterns, we have to provide a fallback `match` arm with e.g. `_` as the pattern.++In Rust 1.42.0, [we are stabilizing *subslice patterns*][pr_subslice]. To introduce a subslice pattern, we use `..` which denotes a variable-length gap, matching as many elements as possible not matched by the patterns before and after the `..`. For example, in a parser, we would like to error when a list of attributes, `attrs`, is not followed by an item, [so we write][recover_attrs_no_item]:++```rust+/// Recover if we parsed attributes and expected an item but there was none.+fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {+    let (start, end) = match attrs {+        [] => return Ok(()),+        [x0] => (x0, x0),+        [x0, .., xn] => (x0, xn),+    };+    let msg = if end.is_doc_comment() {+        "expected item after doc comment"+    } else {+        "expected item after attributes"+    };+    let mut err = self.struct_span_err(end.span, msg);+    if end.is_doc_comment() {+        err.span_label(end.span, "this doc comment doesn't document anything");+    }+    if let [.., penultimate, _] = attrs {+        err.span_label(start.span.to(penultimate.span), "other attributes here");+    }+    Err(err)+}+```++Here we have two subslice patterns, the first one being `[x0, .., xn]`. In this case, the pattern binds `x0`, the first element, and `xn`, the last element, and ignores everything in the middle, matching a slice with at least two elements in total. Meanwhile, `[]` and `[x0]` match cases with fewer than two elements, so the compiler knows that we have covered all possibilities. In the latter case, we extract the `penultimate` element of the slice, which, as the name suggests, also requires that the slice has at least two elements.++We can also bind a subslice to a variable. For example, suppose we want to disallow `...` in all but the last parameter of a function. If so, we can write:++```rust+match &*fn_decl.inputs {+    ... // other arms+    [ps @ .., _] => {+        for Param { ty, span, .. } in ps {+            if let TyKind::CVarArgs = ty.kind {+                self.err_handler().span_err(+                    *span,+                    "`...` must be the last argument of a C-variadic function",+                );+            }+        }+    }+}+```++Here, `ps @ ..` will bind the initial elements of the slice to `ps` and ignore the last element.++After more than 7 years of baking in nightly, with many twists and turns, subslice patterns will finally be stable. To get here, we've had to redesign the feature, plug soundness holes in the borrow checker, and substantially refactor the exhaustiveness checker. For more on how we got here, [read the stabilization report][pr_subslice], [Thomas Hartmann's blog post][thomas_subslice], and stay tuned for the 1.42.0 release announcement  on the 12th of March.++[thomas_subslice]: https://thomashartmann.dev/blog/feature(slice_patterns)/++## Nested OR-patterns++[tracking_or_pats]: https://github.com/rust-lang/rust/issues/54883++When pattern matching on an `enum`, the logic for some of the variants may be exactly the same. To avoid repeating ourselves, the `|` separator in `match`, `if let`, or `while let` expressions can be used to say that the branch should be taken if any of the `|`-separated patterns match. For example, we may write:++```rust+// Any local node that may call something in its body block should be explored.+fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {+    match tcx.hir().find(hir_id) {+        Some(Node::Item(..))+        | Some(Node::ImplItem(..))+        | Some(Node::ForeignItem(..))+        | Some(Node::TraitItem(..))+        | Some(Node::Variant(..))+        | Some(Node::AnonConst(..))+        | Some(Node::Pat(..)) => true,+        _ => false,+    }+}+```++This is serviceable, but `Some(_)` is still repeated several times. With [`#![feature(or_patterns)]`][tracking_or_pats], which recently became usable on nightly, this repetition can be avoided:++```rust+// Any local node that may call something in its body block should be explored.+fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {+    match tcx.hir().find(hir_id) {+        Some(+            Node::Item(..)+            | Node::ImplItem(..)+            | Node::ForeignItem(..)+            | Node::TraitItem(..)+            | Node::Variant(..)+            | Node::AnonConst(..)+            | Node::Pat(..),+        ) => true,+        _ => false,+    }+}+```++Previously, when using `|` in a `match` expression, the `|` syntax was part of `match` itelf. With `or_patterns`, this is now part of patterns themselves, so you can nest OR-patterns arbitrarily, and use them in `let` statements too:++```rust+let Ok(x) | Err(x) = foo();+```++An OR-pattern covers the *union* of all the `|`-ed ("or-ed") patterns. To ensure that whatever alternative matched, all bindings are consistent and initialized, each or-ed pattern must include the exact same set of bindings, with the same types, and the same binding modes.

The compiler doesn't currently track binding modes separately for each binding. Since Ok(x) | Err(mut x) has to be an error, and Ok(ref x) | Err(&ref x) is allowed, there isn't much reason to change this.

Centril

comment created time in a month

pull request commentrust-lang/rust

Propagate lifetime resolution errors into tcx.type_of

It should be OK to assume that lifetime resolution is producing sane results, if a lifetime cannot be resolved then not recording it will result in AST conv lowering it as 'static.

The problem here is that lifetime resolution is recording 'a as EarlyBound with index 0, when it should have index 1 (A has index 0).

Aaron1011

comment created time in a month

push eventmatthewjasper/rust

Matthew Jasper

commit sha b4ff4c9c9562b92665d34f17b571c269b3c59490

Implement soundness check for min_specialization

view details

Matthew Jasper

commit sha 7a1ed3821f4624a962fd7b2579740eb6b7e3a60d

Use min_specialization in libstd and libproc_macro

view details

push time in a month

Pull request review commentrust-lang/rust

Implement a feature for a sound specialization subset

+//! # Minimal Specialization+//!+//! This module contains the checks for sound specialization used when the+//! `min_specialization` feature is enabled. This requires that the impl is+//! *always applicable*.+//!+//! If `impl1` specializes `impl2` then `impl1` is always applicable if we know+//! that all the bounds of `impl2` are satisfied, and all of the bounds of+//! `impl1` are satisfied for some choice of lifetimes then we know that+//! `impl1` applies for any choice of lifetimes.+//!+//! ## Basic approach+//!+//! To enforce this requirement on specializations we take the following+//! approach:+//!+//! 1. Match up the substs for `impl2` so that the implemented trait and+//!    self-type match those for `impl1`.+//! 2. Check for any direct use of `'static` in the substs of `impl2`.+//! 3. Check that all of the generic parameters of `impl1` occur at most once+//!    in the *unconstrained* substs for `impl2`. A parameter is constrained if+//!    its value is completely determined by an associated type projection+//!    predicate.+//! 4. Check that all predicates on `impl1` also exist on `impl2` (after+//!    matching substs).+//!+//! ## Example+//!+//! Suppose we have the following always applicable impl:+//!+//! ```rust+//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }+//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }+//! ```+//!+//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is+//! constrained to be `<I as Iterator>::Item`, so we check only+//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The+//! predicates of `impl1` are only `T: Sized`, which is also a predicate of+//! `impl2`. So this specialization is sound.+//!+//! ## Extensions+//!+//! Unfortunately not all specializations in the standard library are allowed+//! by this. So there are two extensions to these rules that allow specializing+//! on some traits.+//!+//! ### rustc_specialization_trait+//!+//! If a trait is always applicable, then it's sound to specialize on it. We+//! check trait is always applicable in the same way as impls, except that step+//! 4 is now "all predicates on `impl1` are always applicable". We require that+//! `specialization` or `min_specialization` is enabled to implement these+//! traits.+//!+//! ### rustc_specialization_marker+//!+//! There are also some specialization on traits with no methods, including the+//! stable `FusedIterator` trait. We allow marking marker traits with an+//! unstable attribute that means we ignore them in point 3 of the checks+//! above. This is unsound but we allow it in the short term since it can't+//! cause use after frees with purely safe code in the same way as specializing+//! on traits with methods can.++use crate::constrained_generic_params as cgp;++use rustc::infer::outlives::env::OutlivesEnvironment;+use rustc::infer::{InferCtxt, SuppressRegionErrors};+use rustc::middle::region::ScopeTree;+use rustc::traits::specialization_graph::Node;+use rustc::traits::{self, translate_substs};+use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};+use rustc::ty::trait_def::TraitSpecializationKind;+use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};+use rustc_data_structures::fx::FxHashSet;+use rustc_hir as hir;+use rustc_hir::def_id::DefId;+use rustc_span::Span;++pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {+    if let Some(node) = parent_specialization_node(tcx, impl_def_id) {+        tcx.infer_ctxt().enter(|infcx| {+            check_always_applicable(&infcx, impl_def_id, node, span);+        });+    }+}++fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {+    let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;+    let trait_def = tcx.trait_def(trait_ref.def_id);++    let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;++    let always_applicable_trait =+        matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);+    if impl2_node.is_from_trait() && !always_applicable_trait {+        // Implementing a normal trait isn't a specialization.+        return None;+    }+    Some(impl2_node)+}++/// Check that `impl1` is a sound specialization+fn check_always_applicable(+    infcx: &InferCtxt<'_, '_>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) {+    if let Some((impl1_substs, impl2_substs)) =+        get_impl_substs(infcx, impl1_def_id, impl2_node, span)+    {+        let impl2_def_id = impl2_node.def_id();+        debug!(+            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",+            impl1_def_id, impl2_def_id, impl2_substs+        );++        let tcx = infcx.tcx;++        let parent_substs = unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs);++        check_static_lifetimes(tcx, &parent_substs, span);+        check_duplicate_params(tcx, impl1_substs, &parent_substs, span);++        check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);+    }+}++// Get substs for the two impls so that they have the same `TraitRef`.+fn get_impl_substs<'tcx>(+    infcx: &InferCtxt<'_, 'tcx>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {+    let tcx = infcx.tcx;+    let param_env = tcx.param_env(impl1_def_id);++    let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);+    let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);++    // Conservatively use an empty `ParamEnv`.+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());+    infcx.resolve_regions_and_report_errors(+        impl1_def_id,+        &ScopeTree::default(),+        &outlives_env,+        SuppressRegionErrors::default(),+    );+    let impl2_substs = match infcx.fully_resolve(&impl2_substs) {+        Ok(s) => s,+        Err(_) => {+            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();+            return None;+        }+    };+    Some((impl1_substs, impl2_substs))+}++/// Returns a list of all of the unconstrained subst of the given impl.+fn unconstrained_parent_impl_substs<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl_def_id: DefId,+    impl_substs: SubstsRef<'tcx>,+) -> Vec<GenericArg<'tcx>> {+    let mut seen_params = FxHashSet::default();+    let mut constrained_params = FxHashSet::default();

Added an explanation

matthewjasper

comment created time in a month

push eventmatthewjasper/rust

Aaron Hill

commit sha a60669d95cdad0e28cf28790b717bbcf235153f8

Properly use parent generics for opaque types Fixes #67844 Previously, opaque types would only get parent generics if they a return-position-impl-trait (e.g. `fn foo<A>() -> impl MyTrait<A>`). However, it's possible for opaque types to be nested inside one another: ```rust trait WithAssoc { type AssocType; } trait WithParam<A> {} type Return<A> = impl WithAssoc<AssocType = impl WithParam<A>>; ``` When this occurs, we need to ensure that the nested opaque types properly inherit generic parameters from their parent opaque type. This commit fixes the `generics_of` query to take the parent item into account when determining the generics for an opaque type.

view details

Dylan DPC

commit sha 8007f8468b942e689a8db771c4e76c67cdd40c3b

Rollup merge of #68694 - nnethercote:reduce-RefCells-in-InferCtxt, r=varkor Reduce the number of `RefCell`s in `InferCtxt`. `InferCtxt` contains six structures within `RefCell`s. Every time we create and dispose of (commit or rollback) a snapshot we have to `borrow_mut` each one of them. This commit moves the six structures under a single `RefCell`, which gives significant speed-ups by reducing the number of `borrow_mut` calls. To avoid runtime errors I had to reduce the lifetimes of dynamic borrows in a couple of places. r? @varkor

view details

Dylan DPC

commit sha b3cfb97d5c03996d5cd01c287ec2aa6760aa529a

Rollup merge of #68966 - jonas-schievink:coherence-perf, r=varkor Improve performance of coherence checks The biggest perf improvement in here is expected to come from the removal of the remaining #43355 warning code since that effectively runs the expensive parts of coherence *twice*, which can even be visualized by obtaining a flamegraph: ![image](https://user-images.githubusercontent.com/5047365/74091959-e1f41200-4a8b-11ea-969d-2849d3f86c63.png)

view details

Dylan DPC

commit sha e3315f6742fafac8efefd107676000d1a2e3bab0

Rollup merge of #68976 - ecstatic-morse:const-non-zero, r=dtolnay Make `num::NonZeroX::new` an unstable `const fn` cc #53718 These require `#[feature(const_if_match)]`, meaning they must remain unstable for the time being.

view details

Dylan DPC

commit sha 64d2d04eb911bca923726fa6c481cc858187adc3

Rollup merge of #68992 - matthewjasper:imm-binding-after-at, r=Centril Correctly parse `mut a @ b` r? @Centril Closes #67861 Closes #67926

view details

Dylan DPC

commit sha a8d4ccf907e55f5b507b6f68103d6bf151804b50

Rollup merge of #69005 - ecstatic-morse:unified-dataflow-graphviz, r=wesleywiser Small graphviz improvements for the new dataflow framework Split out from #68241. This prints the correct effect diff for each line (the before-effect and the after-effect) and makes marginal improvements to the graphviz output for the new dataflow framework including using monospaced font and better line breaking. This will only be useful when #68241 is merged and the graphviz output changes from this: ![image](https://user-images.githubusercontent.com/29463364/74107776-5e3c3300-4b28-11ea-9d33-4862228b5e87.png) to this: ![image](https://user-images.githubusercontent.com/29463364/74107751-20d7a580-4b28-11ea-99ca-24f749386601.png) r? @wesleywiser

view details

Dylan DPC

commit sha 18c6d39b5500909f38da7b76d1c51d54300c535e

Rollup merge of #69006 - petrochenkov:prevspan2, r=Centril parser: Keep current and previous tokens precisely ...including their unnormalized forms. Add more documentation for them. Hopefully, this will help to eliminate footguns like https://github.com/rust-lang/rust/pull/68728#discussion_r373787486. I'll try to address the FIXMEs in separate PRs during the next week. r? @Centril

view details

David Renshaw

commit sha 371060b5988158fdaa3b7abd6167a28d95d74b38

[parser] change an instance of span_bug() to struct_span_err() to avoid ICE

view details

XAMPPRocky

commit sha 7ab01b24674b88ff4927b0eb445a582fb9e12aba

Update RELEASES.md Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>

view details

Nicholas Nethercote

commit sha f8a02864afa2faecc3cb9cb8f81905a61a638ade

Speed up `SipHasher128`. The current code in `SipHasher128::short_write` is inefficient. It uses `u8to64_le` (which is complex and slow) to extract just the right number of bytes of the input into a u64 and pad the result with zeroes. It then left-shifts that value in order to bitwise-OR it with `self.tail`. For example, imagine we have a u32 input 0xIIHH_GGFF and only need three bytes to fill up `self.tail`. The current code uses `u8to64_le` to construct 0x0000_0000_00HH_GGFF, which is just 0xIIHH_GGFF with the 0xII removed and zero-extended to a u64. The code then left-shifts that value by five bytes -- discarding the 0x00 byte that replaced the 0xII byte! -- to give 0xHHGG_FF00_0000_0000. It then then ORs that value with self.tail. There's a much simpler way to do it: zero-extend to u64 first, then left shift. E.g. 0xIIHH_GGFF is zero-extended to 0x0000_0000_IIHH_GGFF, and then left-shifted to 0xHHGG_FF00_0000_0000. We don't have to take time to exclude the unneeded 0xII byte, because it just gets shifted out anyway! It also avoids multiple occurrences of `unsafe`. There's a similar story with the setting of `self.tail` at the method's end. The current code uses `u8to64_le` to extract the remaining part of the input, but the same effect can be achieved more quickly with a right shift on the zero-extended input. All that works on little-endian. It doesn't work for big-endian, but we can just do a `to_le` before calling `short_write` and then it works. This commit changes `SipHasher128` to use the simpler shift-based approach. The code is also smaller, which means that `short_write` is now inlined where previously it wasn't, which makes things faster again. This gives big speed-ups for all incremental builds, especially "baseline" incremental builds.

view details

Ralf Jung

commit sha b434d7ef8ae19c145dd9348b70bb955147dfab70

add test that checks overflows on arithmetic operators

view details

Ralf Jung

commit sha 1ddb0503ff1e203de40f5bbc1e0b00d1b4e99d12

div/rem overflow tests: also test i128

view details

Ralf Jung

commit sha d6c5a04eff9643b634cb2c98411f973b8f7aa1e2

some more tests for i128 oveflow behavior

view details

bors

commit sha 4d1241f5158ffd66730e094d8f199ed654ed52ae

Auto merge of #69012 - Dylan-DPC:rollup-13qn0fq, r=Dylan-DPC Rollup of 6 pull requests Successful merges: - #68694 (Reduce the number of `RefCell`s in `InferCtxt`.) - #68966 (Improve performance of coherence checks) - #68976 (Make `num::NonZeroX::new` an unstable `const fn`) - #68992 (Correctly parse `mut a @ b`) - #69005 (Small graphviz improvements for the new dataflow framework) - #69006 (parser: Keep current and previous tokens precisely) Failed merges: r? @ghost

view details

Guillaume Gomez

commit sha ded629289a4040450396ea83ad9bddc459a9582c

Clean up E0283 explanation

view details

Guillaume Gomez

commit sha 37e7b461778fab0c9dbe287e4eb3b7096ad6356f

clean up E0275 explanation

view details

ljedrz

commit sha b8893df8d344c11880c4aada639727fbfc195792

preallocate 2 Vecs in traits; tweak WfPredicates::normalize

view details

XAMPPRocky

commit sha 32daa2aa38fafd731ddc27374dece22f38069bc8

Update RELEASES.md

view details

Michael Woerister

commit sha 81dccb1a5c7b67c61cb7eb421150c671d6e1a7de

self-profile: Support arguments for generic_activities.

view details

bors

commit sha e6ec0d125eba4074122b187032474b4174fb9d31

Auto merge of #68835 - CAD97:sound-range-inclusive, r=Mark-Simulacrum Remove problematic specialization from RangeInclusive Fixes #67194 using the approach [outlined by Mark-Simulacrum](https://github.com/rust-lang/rust/issues/67194#issuecomment-581669549). > I believe the property we want is that if `PartialEq(&self, &other) == true`, then `self.next() == other.next()`. It is true that this is satisfied by removing the specialization and always doing `is_empty.unwrap_or_default()`; the "wrong" behavior there arises from calling `next()` having an effect on initially empty ranges, as we should be in `is_empty = true` but are not (yet) there. It might be possible to detect that the current state is always empty (i.e., `start > end`) and then not fill in the empty slot. I think this might solve the problem without regressing tests; however, this could have performance implications. > That approach essentially states that we only use the `is_empty` slot for cases where `start <= end`. That means that `Idx: !Step` and `start > end` would both behave the same, and correctly -- we do not need the boolean if we're not ever going to emit any values from the iterator. This is implemented here by replacing the `is_empty: Option<bool>` slot with an `exhausted: bool` slot. This flag is - `false` upon construction, - `false` when iteration has not yielded an element -- importantly, this means it is always `false` for an iterator empty by construction, - `false` when iteration has yielded an element and the iterator is not exhausted, and - only `true` when iteration has been used to exhaust the iterator. For completeness, this also adds a note to the `Debug` representation to note when the range is exhausted.

view details

push time in a month

Pull request review commentrust-lang/rust

Implement a feature for a sound specialization subset

+//! # Minimal Specialization+//!+//! This module contains the checks for sound specialization used when the+//! `min_specialization` feature is enabled. This requires that the impl is+//! *always applicable*.+//!+//! If `impl1` specializes `impl2` then `impl1` is always applicable if we know+//! that all the bounds of `impl2` are satisfied, and all of the bounds of+//! `impl1` are satisfied for some choice of lifetimes then we know that+//! `impl1` applies for any choice of lifetimes.+//!+//! ## Basic approach+//!+//! To enforce this requirement on specializations we take the following+//! approach:+//!+//! 1. Match up the substs for `impl2` so that the implemented trait and+//!    self-type match those for `impl1`.+//! 2. Check for any direct use of `'static` in the substs of `impl2`.+//! 3. Check that all of the generic parameters of `impl1` occur at most once+//!    in the *unconstrained* substs for `impl2`. A parameter is constrained if+//!    its value is completely determined by an associated type projection+//!    predicate.+//! 4. Check that all predicates on `impl1` also exist on `impl2` (after+//!    matching substs).+//!+//! ## Example+//!+//! Suppose we have the following always applicable impl:+//!+//! ```rust+//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }+//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }+//! ```+//!+//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is+//! constrained to be `<I as Iterator>::Item`, so we check only+//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The+//! predicates of `impl1` are only `T: Sized`, which is also a predicate of+//! `impl2`. So this specialization is sound.+//!+//! ## Extensions+//!+//! Unfortunately not all specializations in the standard library are allowed+//! by this. So there are two extensions to these rules that allow specializing+//! on some traits.+//!+//! ### rustc_specialization_trait+//!+//! If a trait is always applicable, then it's sound to specialize on it. We+//! check trait is always applicable in the same way as impls, except that step+//! 4 is now "all predicates on `impl1` are always applicable". We require that+//! `specialization` or `min_specialization` is enabled to implement these+//! traits.+//!+//! ### rustc_specialization_marker+//!+//! There are also some specialization on traits with no methods, including the+//! stable `FusedIterator` trait. We allow marking marker traits with an+//! unstable attribute that means we ignore them in point 3 of the checks+//! above. This is unsound but we allow it in the short term since it can't+//! cause use after frees with purely safe code in the same way as specializing+//! on traits with methods can.++use crate::constrained_generic_params as cgp;++use rustc::infer::outlives::env::OutlivesEnvironment;+use rustc::infer::{InferCtxt, SuppressRegionErrors};+use rustc::middle::region::ScopeTree;+use rustc::traits::specialization_graph::Node;+use rustc::traits::{self, translate_substs};+use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};+use rustc::ty::trait_def::TraitSpecializationKind;+use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};+use rustc_data_structures::fx::FxHashSet;+use rustc_hir as hir;+use rustc_hir::def_id::DefId;+use rustc_span::Span;++pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {+    if let Some(node) = parent_specialization_node(tcx, impl_def_id) {+        tcx.infer_ctxt().enter(|infcx| {+            check_always_applicable(&infcx, impl_def_id, node, span);+        });+    }+}++fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {+    let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;+    let trait_def = tcx.trait_def(trait_ref.def_id);++    let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;++    let always_applicable_trait =+        matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);+    if impl2_node.is_from_trait() && !always_applicable_trait {+        // Implementing a normal trait isn't a specialization.+        return None;+    }+    Some(impl2_node)+}++/// Check that `impl1` is a sound specialization+fn check_always_applicable(+    infcx: &InferCtxt<'_, '_>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) {+    if let Some((impl1_substs, impl2_substs)) =+        get_impl_substs(infcx, impl1_def_id, impl2_node, span)+    {+        let impl2_def_id = impl2_node.def_id();+        debug!(+            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",+            impl1_def_id, impl2_def_id, impl2_substs+        );++        let tcx = infcx.tcx;++        let parent_substs = unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs);++        check_static_lifetimes(tcx, &parent_substs, span);+        check_duplicate_params(tcx, impl1_substs, &parent_substs, span);++        check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);+    }+}++// Get substs for the two impls so that they have the same `TraitRef`.+fn get_impl_substs<'tcx>(+    infcx: &InferCtxt<'_, 'tcx>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {+    let tcx = infcx.tcx;+    let param_env = tcx.param_env(impl1_def_id);++    let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);+    let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);++    // Conservatively use an empty `ParamEnv`.+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());+    infcx.resolve_regions_and_report_errors(+        impl1_def_id,+        &ScopeTree::default(),+        &outlives_env,+        SuppressRegionErrors::default(),+    );+    let impl2_substs = match infcx.fully_resolve(&impl2_substs) {+        Ok(s) => s,+        Err(_) => {+            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();+            return None;+        }+    };+    Some((impl1_substs, impl2_substs))+}++/// Returns a list of all of the unconstrained subst of the given impl.+fn unconstrained_parent_impl_substs<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl_def_id: DefId,+    impl_substs: SubstsRef<'tcx>,+) -> Vec<GenericArg<'tcx>> {+    let mut seen_params = FxHashSet::default();+    let mut constrained_params = FxHashSet::default();++    let impl2_identity_substs = InternalSubsts::identity_for_item(tcx, impl_def_id);+    let impl2_generic_predicates = tcx.predicates_of(impl_def_id);+    let impl2_identity_predicates =+        impl2_generic_predicates.instantiate(tcx, impl2_identity_substs);++    for predicate in impl2_identity_predicates.predicates.iter() {+        if let ty::Predicate::Projection(proj) = predicate {+            let projection_ty = proj.skip_binder().projection_ty;+            let projected_ty = proj.skip_binder().ty;+            seen_params.extend(cgp::parameters_for(&projection_ty, true));+            for param in cgp::parameters_for(&projected_ty, false) {+                if !seen_params.contains(&param) {+                    constrained_params.insert(param.0);+                }+            }+            seen_params.extend(cgp::parameters_for(&projected_ty, true));+        }+    }++    impl_substs+        .iter()+        .enumerate()+        .filter(|(idx, _)| !constrained_params.contains(&(*idx as u32)))+        .map(|(_, arg)| *arg)+        .collect()+}++fn check_duplicate_params<'tcx>(

It needs to be Vec so that it's TypeFoldable.

matthewjasper

comment created time in a month

Pull request review commentrust-lang/rust

Implement a feature for a sound specialization subset

+//! # Minimal Specialization+//!+//! This module contains the checks for sound specialization used when the+//! `min_specialization` feature is enabled. This requires that the impl is+//! *always applicable*.+//!+//! If `impl1` specializes `impl2` then `impl1` is always applicable if we know+//! that all the bounds of `impl2` are satisfied, and all of the bounds of+//! `impl1` are satisfied for some choice of lifetimes then we know that+//! `impl1` applies for any choice of lifetimes.+//!+//! ## Basic approach+//!+//! To enforce this requirement on specializations we take the following+//! approach:+//!+//! 1. Match up the substs for `impl2` so that the implemented trait and+//!    self-type match those for `impl1`.+//! 2. Check for any direct use of `'static` in the substs of `impl2`.+//! 3. Check that all of the generic parameters of `impl1` occur at most once+//!    in the *unconstrained* substs for `impl2`. A parameter is constrained if+//!    its value is completely determined by an associated type projection+//!    predicate.+//! 4. Check that all predicates on `impl1` also exist on `impl2` (after+//!    matching substs).+//!+//! ## Example+//!+//! Suppose we have the following always applicable impl:+//!+//! ```rust+//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }+//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }+//! ```+//!+//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is+//! constrained to be `<I as Iterator>::Item`, so we check only+//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The+//! predicates of `impl1` are only `T: Sized`, which is also a predicate of+//! `impl2`. So this specialization is sound.+//!+//! ## Extensions+//!+//! Unfortunately not all specializations in the standard library are allowed+//! by this. So there are two extensions to these rules that allow specializing+//! on some traits.+//!+//! ### rustc_specialization_trait+//!+//! If a trait is always applicable, then it's sound to specialize on it. We+//! check trait is always applicable in the same way as impls, except that step+//! 4 is now "all predicates on `impl1` are always applicable". We require that+//! `specialization` or `min_specialization` is enabled to implement these+//! traits.+//!+//! ### rustc_specialization_marker+//!+//! There are also some specialization on traits with no methods, including the+//! stable `FusedIterator` trait. We allow marking marker traits with an+//! unstable attribute that means we ignore them in point 3 of the checks+//! above. This is unsound but we allow it in the short term since it can't+//! cause use after frees with purely safe code in the same way as specializing+//! on traits with methods can.++use crate::constrained_generic_params as cgp;++use rustc::infer::outlives::env::OutlivesEnvironment;+use rustc::infer::{InferCtxt, SuppressRegionErrors};+use rustc::middle::region::ScopeTree;+use rustc::traits::specialization_graph::Node;+use rustc::traits::{self, translate_substs};+use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};+use rustc::ty::trait_def::TraitSpecializationKind;+use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};+use rustc_data_structures::fx::FxHashSet;+use rustc_hir as hir;+use rustc_hir::def_id::DefId;+use rustc_span::Span;++pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {+    if let Some(node) = parent_specialization_node(tcx, impl_def_id) {+        tcx.infer_ctxt().enter(|infcx| {+            check_always_applicable(&infcx, impl_def_id, node, span);+        });+    }+}++fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {+    let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;+    let trait_def = tcx.trait_def(trait_ref.def_id);++    let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;++    let always_applicable_trait =+        matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);+    if impl2_node.is_from_trait() && !always_applicable_trait {+        // Implementing a normal trait isn't a specialization.+        return None;+    }+    Some(impl2_node)+}++/// Check that `impl1` is a sound specialization+fn check_always_applicable(+    infcx: &InferCtxt<'_, '_>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) {+    if let Some((impl1_substs, impl2_substs)) =+        get_impl_substs(infcx, impl1_def_id, impl2_node, span)+    {+        let impl2_def_id = impl2_node.def_id();+        debug!(+            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",+            impl1_def_id, impl2_def_id, impl2_substs+        );++        let tcx = infcx.tcx;++        let parent_substs = unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs);++        check_static_lifetimes(tcx, &parent_substs, span);+        check_duplicate_params(tcx, impl1_substs, &parent_substs, span);++        check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);+    }+}++// Get substs for the two impls so that they have the same `TraitRef`.+fn get_impl_substs<'tcx>(+    infcx: &InferCtxt<'_, 'tcx>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {+    let tcx = infcx.tcx;+    let param_env = tcx.param_env(impl1_def_id);++    let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);+    let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);++    // Conservatively use an empty `ParamEnv`.+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());+    infcx.resolve_regions_and_report_errors(+        impl1_def_id,+        &ScopeTree::default(),+        &outlives_env,+        SuppressRegionErrors::default(),+    );+    let impl2_substs = match infcx.fully_resolve(&impl2_substs) {+        Ok(s) => s,+        Err(_) => {+            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();+            return None;+        }+    };+    Some((impl1_substs, impl2_substs))+}++/// Returns a list of all of the unconstrained subst of the given impl.+fn unconstrained_parent_impl_substs<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl_def_id: DefId,+    impl_substs: SubstsRef<'tcx>,+) -> Vec<GenericArg<'tcx>> {+    let mut seen_params = FxHashSet::default();+    let mut constrained_params = FxHashSet::default();++    let impl2_identity_substs = InternalSubsts::identity_for_item(tcx, impl_def_id);+    let impl2_generic_predicates = tcx.predicates_of(impl_def_id);+    let impl2_identity_predicates =+        impl2_generic_predicates.instantiate(tcx, impl2_identity_substs);++    for predicate in impl2_identity_predicates.predicates.iter() {+        if let ty::Predicate::Projection(proj) = predicate {+            let projection_ty = proj.skip_binder().projection_ty;+            let projected_ty = proj.skip_binder().ty;+            seen_params.extend(cgp::parameters_for(&projection_ty, true));+            for param in cgp::parameters_for(&projected_ty, false) {+                if !seen_params.contains(&param) {+                    constrained_params.insert(param.0);+                }+            }+            seen_params.extend(cgp::parameters_for(&projected_ty, true));+        }+    }++    impl_substs+        .iter()+        .enumerate()+        .filter(|(idx, _)| !constrained_params.contains(&(*idx as u32)))+        .map(|(_, arg)| *arg)+        .collect()+}++fn check_duplicate_params<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl1_substs: SubstsRef<'tcx>,+    parent_substs: &Vec<GenericArg<'tcx>>,+    span: Span,+) {+    let mut base_params = cgp::parameters_for(parent_substs, true);

parameters_for(_, true) doesn't have any special handling of any TyKind. I'm using it to conveniently handle the 3 different kinds of params.

matthewjasper

comment created time in a month

Pull request review commentrust-lang/rust

Implement a feature for a sound specialization subset

+//! # Minimal Specialization+//!+//! This module contains the checks for sound specialization used when the+//! `min_specialization` feature is enabled. This requires that the impl is+//! *always applicable*.+//!+//! If `impl1` specializes `impl2` then `impl1` is always applicable if we know+//! that all the bounds of `impl2` are satisfied, and all of the bounds of+//! `impl1` are satisfied for some choice of lifetimes then we know that+//! `impl1` applies for any choice of lifetimes.+//!+//! ## Basic approach+//!+//! To enforce this requirement on specializations we take the following+//! approach:+//!+//! 1. Match up the substs for `impl2` so that the implemented trait and+//!    self-type match those for `impl1`.+//! 2. Check for any direct use of `'static` in the substs of `impl2`.+//! 3. Check that all of the generic parameters of `impl1` occur at most once+//!    in the *unconstrained* substs for `impl2`. A parameter is constrained if+//!    its value is completely determined by an associated type projection+//!    predicate.+//! 4. Check that all predicates on `impl1` also exist on `impl2` (after+//!    matching substs).+//!+//! ## Example+//!+//! Suppose we have the following always applicable impl:+//!+//! ```rust+//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }+//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }+//! ```+//!+//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is+//! constrained to be `<I as Iterator>::Item`, so we check only+//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The+//! predicates of `impl1` are only `T: Sized`, which is also a predicate of+//! `impl2`. So this specialization is sound.+//!+//! ## Extensions+//!+//! Unfortunately not all specializations in the standard library are allowed+//! by this. So there are two extensions to these rules that allow specializing+//! on some traits.+//!+//! ### rustc_specialization_trait+//!+//! If a trait is always applicable, then it's sound to specialize on it. We+//! check trait is always applicable in the same way as impls, except that step+//! 4 is now "all predicates on `impl1` are always applicable". We require that+//! `specialization` or `min_specialization` is enabled to implement these+//! traits.+//!+//! ### rustc_specialization_marker+//!+//! There are also some specialization on traits with no methods, including the+//! stable `FusedIterator` trait. We allow marking marker traits with an+//! unstable attribute that means we ignore them in point 3 of the checks+//! above. This is unsound but we allow it in the short term since it can't+//! cause use after frees with purely safe code in the same way as specializing+//! on traits with methods can.++use crate::constrained_generic_params as cgp;++use rustc::infer::outlives::env::OutlivesEnvironment;+use rustc::infer::{InferCtxt, SuppressRegionErrors};+use rustc::middle::region::ScopeTree;+use rustc::traits::specialization_graph::Node;+use rustc::traits::{self, translate_substs};+use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};+use rustc::ty::trait_def::TraitSpecializationKind;+use rustc::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};+use rustc_data_structures::fx::FxHashSet;+use rustc_hir as hir;+use rustc_hir::def_id::DefId;+use rustc_span::Span;++pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {+    if let Some(node) = parent_specialization_node(tcx, impl_def_id) {+        tcx.infer_ctxt().enter(|infcx| {+            check_always_applicable(&infcx, impl_def_id, node, span);+        });+    }+}++fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {+    let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;+    let trait_def = tcx.trait_def(trait_ref.def_id);++    let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;++    let always_applicable_trait =+        matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);+    if impl2_node.is_from_trait() && !always_applicable_trait {+        // Implementing a normal trait isn't a specialization.+        return None;+    }+    Some(impl2_node)+}++/// Check that `impl1` is a sound specialization+fn check_always_applicable(+    infcx: &InferCtxt<'_, '_>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) {+    if let Some((impl1_substs, impl2_substs)) =+        get_impl_substs(infcx, impl1_def_id, impl2_node, span)+    {+        let impl2_def_id = impl2_node.def_id();+        debug!(+            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",+            impl1_def_id, impl2_def_id, impl2_substs+        );++        let tcx = infcx.tcx;++        let parent_substs = unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs);++        check_static_lifetimes(tcx, &parent_substs, span);+        check_duplicate_params(tcx, impl1_substs, &parent_substs, span);++        check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);+    }+}++// Get substs for the two impls so that they have the same `TraitRef`.+fn get_impl_substs<'tcx>(+    infcx: &InferCtxt<'_, 'tcx>,+    impl1_def_id: DefId,+    impl2_node: Node,+    span: Span,+) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {+    let tcx = infcx.tcx;+    let param_env = tcx.param_env(impl1_def_id);++    let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);+    let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);++    // Conservatively use an empty `ParamEnv`.+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());+    infcx.resolve_regions_and_report_errors(+        impl1_def_id,+        &ScopeTree::default(),+        &outlives_env,+        SuppressRegionErrors::default(),+    );+    let impl2_substs = match infcx.fully_resolve(&impl2_substs) {+        Ok(s) => s,+        Err(_) => {+            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();+            return None;+        }+    };+    Some((impl1_substs, impl2_substs))+}++/// Returns a list of all of the unconstrained subst of the given impl.+fn unconstrained_parent_impl_substs<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl_def_id: DefId,+    impl_substs: SubstsRef<'tcx>,+) -> Vec<GenericArg<'tcx>> {+    let mut seen_params = FxHashSet::default();+    let mut constrained_params = FxHashSet::default();++    let impl2_identity_substs = InternalSubsts::identity_for_item(tcx, impl_def_id);+    let impl2_generic_predicates = tcx.predicates_of(impl_def_id);+    let impl2_identity_predicates =+        impl2_generic_predicates.instantiate(tcx, impl2_identity_substs);++    for predicate in impl2_identity_predicates.predicates.iter() {+        if let ty::Predicate::Projection(proj) = predicate {+            let projection_ty = proj.skip_binder().projection_ty;+            let projected_ty = proj.skip_binder().ty;+            seen_params.extend(cgp::parameters_for(&projection_ty, true));+            for param in cgp::parameters_for(&projected_ty, false) {+                if !seen_params.contains(&param) {+                    constrained_params.insert(param.0);+                }+            }+            seen_params.extend(cgp::parameters_for(&projected_ty, true));+        }+    }++    impl_substs+        .iter()+        .enumerate()+        .filter(|(idx, _)| !constrained_params.contains(&(*idx as u32)))+        .map(|(_, arg)| *arg)+        .collect()+}++fn check_duplicate_params<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl1_substs: SubstsRef<'tcx>,+    parent_substs: &Vec<GenericArg<'tcx>>,+    span: Span,+) {+    let mut base_params = cgp::parameters_for(parent_substs, true);+    base_params.sort_by_key(|param| param.0);+    if let (_, [duplicate, ..]) = base_params.partition_dedup() {+        let param = impl1_substs[duplicate.0 as usize];+        tcx.sess+            .struct_span_err(span, &format!("specializing impl repeats parameter `{}`", param))+            .emit();+    }+}++fn check_static_lifetimes<'tcx>(+    tcx: TyCtxt<'tcx>,+    parent_substs: &Vec<GenericArg<'tcx>>,+    span: Span,+) {+    if tcx.any_free_region_meets(parent_substs, |r| *r == ty::ReStatic) {+        tcx.sess.struct_span_err(span, &format!("cannot specialize on `'static` lifetime")).emit();+    }+}++fn check_predicates<'tcx>(+    tcx: TyCtxt<'tcx>,+    impl1_def_id: DefId,+    impl1_substs: SubstsRef<'tcx>,+    impl2_node: Node,+    impl2_substs: SubstsRef<'tcx>,+    span: Span,+) {+    let impl1_predicates = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);+    let mut impl2_predicates = if impl2_node.is_from_trait() {+        // Always applicable traits have to be always applicable without any+        // assumptions.+        InstantiatedPredicates::empty()+    } else {+        tcx.predicates_of(impl2_node.def_id()).instantiate(tcx, impl2_substs)+    };+    debug!(+        "check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)",+        impl1_predicates, impl2_predicates,+    );++    // Since impls of always applicable traits don't get to assume anything, we+    // can also assume their supertraits apply.+    let always_applicable_traits: Vec<_> = impl1_predicates+        .predicates+        .iter()+        .filter(|predicate| {+            matches!(+                trait_predicate_kind(tcx, predicate),+                Some(TraitSpecializationKind::AlwaysApplicable)+            )+        })+        .copied()+        .collect();+    impl2_predicates.predicates.extend(traits::elaborate_predicates(tcx, always_applicable_traits));++    for predicate in impl1_predicates.predicates {

We could, it just doesn't occur in the standard library because bounds are rarely found on libstd types, rather than their impls.

matthewjasper

comment created time in a month

Pull request review commentrust-lang/rust-clippy

Rustup to rust-lang/rust#69469

 fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: S                 db.span_label(const_kw_span, "make this a static item (maybe with lazy_static)");             },             Source::Assoc { ty: ty_span, .. } => {-                if ty.flags.contains(TypeFlags::HAS_FREE_LOCAL_NAMES) {+                if !ty.has_infer_types_or_consts() {

I think that this should keep the meaning of the original code:

                if ty.flags.intersects(TypeFlags::HAS_FREE_LOCAL_NAMES) {
JohnTitor

comment created time in a month

delete branch matthewjasper/rust

delete branch : type-flags

delete time in a month

pull request commentrust-lang/rust

Clean up TypeFlags

@bors r=cramertj

matthewjasper

comment created time in a month

push eventmatthewjasper/rust

Jonas Schievink

commit sha a859ca5c87ddfaa635fb4cacf8a41e04fd9b02e8

Fix `binary_heap::DrainSorted` drop leak on panics

view details

Jonas Schievink

commit sha 3e5eb2634cbb356b626e028a4be1305d4a44a023

Fix `VecDeque::truncate` leak on drop panic

view details

Jonas Schievink

commit sha 5d04790dd2e73f3faf08d528e3675e131585ec01

Avoid leak in `vec::Drain` when item drop panics

view details

Jonas Schievink

commit sha dc492452dae29d75b14afe3559f5fb59be7f2d3a

Fix leak in btree_map::IntoIter when drop panics

view details

Jonas Schievink

commit sha b04ca13873d5ef5e5b18195aaf8925562302e8e0

Fix leak in VecDeque::drain when drop panics

view details

Jonas Schievink

commit sha 163ed23f0081d7283ccaef39141bc29879260663

Fix leak in vec::IntoIter when a destructor panics

view details

Jonas Schievink

commit sha 0ae16b47ffee866ee49f909ea213a28d8068cf56

Avoid leak in DrainFilter when a drop panics

view details

Jonas Schievink

commit sha 1f373f4aeb279c6bf98976aee419db967c4f56f6

Add test for panic in LL DrainFilter predicate

view details

Jonas Schievink

commit sha 75f721df97fd7895b31a1d8c9ed05a368fc95d6d

Move VecDeque Drain iterator to new file

view details

Jonas Schievink

commit sha 52d6c90488abdd12a24c66f5e3490ae3136bb295

Update comments in `Drain`s `Drop` impl

view details

Jonas Schievink

commit sha e5987a062f487321bdfcbbdac4b0b30548258631

Format

view details

Andreas Molzer

commit sha 14999dd74b38ca79b80772f4f33425574faff89a

Add methods to leak RefCell borrows to references Usually, references to the interior are only created by the `Deref` and `DerefMut` impl of the guards `Ref` and `RefMut`. Note that `RefCell` already has to cope with leaks of such guards which, when it occurs, effectively makes it impossible to ever acquire a mutable guard or any guard for `Ref` and `RefMut` respectively. It is already safe to use this to create a reference to the inner of the ref cell that lives as long as the reference to the `RefCell` itself, e.g. ```rust fn leak(r: &RefCell<usize>) -> Option<&usize> { let guard = r.try_borrow().ok()?; let leaked = Box::leak(Box::new(guard)); Some(&*leaked) } ``` The newly added methods allow the same reference conversion without an indirection over a leaked allocation and composing with both borrow and try_borrow without additional method combinations.

view details

Mark Rousskov

commit sha 178de46116b4fc8c1d9b30007f5e5ed24c809881

Add primitive module to libcore/std This re-exports the primitive types from libcore at `core::primitive` to allow macro authors to have a reliable location to use them from.

view details

Dylan MacKenzie

commit sha b23d910d570b392b1740ef1bb888f04194fe82c1

Skip `Drop` terminators for enum variants without drop glue When doing drop elaboration for an `enum` that may or may not be moved out of (an open drop), we check the discriminant of the `enum` to see whether the live variant has any drop flags and then check the drop flags to see whether we need to drop each field. Sometimes, however, the live variant has no move paths. In this case, we still emit a drop terminator for the entire enum after checking the enum discriminant. This commit skips emitting the drop terminator when the "otherwise" variants, those without move paths, have no drop glue. This was frequently the case with `Option`, as the `None` variant has no drop glue and no move path.

view details

Stein Somers

commit sha b685985ea40ab1faa8cb888bf001779e44a8c716

Refine and extend benchmarks of mutable BTreeSet methods

view details

Dylan MacKenzie

commit sha f6d4720f26c92e9905c98b4ee2db832927e30a8a

Make `u8::is_ascii` a stable `const fn` `char::is_ascii` is already a stable `const fn`, so there is no reason for `u8::is_ascii` to be unstable.

view details

Dylan MacKenzie

commit sha bf732a11ecc319e0c0a840196bde1b5daccbdc85

Test `u8::is_ascii` alongside `char::is_ascii`

view details

Erin Power

commit sha 81e40278bd0ad707a3be2396a076f151d1ff1072

Update RELEASES.md for 1.42.0

view details

XAMPPRocky

commit sha 26fdcbbc2810474770bb7f87d410a1e34b142b87

Update RELEASES.md

view details

XAMPPRocky

commit sha 7ab01b24674b88ff4927b0eb445a582fb9e12aba

Update RELEASES.md Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>

view details

push time in a month

Pull request review commentrust-lang/rust

Fix warning for unused variables in or pattern (issue #67691)

+error: unused variable: `j`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:20:16+   |+LL |         A { i, j } | B { i, j } => {+   |                ^            ^+   |+note: the lint level is defined here+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:4:9+   |+LL | #![deny(unused)]+   |         ^^^^^^+   = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`+help: try ignoring the field+   |+LL |         A { i, j: _ } | B { i, j: _ } => {+   |                ^^^^            ^^^^++error: unused variable: `j`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:30:16+   |+LL |         A { i, ref j } | B { i, ref j } => {+   |                ^^^^^            ^^^^^+   |+help: try ignoring the field+   |+LL |         A { i, j: _ } | B { i, j: _ } => {+   |                ^^^^            ^^^^++error: unused variable: `j`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:40:21+   |+LL |         Some(A { i, j } | B { i, j }) => {+   |                     ^            ^+   |+help: try ignoring the field+   |+LL |         Some(A { i, j: _ } | B { i, j: _ }) => {+   |                     ^^^^            ^^^^++error: unused variable: `j`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:52:21+   |+LL |         Some(A { i, ref j } | B { i, ref j }) => {+   |                     ^^^^^            ^^^^^+   |+help: try ignoring the field+   |+LL |         Some(A { i, j: _ } | B { i, j: _ }) => {+   |                     ^^^^            ^^^^++error: unused variable: `i`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:62:24+   |+LL |         MixedEnum::A { i } | MixedEnum::B(i) => {+   |                        ^                  ^+   |+help: try ignoring the field+   |+LL |         MixedEnum::A { i: _ } | MixedEnum::B(_i) => {+   |                        ^^^^                  ^^++error: unused variable: `i`+  --> $DIR/issue-67691-unused-field-in-or-pattern.rs:70:24+   |+LL |         MixedEnum::A { ref i } | MixedEnum::B(ref i) => {+   |                        ^^^^^                  ^^^^^+   |+help: try ignoring the field+   |+LL |         MixedEnum::A { i: _ } | MixedEnum::B(_i) => {

This should be suggesting MixedEnum::A { i: _ } | MixedEnum::B(_) or MixedEnum::A { i: ref _i } | MixedEnum::B(ref _i)

sapir

comment created time in a month

pull request commentrust-lang/rust

Use TypeRelating for instantiating query responses

r? @nikomatsakis

matthewjasper

comment created time in a month

pull request commentrust-lang/rust

[PERF] further drop changes

@bors try @rust-timer queue

matthewjasper

comment created time in a month

PR opened rust-lang/rust

Use TypeRelating for instantiating query responses

eq can add constraints to RegionConstraintData, which isn't allowed during borrow checking outside of a CustomTypeOp. Use TypeRelating instead to always push constraints to the obligations list.

closes #69490

+111 -7

0 comment

2 changed files

pr created time in a month

more