From 20446bd92bdd165ad23eef413b855a0be78285cc Mon Sep 17 00:00:00 2001 From: base0x10 Date: Fri, 10 Feb 2023 23:58:25 +0000 Subject: [PATCH 1/8] Update broken link in cargo style guide Toml now uses [toml.io](https://toml.io) for released specifications and the github repo for development. Also the old link was for the 0.4 specification, while cargo uses toml_edit, which uses toml 1.0 (reference: https://github.com/toml-rs/toml/blob/main/crates/toml_edit/CHANGELOG.md#030---2021-09-13). Finally the discussion of "Bare keys" vs "Quoted keys" has moved from the `#table` section to `#keys`. --- src/doc/style-guide/src/cargo.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index f4993ba06a888..13b96ca8c5e9d 100644 --- a/src/doc/style-guide/src/cargo.md +++ b/src/doc/style-guide/src/cargo.md @@ -17,8 +17,7 @@ followed by the `description` at the end of that section. Don't use quotes around any standard key names; use bare keys. Only use quoted keys for non-standard keys whose names require them, and avoid introducing such key names when possible. See the [TOML -specification](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md#table) -for details. +specification](https://toml.io/en/v1.0.0#keys) for details. Put a single space both before and after the `=` between a key and value. Do not indent any key names; start all key names at the start of a line. From f72eb4704a944c75c1eb1215bce6961fae3b3608 Mon Sep 17 00:00:00 2001 From: alesito85 Date: Mon, 13 Feb 2023 03:57:22 -0500 Subject: [PATCH 2/8] Add another error to Windows file open fallback Added another error to be processed in fallback Solution suggested by Chris Denton https://github.com/nushell/nushell/issues/6857#issuecomment-1426847135 --- library/std/src/sys/windows/fs.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index f1a784b5fd2e7..d2c597664fa78 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1266,7 +1266,12 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result { // If the fallback fails for any reason we return the original error. match File::open(path, &opts) { Ok(file) => file.file_attr(), - Err(e) if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _) => { + Err(e) + if [Some(c::ERROR_SHARING_VIOLATION as _), Some(c::ERROR_ACCESS_DENIED as _)] + .contains(&e.raw_os_error()) => + { + // `ERROR_ACCESS_DENIED` is returned when the user doesn't have permission for the resource. + // One such example is `System Volume Information` as default but can be created as well // `ERROR_SHARING_VIOLATION` will almost never be returned. // Usually if a file is locked you can still read some metadata. // However, there are special system files, such as From 2bdc9a046ae1b8f5e479d71a0d43eb313737c2af Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Fri, 10 Feb 2023 19:03:54 +0100 Subject: [PATCH 3/8] fix: improve the suggestion on future not awaited MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Considering the following code ```rust fn foo() -> u8 { async fn async_fn() -> u8 { 22 } async_fn() } fn main() {} ``` the error generated before this commit from the compiler is ``` ➜ rust git:(macros/async_fn_suggestion) ✗ rustc test.rs --edition 2021 error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type ... 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found opaque type | = note: expected type `u8` found opaque type `impl Future` help: consider `await`ing on the `Future` | 4 | async_fn().await | ++++++ error: aborting due to previous error ``` In this case the error is nor perfect, and can confuse the user that do not know that the opaque type is the future. So this commit will propose (and conclude the work start in https://github.com/rust-lang/rust/issues/80658) to change the string `opaque type` to `future` when applicable and also remove the Expected vs Received note by adding a more specific one regarding the async function that return a future type. So the new error emitted by the compiler is ``` error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type ... 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found future | note: calling an async function returns a future --> test.rs:4:5 | 4 | async_fn() | ^^^^^^^^^^ help: consider `await`ing on the `Future` | 4 | async_fn().await | ++++++ error: aborting due to previous error ``` Signed-off-by: Vincenzo Palazzo --- .../src/infer/error_reporting/mod.rs | 34 ++++++++++++++----- .../src/infer/error_reporting/suggest.rs | 31 +++++++---------- compiler/rustc_middle/src/ty/error.rs | 2 +- .../dont-suggest-missing-await.stderr | 9 +++-- tests/ui/async-await/generator-desc.stderr | 4 +-- ...nc-example-desugared-boxed-in-trait.stderr | 2 +- tests/ui/async-await/issue-61076.rs | 2 +- tests/ui/async-await/issue-61076.stderr | 2 +- tests/ui/async-await/issue-98634.stderr | 12 ++----- .../ui/async-await/issues/issue-102206.stderr | 4 +-- .../suggest-missing-await-closure.stderr | 9 +++-- .../async-await/suggest-missing-await.stderr | 28 +++++++++------ tests/ui/impl-trait/issue-102605.stderr | 9 +++-- tests/ui/impl-trait/issue-99914.stderr | 4 +-- tests/ui/suggestions/if-then-neeing-semi.rs | 11 +++--- .../ui/suggestions/if-then-neeing-semi.stderr | 24 +++++++------ tests/ui/suggestions/issue-81839.stderr | 5 +-- .../match-prev-arm-needing-semi.rs | 11 +++--- .../match-prev-arm-needing-semi.stderr | 24 +++++++------ tests/ui/suggestions/opaque-type-error.stderr | 8 ++--- .../type-alias-impl-trait/issue-98604.stderr | 4 +-- ...ue-90027-async-fn-return-suggestion.stderr | 9 +++-- 22 files changed, 132 insertions(+), 116 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 88a0d6def5ec2..94f742f2b0ae3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1783,14 +1783,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } })) { - diag.note_expected_found_extra( - &expected_label, - expected, - &found_label, - found, - &sort_string(values.expected, exp_p), - &sort_string(values.found, found_p), - ); + if let Some(ExpectedFound { found: found_ty, .. }) = exp_found { + // `Future` is a special opaque type that the compiler + // will try to hide in some case such as `async fn`, so + // to make an error more use friendly we will + // avoid to suggest a mismatch type with a + // type that the user usually are not usign + // directly such as `impl Future`. + if !self.tcx.ty_is_opaque_future(found_ty) { + diag.note_expected_found_extra( + &expected_label, + expected, + &found_label, + found, + &sort_string(values.expected, exp_p), + &sort_string(values.found, found_p), + ); + } + } } } _ => { @@ -2854,6 +2864,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> { pub enum TyCategory { Closure, Opaque, + OpaqueFuture, Generator(hir::GeneratorKind), Foreign, } @@ -2863,6 +2874,7 @@ impl TyCategory { match self { Self::Closure => "closure", Self::Opaque => "opaque type", + Self::OpaqueFuture => "future", Self::Generator(gk) => gk.descr(), Self::Foreign => "foreign type", } @@ -2871,7 +2883,11 @@ impl TyCategory { pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> { match *ty.kind() { ty::Closure(def_id, _) => Some((Self::Closure, def_id)), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => Some((Self::Opaque, def_id)), + ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { + let kind = + if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque }; + Some((kind, def_id)) + } ty::Generator(def_id, ..) => { Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id)) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 73859aca42478..7d9a53d1c025f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -238,31 +238,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - diag.span_suggestion_verbose( - exp_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, exp_span); + diag.span_note(exp_span, "calling an async function returns a future"); } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() { ObligationCauseCode::Pattern { span: Some(then_span), .. } => { - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, then_span.shrink_to_hi()); } ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, then_span.shrink_to_hi()); } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { ref prior_arms, @@ -283,6 +269,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } + pub fn suggest_await_on_future(&self, diag: &mut Diagnostic, sp: Span) { + diag.span_suggestion_verbose( + sp.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + pub(super) fn suggest_accessing_field_where_appropriate( &self, cause: &ObligationCause<'tcx>, diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index bd78705cdb59b..9c171a69d064f 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -271,7 +271,7 @@ impl<'tcx> Ty<'tcx> { ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Alias(ty::Projection, _) => "associated type".into(), ty::Param(p) => format!("type parameter `{p}`").into(), - ty::Alias(ty::Opaque, ..) => "opaque type".into(), + ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() }, ty::Error(_) => "type error".into(), _ => { let width = tcx.sess.diagnostic_width(); diff --git a/tests/ui/async-await/dont-suggest-missing-await.stderr b/tests/ui/async-await/dont-suggest-missing-await.stderr index 8e2d42c8f138c..1fa4e5db0cbbc 100644 --- a/tests/ui/async-await/dont-suggest-missing-await.stderr +++ b/tests/ui/async-await/dont-suggest-missing-await.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/dont-suggest-missing-await.rs:14:18 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/dont-suggest-missing-await.rs:5:4 | diff --git a/tests/ui/async-await/generator-desc.stderr b/tests/ui/async-await/generator-desc.stderr index 9fdb1ce47d7ba..51ac9d86bfb47 100644 --- a/tests/ui/async-await/generator-desc.stderr +++ b/tests/ui/async-await/generator-desc.stderr @@ -17,12 +17,10 @@ error[E0308]: mismatched types --> $DIR/generator-desc.rs:12:16 | LL | fun(one(), two()); - | --- ^^^^^ expected opaque type, found a different opaque type + | --- ^^^^^ expected future, found a different future | | | arguments to this function are incorrect | - = note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>) - found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>) = help: consider `await`ing on both `Future`s = note: distinct uses of `impl Trait` result in different opaque types note: function defined here diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 3c01fca2f4d8d..168ef8e9ee4e7 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -2,7 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28 | LL | async fn foo(&self) -> i32 { - | ^^^ expected `Pin>>`, found opaque type + | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 diff --git a/tests/ui/async-await/issue-61076.rs b/tests/ui/async-await/issue-61076.rs index 9c4acbe0a5bf7..cf6e5b4e436f2 100644 --- a/tests/ui/async-await/issue-61076.rs +++ b/tests/ui/async-await/issue-61076.rs @@ -86,7 +86,7 @@ async fn match_() { match tuple() { //~ HELP consider `await`ing on the `Future` //~^ NOTE this expression has type `impl Future` Tuple(_) => {} //~ ERROR mismatched types - //~^ NOTE expected opaque type, found `Tuple` + //~^ NOTE expected future, found `Tuple` //~| NOTE expected opaque type `impl Future` } } diff --git a/tests/ui/async-await/issue-61076.stderr b/tests/ui/async-await/issue-61076.stderr index b25b29bf50c17..44de282988baa 100644 --- a/tests/ui/async-await/issue-61076.stderr +++ b/tests/ui/async-await/issue-61076.stderr @@ -62,7 +62,7 @@ LL | match tuple() { | ------- this expression has type `impl Future` LL | LL | Tuple(_) => {} - | ^^^^^^^^ expected opaque type, found `Tuple` + | ^^^^^^^^ expected future, found `Tuple` | = note: expected opaque type `impl Future` found struct `Tuple` diff --git a/tests/ui/async-await/issue-98634.stderr b/tests/ui/async-await/issue-98634.stderr index 4c5dfeed9ba5c..5b7f18a98b539 100644 --- a/tests/ui/async-await/issue-98634.stderr +++ b/tests/ui/async-await/issue-98634.stderr @@ -2,10 +2,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin $DIR/issue-98634.rs:45:23 | LL | StructAsync { callback }.await; - | ^^^^^^^^ expected `Pin>>`, found opaque type + | ^^^^^^^^ expected `Pin>>`, found future | - = note: expected struct `Pin + 'static)>>` - found opaque type `impl Future` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | @@ -16,10 +14,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin $DIR/issue-98634.rs:45:9 | LL | StructAsync { callback }.await; - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin>>`, found opaque type + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin>>`, found future | - = note: expected struct `Pin + 'static)>>` - found opaque type `impl Future` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | @@ -30,10 +26,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin $DIR/issue-98634.rs:45:33 | LL | StructAsync { callback }.await; - | ^^^^^^ expected `Pin>>`, found opaque type + | ^^^^^^ expected `Pin>>`, found future | - = note: expected struct `Pin + 'static)>>` - found opaque type `impl Future` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr index ebb80f6e07e74..750b7a886ef9a 100644 --- a/tests/ui/async-await/issues/issue-102206.stderr +++ b/tests/ui/async-await/issues/issue-102206.stderr @@ -4,12 +4,10 @@ error[E0308]: mismatched types LL | std::mem::size_of_val(foo()); | --------------------- ^^^^^ | | | - | | expected `&_`, found opaque type + | | expected `&_`, found future | | help: consider borrowing here: `&foo()` | arguments to this function are incorrect | - = note: expected reference `&_` - found opaque type `impl Future` note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL diff --git a/tests/ui/async-await/suggest-missing-await-closure.stderr b/tests/ui/async-await/suggest-missing-await-closure.stderr index e47325cb4aeae..d44af5b8dd832 100644 --- a/tests/ui/async-await/suggest-missing-await-closure.stderr +++ b/tests/ui/async-await/suggest-missing-await-closure.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/suggest-missing-await-closure.rs:16:18 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/suggest-missing-await-closure.rs:6:4 | diff --git a/tests/ui/async-await/suggest-missing-await.stderr b/tests/ui/async-await/suggest-missing-await.stderr index 4ed0272ac1a12..f0ec34a6a5557 100644 --- a/tests/ui/async-await/suggest-missing-await.stderr +++ b/tests/ui/async-await/suggest-missing-await.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/suggest-missing-await.rs:12:14 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/suggest-missing-await.rs:3:4 | @@ -22,10 +25,13 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:22:5 | LL | dummy() - | ^^^^^^^ expected `()`, found opaque type + | ^^^^^^^ expected `()`, found future | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/suggest-missing-await.rs:22:5 + | +LL | dummy() + | ^^^^^^^ help: consider `await`ing on the `Future` | LL | dummy().await @@ -45,7 +51,7 @@ LL | | dummy() LL | | LL | | } else { LL | | dummy().await - | | ^^^^^^^^^^^^^ expected opaque type, found `()` + | | ^^^^^^^^^^^^^ expected future, found `()` LL | | LL | | }; | |_____- `if` and `else` have incompatible types @@ -67,7 +73,7 @@ LL | | 0 => dummy(), LL | | 1 => dummy(), | | ------- this is found to be of type `impl Future` LL | | 2 => dummy().await, - | | ^^^^^^^^^^^^^ expected opaque type, found `()` + | | ^^^^^^^^^^^^^ expected future, found `()` LL | | LL | | }; | |_____- `match` arms have incompatible types @@ -86,7 +92,7 @@ error[E0308]: mismatched types LL | let _x = match dummy() { | ------- this expression has type `impl Future` LL | () => {} - | ^^ expected opaque type, found `()` + | ^^ expected future, found `()` | = note: expected opaque type `impl Future` found unit type `()` @@ -102,7 +108,7 @@ LL | match dummy_result() { | -------------- this expression has type `impl Future>` ... LL | Ok(_) => {} - | ^^^^^ expected opaque type, found `Result<_, _>` + | ^^^^^ expected future, found `Result<_, _>` | = note: expected opaque type `impl Future>` found enum `Result<_, _>` @@ -118,7 +124,7 @@ LL | match dummy_result() { | -------------- this expression has type `impl Future>` ... LL | Err(_) => {} - | ^^^^^^ expected opaque type, found `Result<_, _>` + | ^^^^^^ expected future, found `Result<_, _>` | = note: expected opaque type `impl Future>` found enum `Result<_, _>` diff --git a/tests/ui/impl-trait/issue-102605.stderr b/tests/ui/impl-trait/issue-102605.stderr index 8ff08968008bb..dfe18e43eeea1 100644 --- a/tests/ui/impl-trait/issue-102605.stderr +++ b/tests/ui/impl-trait/issue-102605.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-102605.rs:13:20 | LL | convert_result(foo()) - | -------------- ^^^^^ expected `Result<(), _>`, found opaque type + | -------------- ^^^^^ expected `Result<(), _>`, found future | | | arguments to this function are incorrect | - = note: expected enum `Result<(), _>` - found opaque type `impl Future>` +note: calling an async function returns a future + --> $DIR/issue-102605.rs:13:20 + | +LL | convert_result(foo()) + | ^^^^^ note: function defined here --> $DIR/issue-102605.rs:7:4 | diff --git a/tests/ui/impl-trait/issue-99914.stderr b/tests/ui/impl-trait/issue-99914.stderr index a4b7fc1f5bc75..c86e9eadc87cb 100644 --- a/tests/ui/impl-trait/issue-99914.stderr +++ b/tests/ui/impl-trait/issue-99914.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-99914.rs:9:27 | LL | t.and_then(|t| -> _ { bar(t) }); - | ^^^^^^ expected `Result<_, Error>`, found opaque type + | ^^^^^^ expected `Result<_, Error>`, found future | - = note: expected enum `Result<_, Error>` - found opaque type `impl Future` help: try wrapping the expression in `Ok` | LL | t.and_then(|t| -> _ { Ok(bar(t)) }); diff --git a/tests/ui/suggestions/if-then-neeing-semi.rs b/tests/ui/suggestions/if-then-neeing-semi.rs index 7be4312bfbacb..a4eefb41508fa 100644 --- a/tests/ui/suggestions/if-then-neeing-semi.rs +++ b/tests/ui/suggestions/if-then-neeing-semi.rs @@ -26,8 +26,8 @@ async fn async_extra_semicolon_same() { //~^ HELP consider removing this semicolon } else { async_dummy() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -39,8 +39,8 @@ async fn async_extra_semicolon_different() { //~^ HELP consider removing this semicolon } else { async_dummy2() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -52,8 +52,7 @@ async fn async_different_futures() { //~| HELP consider `await`ing on both `Future`s } else { async_dummy2() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected opaque type `impl Future` + //~^ NOTE expected future, found a different future //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/tests/ui/suggestions/if-then-neeing-semi.stderr b/tests/ui/suggestions/if-then-neeing-semi.stderr index 567deb405fccd..6833e0bab2b83 100644 --- a/tests/ui/suggestions/if-then-neeing-semi.stderr +++ b/tests/ui/suggestions/if-then-neeing-semi.stderr @@ -9,14 +9,17 @@ LL | | async_dummy(); LL | | LL | | } else { LL | | async_dummy() - | | ^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/if-then-neeing-semi.rs:28:9 + | +LL | async_dummy() + | ^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | async_dummy().await @@ -38,14 +41,17 @@ LL | | async_dummy(); LL | | LL | | } else { LL | | async_dummy2() - | | ^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/if-then-neeing-semi.rs:41:9 + | +LL | async_dummy2() + | ^^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | async_dummy2().await @@ -69,14 +75,12 @@ LL | | async_dummy() LL | | LL | | } else { LL | | async_dummy2() - | | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type -... | + | | ^^^^^^^^^^^^^^ expected future, found a different future +LL | | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected opaque type `impl Future` (opaque type at <$DIR/if-then-neeing-semi.rs:18:24>) - found opaque type `impl Future` (opaque type at <$DIR/if-then-neeing-semi.rs:20:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/suggestions/issue-81839.stderr b/tests/ui/suggestions/issue-81839.stderr index 4af7cc9f8ec80..6d0a0c7b3faa2 100644 --- a/tests/ui/suggestions/issue-81839.stderr +++ b/tests/ui/suggestions/issue-81839.stderr @@ -10,12 +10,9 @@ LL | | cx.answer_str("hi"); | | this is found to be of type `()` LL | | } LL | | _ => cx.answer_str("hi"), - | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found future LL | | } | |_____- `match` arms have incompatible types - | - = note: expected unit type `()` - found opaque type `impl Future` error: aborting due to previous error diff --git a/tests/ui/suggestions/match-prev-arm-needing-semi.rs b/tests/ui/suggestions/match-prev-arm-needing-semi.rs index 3f863cb104e0b..11463c453d407 100644 --- a/tests/ui/suggestions/match-prev-arm-needing-semi.rs +++ b/tests/ui/suggestions/match-prev-arm-needing-semi.rs @@ -24,8 +24,8 @@ async fn async_extra_semicolon_same() { //~^ HELP consider removing this semicolon } false => async_dummy(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -37,8 +37,8 @@ async fn async_extra_semicolon_different() { //~^ HELP consider removing this semicolon } false => async_dummy2(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -48,8 +48,7 @@ async fn async_different_futures() { true => async_dummy(), //~ NOTE this is found to be //~| HELP consider `await`ing on both `Future`s false => async_dummy2(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected opaque type `impl Future` + //~^ NOTE expected future, found a different future //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr index df18c7b0b23cc..cf3cf45ef402a 100644 --- a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -9,14 +9,17 @@ LL | | async_dummy(); LL | | LL | | } LL | | false => async_dummy(), - | | ^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/match-prev-arm-needing-semi.rs:26:18 + | +LL | false => async_dummy(), + | ^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | false => async_dummy().await, @@ -38,14 +41,17 @@ LL | | async_dummy(); LL | | LL | | } LL | | false => async_dummy2(), - | | ^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/match-prev-arm-needing-semi.rs:39:18 + | +LL | false => async_dummy2(), + | ^^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | false => async_dummy2().await, @@ -67,14 +73,12 @@ LL | | true => async_dummy(), | | ------------- this is found to be of type `impl Future` LL | | LL | | false => async_dummy2(), - | | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type -... | + | | ^^^^^^^^^^^^^^ expected future, found a different future +LL | | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) - found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:18:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/suggestions/opaque-type-error.stderr b/tests/ui/suggestions/opaque-type-error.stderr index 133ffb0587392..5c90d3012abf9 100644 --- a/tests/ui/suggestions/opaque-type-error.stderr +++ b/tests/ui/suggestions/opaque-type-error.stderr @@ -2,22 +2,20 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | LL | fn thing_one() -> impl Future> { - | ------------------------------------ the expected opaque type + | ------------------------------------ the expected future ... LL | fn thing_two() -> impl Future> { - | ------------------------------------ the found opaque type + | ------------------------------------ the found future ... LL | / if true { LL | | thing_one() | | ----------- expected because of this LL | | } else { LL | | thing_two() - | | ^^^^^^^^^^^ expected opaque type, found a different opaque type + | | ^^^^^^^^^^^ expected future, found a different future LL | | }.await | |_____- `if` and `else` have incompatible types | - = note: expected opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) - found opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr index bb9dd2365ea0d..fa16d321890cc 100644 --- a/tests/ui/type-alias-impl-trait/issue-98604.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr @@ -2,10 +2,8 @@ error[E0271]: expected `test` to be a fn item that returns `Pin $DIR/issue-98604.rs:9:5 | LL | Box::new(test) as AsyncFnPtr; - | ^^^^^^^^^^^^^^ expected `Pin>>`, found opaque type + | ^^^^^^^^^^^^^^ expected `Pin>>`, found future | - = note: expected struct `Pin + 'static)>>` - found opaque type `impl Future` = note: required for the cast from `fn() -> impl Future {test}` to the object type `dyn Fn() -> Pin + 'static)>>` error: aborting due to previous error diff --git a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr index 6a1a9f45bc62b..0d72ae118f3aa 100644 --- a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr +++ b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr @@ -18,10 +18,13 @@ error[E0308]: mismatched types --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 | LL | hello() - | ^^^^^^^ expected `()`, found opaque type + | ^^^^^^^ expected `()`, found future | - = note: expected unit type `()` - found opaque type `impl Future` +note: calling an async function returns a future + --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 + | +LL | hello() + | ^^^^^^^ help: consider `await`ing on the `Future` | LL | hello().await From 9dcad5a340ea69f8aeb60d542d5a2b9acd54b2c6 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:01:05 -0500 Subject: [PATCH 4/8] Update books --- src/doc/book | 2 +- src/doc/embedded-book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/book b/src/doc/book index f2a78f64b668f..d94e03a18a259 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit f2a78f64b668f63f581203c6bac509903f7c00ee +Subproject commit d94e03a18a2590ed3f1c67b859cb11528d2a2d5c diff --git a/src/doc/embedded-book b/src/doc/embedded-book index f1a4614aa41cc..701d1551429da 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit f1a4614aa41cc544b91b79760a709e113f3451d7 +Subproject commit 701d1551429da4cb609082c0ac99df569e336710 diff --git a/src/doc/nomicon b/src/doc/nomicon index bd1829d235296..79b53665a7c61 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit bd1829d235296952bf72ca55635e360584b8805e +Subproject commit 79b53665a7c61d171fb8c5ad0b73b371f9ee6ba7 diff --git a/src/doc/reference b/src/doc/reference index 22882fb3f7b4d..e5adb99c04817 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d +Subproject commit e5adb99c04817b7fbe08f4ffce5b36702667345f diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 134376872e8c3..efe23c4fe12e0 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 134376872e8c387ef369507e0ee9b5a0e3272718 +Subproject commit efe23c4fe12e06351b8dc8c3d18312c761455109 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index e359ee27fc3da..41a96ab971cb4 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit e359ee27fc3da3356d71a732128c0a1abe02e53a +Subproject commit 41a96ab971cb45e2a184df20619ad1829765c990 From b10d744b87fcaaeea1a2ec2a299dba494c1f3d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 12 Feb 2023 15:59:57 +0800 Subject: [PATCH 5/8] Allow shortcuts to directories to be used for `./x.py fmt` Fixes #107944. Maximum recursive search depth is 3 and only accepts shortcuts for directories (single component paths, such as `./x.py fmt std`). If there are no shortcut candidates but single componenet path(s) are given, it falls back to the previous behavior to panic with unable to find directory. If there are multiple shortcut candidates for a given single component path, the shortcut candidates are considered ambiguous, are then ignored, and the single component path is accepted as-is. After this change, `./x.py fmt std` no longer panics and formats `library/std` instead. --- src/bootstrap/format.rs | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 6c9c26faef6aa..615794958d087 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -193,10 +193,46 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let (tx, rx): (SyncSender, _) = std::sync::mpsc::sync_channel(128); let walker = match paths.get(0) { Some(first) => { - let mut walker = WalkBuilder::new(first); + let find_shortcut_candidates = |p: &PathBuf| { + let mut candidates = Vec::new(); + for candidate in WalkBuilder::new(src.clone()).max_depth(Some(3)).build() { + if let Ok(entry) = candidate { + if let Some(dir_name) = p.file_name() { + if entry.path().is_dir() && entry.file_name() == dir_name { + candidates.push(entry.into_path()); + } + } + } + } + candidates + }; + + // Only try to look for shortcut candidates for single component paths like + // `std` and not for e.g. relative paths like `../library/std`. + let should_look_for_shortcut_dir = |p: &PathBuf| p.components().count() == 1; + + let mut walker = if should_look_for_shortcut_dir(first) { + if let [single_candidate] = &find_shortcut_candidates(first)[..] { + WalkBuilder::new(single_candidate) + } else { + WalkBuilder::new(first) + } + } else { + WalkBuilder::new(first) + }; + for path in &paths[1..] { - walker.add(path); + if should_look_for_shortcut_dir(path) { + if let [single_candidate] = &find_shortcut_candidates(path)[..] { + walker.add(single_candidate); + } else { + walker.add(path); + } + } else { + walker.add(path); + } } + walker } None => WalkBuilder::new(src.clone()), From e20f6ff1dcfaa90aad841f8d36734d1e70d2e065 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 23:17:38 +0000 Subject: [PATCH 6/8] Tighter spans for bad inherent impl types --- .../src/coherence/inherent_impls.rs | 33 ++++---- tests/ui/coherence/issue-85026.stderr | 8 +- .../const-generics/wrong-normalization.stderr | 4 +- tests/ui/error-codes/E0116.stderr | 2 +- tests/ui/error-codes/E0118.stderr | 4 +- tests/ui/error-codes/E0390.stderr | 8 +- tests/ui/impl-trait/where-allowed.stderr | 4 +- .../needs-has-incoherent-impls.stderr | 78 ++++++------------- .../no-attr-empty-impl.stderr | 12 +-- tests/ui/kinds-of-primitive-impl.stderr | 16 ++-- .../private-in-public-ill-formed.stderr | 8 +- .../traits/trait-or-new-type-instead.stderr | 7 +- 12 files changed, 74 insertions(+), 110 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c1b0237b2d1f1..940a450101ca0 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -57,7 +57,7 @@ const ADD_ATTR: &str = "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items"; impl<'tcx> InherentCollect<'tcx> { - fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) { + fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) { let impl_def_id = item.owner_id; if let Some(def_id) = def_id.as_local() { // Add the implementation to the mapping from implementation to base @@ -76,12 +76,12 @@ impl<'tcx> InherentCollect<'tcx> { if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { struct_span_err!( self.tcx.sess, - item.span, + span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(item.span, ADD_ATTR_TO_TY) + .span_help(span, ADD_ATTR_TO_TY) .emit(); return; } @@ -93,12 +93,12 @@ impl<'tcx> InherentCollect<'tcx> { { struct_span_err!( self.tcx.sess, - item.span, + span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(impl_item.span, ADD_ATTR) + .span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR) .emit(); return; } @@ -112,12 +112,12 @@ impl<'tcx> InherentCollect<'tcx> { } else { struct_span_err!( self.tcx.sess, - item.span, + span, E0116, "cannot define inherent `impl` for a type outside of the crate \ where the type is defined" ) - .span_label(item.span, "impl for type defined outside of crate.") + .span_label(span, "impl for type defined outside of crate.") .note("define and implement a trait or new type instead") .emit(); } @@ -182,29 +182,30 @@ impl<'tcx> InherentCollect<'tcx> { } let item = self.tcx.hir().item(id); - let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items, .. }) = item.kind else { + let impl_span = self.tcx.hir().span(id.hir_id()); + let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else { return; }; let self_ty = self.tcx.type_of(item.owner_id); match *self_ty.kind() { ty::Adt(def, _) => { - self.check_def_id(item, self_ty, def.did()); + self.check_def_id(item, self_ty, def.did(), impl_span); } ty::Foreign(did) => { - self.check_def_id(item, self_ty, did); + self.check_def_id(item, self_ty, did, impl_span); } ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { - self.check_def_id(item, self_ty, data.principal_def_id().unwrap()); + self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span); } ty::Dynamic(..) => { struct_span_err!( self.tcx.sess, - ty.span, + impl_span, E0785, "cannot define inherent `impl` for a dyn auto trait" ) - .span_label(ty.span, "impl requires at least one non-auto trait") + .span_label(impl_span, "impl requires at least one non-auto trait") .note("define and implement a new trait or type instead") .emit(); } @@ -221,17 +222,17 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Never | ty::FnPtr(_) | ty::Tuple(..) => { - self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span) + self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span) } ty::Alias(..) | ty::Param(_) => { let mut err = struct_span_err!( self.tcx.sess, - ty.span, + impl_span, E0118, "no nominal type found for inherent implementation" ); - err.span_label(ty.span, "impl requires a nominal type") + err.span_label(impl_span, "impl requires a nominal type") .note("either implement a trait on it or create a newtype to wrap it instead"); err.emit(); diff --git a/tests/ui/coherence/issue-85026.stderr b/tests/ui/coherence/issue-85026.stderr index a5da19bbfaa47..fb6e9976583b2 100644 --- a/tests/ui/coherence/issue-85026.stderr +++ b/tests/ui/coherence/issue-85026.stderr @@ -1,16 +1,16 @@ error[E0785]: cannot define inherent `impl` for a dyn auto trait - --> $DIR/issue-85026.rs:5:6 + --> $DIR/issue-85026.rs:5:1 | LL | impl dyn AutoTrait {} - | ^^^^^^^^^^^^^ impl requires at least one non-auto trait + | ^^^^^^^^^^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead error[E0785]: cannot define inherent `impl` for a dyn auto trait - --> $DIR/issue-85026.rs:8:6 + --> $DIR/issue-85026.rs:8:1 | LL | impl dyn Unpin {} - | ^^^^^^^^^ impl requires at least one non-auto trait + | ^^^^^^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr index fb806bdb1e747..658a840660876 100644 --- a/tests/ui/const-generics/wrong-normalization.stderr +++ b/tests/ui/const-generics/wrong-normalization.stderr @@ -1,8 +1,8 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/wrong-normalization.rs:16:6 + --> $DIR/wrong-normalization.rs:16:1 | LL | impl as Identity>::Identity { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/error-codes/E0116.stderr b/tests/ui/error-codes/E0116.stderr index a5ceeb4a55d81..8a02768676084 100644 --- a/tests/ui/error-codes/E0116.stderr +++ b/tests/ui/error-codes/E0116.stderr @@ -2,7 +2,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/E0116.rs:1:1 | LL | impl Vec {} - | ^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead diff --git a/tests/ui/error-codes/E0118.stderr b/tests/ui/error-codes/E0118.stderr index 8c6fa7947a853..442f8a4f870f2 100644 --- a/tests/ui/error-codes/E0118.stderr +++ b/tests/ui/error-codes/E0118.stderr @@ -1,8 +1,8 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/E0118.rs:1:9 + --> $DIR/E0118.rs:1:1 | LL | impl T { - | ^ impl requires a nominal type + | ^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/error-codes/E0390.stderr b/tests/ui/error-codes/E0390.stderr index 0e5a9ca762b76..ec4b5758c5b78 100644 --- a/tests/ui/error-codes/E0390.stderr +++ b/tests/ui/error-codes/E0390.stderr @@ -1,16 +1,16 @@ error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/E0390.rs:5:6 + --> $DIR/E0390.rs:5:1 | LL | impl *mut Foo {} - | ^^^^^^^^ + | ^^^^^^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/E0390.rs:7:6 + --> $DIR/E0390.rs:7:1 | LL | impl fn(Foo) {} - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: consider using an extension trait instead diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 3ad0a9f9d5c8b..e3a9caa646026 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -303,10 +303,10 @@ LL | fn in_method_generic_param_default(_: T) {} = note: for more information, see issue #36887 error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:233:23 + --> $DIR/where-allowed.rs:233:1 | LL | impl T {} - | ^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr b/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr index 8f70825115dd3..f5900afe2dcd1 100644 --- a/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr +++ b/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr @@ -1,114 +1,80 @@ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:5:1 | -LL | / impl extern_crate::StructWithAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructWithAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:7:5 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:13:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:13:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:17:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:17:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:22:1 | -LL | / impl extern_crate::EnumWithAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumWithAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:24:5 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:30:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:30:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:34:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:34:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr index b3f8b51d0ea8b..6dc1680cf89f8 100644 --- a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr +++ b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr @@ -2,7 +2,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:4:1 | LL | impl extern_crate::StructWithAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -10,7 +10,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:7:1 | LL | impl extern_crate::StructNoAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -18,7 +18,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:10:1 | LL | impl extern_crate::EnumWithAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -26,15 +26,15 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:13:1 | LL | impl extern_crate::EnumNoAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/no-attr-empty-impl.rs:16:6 + --> $DIR/no-attr-empty-impl.rs:16:1 | LL | impl f32 {} - | ^^^ + | ^^^^^^^^ | = help: consider using an extension trait instead diff --git a/tests/ui/kinds-of-primitive-impl.stderr b/tests/ui/kinds-of-primitive-impl.stderr index f4dbd1c40e818..21aac58f1f20b 100644 --- a/tests/ui/kinds-of-primitive-impl.stderr +++ b/tests/ui/kinds-of-primitive-impl.stderr @@ -1,32 +1,32 @@ error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:1:6 + --> $DIR/kinds-of-primitive-impl.rs:1:1 | LL | impl u8 { - | ^^ + | ^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:6:6 + --> $DIR/kinds-of-primitive-impl.rs:6:1 | LL | impl str { - | ^^^ + | ^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:12:6 + --> $DIR/kinds-of-primitive-impl.rs:12:1 | LL | impl char { - | ^^^^ + | ^^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:21:6 + --> $DIR/kinds-of-primitive-impl.rs:21:1 | LL | impl &MyType { - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: consider using an extension trait instead = note: you could also try moving the reference to uses of `MyType` (such as `self`) within the implementation diff --git a/tests/ui/privacy/private-in-public-ill-formed.stderr b/tests/ui/privacy/private-in-public-ill-formed.stderr index e7c94bc301bdf..abc8538e5b330 100644 --- a/tests/ui/privacy/private-in-public-ill-formed.stderr +++ b/tests/ui/privacy/private-in-public-ill-formed.stderr @@ -1,16 +1,16 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/private-in-public-ill-formed.rs:14:10 + --> $DIR/private-in-public-ill-formed.rs:14:5 | LL | impl ::AssocAlias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead error[E0118]: no nominal type found for inherent implementation - --> $DIR/private-in-public-ill-formed.rs:31:10 + --> $DIR/private-in-public-ill-formed.rs:31:5 | LL | impl ::AssocAlias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/traits/trait-or-new-type-instead.stderr b/tests/ui/traits/trait-or-new-type-instead.stderr index 4726b0668e516..6fd8a03fd8fed 100644 --- a/tests/ui/traits/trait-or-new-type-instead.stderr +++ b/tests/ui/traits/trait-or-new-type-instead.stderr @@ -1,11 +1,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/trait-or-new-type-instead.rs:1:1 | -LL | / impl Option { -LL | | -LL | | pub fn foo(&self) { } -LL | | } - | |_^ impl for type defined outside of crate. +LL | impl Option { + | ^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead From 614df3fd5eb83163b0cac65dc16eba35b7afe210 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 12 Feb 2023 14:37:09 -0500 Subject: [PATCH 7/8] Clearly document intentional UB in mir-opt tests Co-authored-by: Jakob Degen --- .../copy-prop/mutate_through_pointer.rs | 10 ++++ .../sibling_ptr.main.DataflowConstProp.diff | 2 +- .../dataflow-const-prop/sibling_ptr.rs | 9 +++- ...scaping.ScalarReplacementOfAggregates.diff | 48 +++++++++---------- tests/mir-opt/sroa.rs | 7 ++- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs index 609e49d6bc998..da142e33948ef 100644 --- a/tests/mir-opt/copy-prop/mutate_through_pointer.rs +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs @@ -1,3 +1,13 @@ +// This attempts to mutate `a` via a pointer derived from `addr_of!(a)`. That is UB +// according to Miri. However, the decision to make this UB - and to allow +// rustc to rely on that fact for the purpose of optimizations - has not been +// finalized. +// +// As such, we include this test to ensure that copy prop does not rely on that +// fact. Specifically, if `addr_of!(a)` could not be used to modify a, it would +// be correct for CopyProp to replace all occurrences of `a` with `c` - but that +// would cause `f(true)` to output `false` instead of `true`. + #![feature(custom_mir, core_intrinsics)] #![allow(unused_assignments)] extern crate core; diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff index a91a755830d15..004643e36f139 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff @@ -32,7 +32,7 @@ _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 _4 = ptr::mut_ptr::::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 // mir::Constant - // + span: $DIR/sibling_ptr.rs:8:12: 8:15 + // + span: $DIR/sibling_ptr.rs:15:12: 15:15 // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::::add}, val: Value() } } diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 87ef00d18295f..6dfb3a4ed3099 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -1,3 +1,10 @@ +// This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`. +// According to Miri, that is UB. However, T-opsem has not finalized that +// decision and as such we cannot rely on it in optimizations. Consequently, +// DataflowConstProp must treat the `addr_of_mut!(x.0)` as potentially being +// used to modify `x.1` - if it did not, then it might incorrectly assume that it +// can infer the value of `x.1` at the end of this function. + // unit-test: DataflowConstProp // EMIT_MIR sibling_ptr.main.DataflowConstProp.diff @@ -7,5 +14,5 @@ fn main() { let p = std::ptr::addr_of_mut!(x.0); *p.add(1) = 1; } - let x1 = x.1; // should not be propagated + let x1 = x.1; // should not be propagated } diff --git a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff index ea7f500722451..fd691fdd15332 100644 --- a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff @@ -3,42 +3,42 @@ fn escaping() -> () { let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 - let _1: (); // in scope 0 at $DIR/sroa.rs:+2:5: +2:42 - let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 - let _3: &u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 - let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+2:8: +2:39 - let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+2:34: +2:37 + let _1: (); // in scope 0 at $DIR/sroa.rs:+1:5: +1:42 + let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+1:7: +1:41 + let _3: &u32; // in scope 0 at $DIR/sroa.rs:+1:7: +1:41 + let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+1:8: +1:39 + let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+1:34: +1:37 bb0: { - StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:5: +2:42 - StorageLive(_2); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - StorageLive(_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39 - StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37 - _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37 + StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:5: +1:42 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:8: +1:39 + StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:34: +1:37 + _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+1:34: +1:37 // mir::Constant - // + span: $DIR/sroa.rs:73:34: 73:35 + // + span: $DIR/sroa.rs:78:34: 78:35 // + literal: Const { ty: fn() -> u32 {g}, val: Value() } } bb1: { - _4 = Escaping { a: const 1_u32, b: const 2_u32, c: move _5 }; // scope 0 at $DIR/sroa.rs:+2:8: +2:39 - StorageDead(_5); // scope 0 at $DIR/sroa.rs:+2:38: +2:39 - _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42 + _4 = Escaping { a: const 1_u32, b: const 2_u32, c: move _5 }; // scope 0 at $DIR/sroa.rs:+1:8: +1:39 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:38: +1:39 + _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+1:5: +1:42 // mir::Constant - // + span: $DIR/sroa.rs:73:5: 73:6 + // + span: $DIR/sroa.rs:78:5: 78:6 // + literal: Const { ty: fn(*const u32) {f}, val: Value() } } bb2: { - StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:41: +2:42 - StorageDead(_4); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - StorageDead(_3); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - StorageDead(_1); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +3:2 - return; // scope 0 at $DIR/sroa.rs:+3:2: +3:2 + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+1:41: +1:42 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + StorageDead(_1); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +2:2 + return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index 471aac9f9d82d..943520f2a5f95 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -68,8 +68,13 @@ fn f(a: *const u32) { println!("{}", unsafe { *a.add(2) }); } +// `f` uses the `&e.a` to access `e.c`. This is UB according to Miri today; however, +// T-opsem has not finalized that decision and as such rustc should not rely on +// it. If SROA were to rely on it, it would be (almost) correct to turn `e` into +// three distinct locals - one for each field - and pass a reference to only one +// of them to `f`. However, this would lead to a miscompilation because `b` and `c` +// might no longer appear right after `a` in memory. pub fn escaping() { - // Verify this struct is not flattened. f(&Escaping { a: 1, b: 2, c: g() }.a); } From a7b69ddea93f63a1e44e4c9ac8e7df264654498b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 13 Feb 2023 13:39:01 -0700 Subject: [PATCH 8/8] rustdoc: use a string with one-character codes for search index types $ wc -c search-index.old.js search-index.new.js 3940530 search-index.old.js 3843222 search-index.new.js ((3940530-3843222)/3940530)*100 = 2.47% $ wc -c search-index.old.js.gz search-index.new.js.gz 380251 search-index.old.js.gz 379434 search-index.new.js.gz ((380251-379434)/380251)*100 = 0.214% --- src/librustdoc/formats/item_type.rs | 1 + src/librustdoc/html/render/search_index.rs | 11 ++++++++++- src/librustdoc/html/static/js/search.js | 9 +++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 2f1f4cbf35924..aafedc17499a7 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -21,6 +21,7 @@ use crate::clean; /// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an /// ordering based on a helper function inside `item_module`, in the same file. #[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)] +#[repr(u8)] pub(crate) enum ItemType { Module = 0, ExternCrate = 1, diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 5b0caac099bc3..090ea2cb15763 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -236,7 +236,16 @@ pub(crate) fn build_index<'tcx>( crate_data.serialize_field("doc", &self.doc)?; crate_data.serialize_field( "t", - &self.items.iter().map(|item| &item.ty).collect::>(), + &self + .items + .iter() + .map(|item| { + let n = item.ty as u8; + let c = char::try_from(n + b'A').expect("item types must fit in ASCII"); + assert!(c <= 'z', "item types must fit within ASCII printables"); + c + }) + .collect::(), )?; crate_data.serialize_field( "n", diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index ea1875d8e27a9..1e6c94d29ba47 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1939,6 +1939,7 @@ function initSearch(rawSearchIndex) { * @type {Array} */ const searchWords = []; + const charA = "A".charCodeAt(0); let i, word; let currentIndex = 0; let id = 0; @@ -1953,7 +1954,7 @@ function initSearch(rawSearchIndex) { /** * The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f` * are arrays with the same length. n[i] contains the name of an item. - * t[i] contains the type of that item (as a small integer that represents an + * t[i] contains the type of that item (as a string of characters that represent an * offset in `itemTypes`). d[i] contains the description of that item. * * q[i] contains the full path of the item, or an empty string indicating @@ -1980,7 +1981,7 @@ function initSearch(rawSearchIndex) { * doc: string, * a: Object, * n: Array, - * t: Array, + * t: String, * d: Array, * q: Array, * i: Array, @@ -2009,7 +2010,7 @@ function initSearch(rawSearchIndex) { searchIndex.push(crateRow); currentIndex += 1; - // an array of (Number) item types + // a String of one character item type codes const itemTypes = crateCorpus.t; // an array of (String) item names const itemNames = crateCorpus.n; @@ -2060,7 +2061,7 @@ function initSearch(rawSearchIndex) { } const row = { crate: crate, - ty: itemTypes[i], + ty: itemTypes.charCodeAt(i) - charA, name: itemNames[i], path: itemPaths[i] ? itemPaths[i] : lastPath, desc: itemDescs[i],