From b551730cd6be9c46d795d9b12a5f932ff2374eca Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 21 Jun 2023 16:18:52 -0700 Subject: [PATCH 1/8] style-guide: Rewrite let-else section for clarity, without changing formatting The section as written did not cover all cases, and left some of them implicit. Rewrite it to systematically cover all cases. Place examples immediately following the corresponding case. In the process, reorder to move the simplest cases first: start with single-line and add progressively more line breaks. This does not change the meaning of the section at all, and in particular does not change the defined style for let-else statements. --- src/doc/style-guide/src/statements.md | 105 +++++++++++++++----------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index 671e6d31a5775..b6708e6c72a58 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -101,22 +101,69 @@ let Foo { #### else blocks (let-else statements) -If a let statement contains an `else` component, also known as a let-else statement, -then the `else` component should be formatted according to the same rules as the `else` block -in [control flow expressions (i.e. if-else, and if-let-else expressions)](./expressions.md#control-flow-expressions). -Apply the same formatting rules to the components preceding -the `else` block (i.e. the `let pattern: Type = initializer_expr ...` portion) -as described [above](#let-statements) - -Similarly to if-else expressions, if the initializer -expression is multi-lined, then the `else` keyword and opening brace of the block (i.e. `else {`) -should be put on the same line as the end of the initializer -expression with a preceding space if all the following are true: +A let statement can contain an `else` component, making it a let-else statement. +In this case, always apply the same formatting rules to the components preceding +the `else` block (i.e. the `let pattern: Type = initializer_expr` portion) +as described [for other let statements](#let-statements). + +The entire let-else statement may be formatted on a single line if all the +following are true: + +* the entire statement is *short* +* the `else` block contains only a single-line expression and no statements +* the `else` block contains no comments +* the let statement components preceding the `else` block can be formatted on a single line + +```rust +let Some(1) = opt else { return }; +``` + +Formatters may allow users to configure the value of the threshold +used to determine whether a let-else statement is *short*. + +Otherwise, the let-else statement requires some line breaks. + +If breaking a let-else statement across multiple lines, never break between the +`else` and the `{`, and always break before the `}`. + +If the let statement components preceding the `else` can be formatted on a +single line, but the let-else does not qualify to be placed entirely on a +single line, put the `else {` on the same line as the initializer expression, +with a space between them, then break the line after the `{`. Indent the +closing `}` to match the `let`, and indent the contained block one step +further. + +```rust +let Some(1) = opt else { + return; +}; + +let Some(1) = opt else { + // nope + return +}; +``` + +If the let statement components preceding the `else` can be formatted on a +single line, but the `else {` does not fit on the same line, break the line +before the `else`. + +```rust + let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name + else { + return; + }; +``` + +If the initializer expression is multi-line, the `else` keyword and opening +brace of the block (i.e. `else {`) should be put on the same line as the end of +the initializer expression, with a space between them, if all the following are +true: * The initializer expression ends with one or more closing parentheses, square brackets, and/or braces * There is nothing else on that line -* That line is not indented beyond the indent of the first line containing the `let` keyword +* That line has the same indentation level as the initial `let` keyword. For example: @@ -133,7 +180,9 @@ let Some(x) = y.foo( } ``` -Otherwise, the `else` keyword and opening brace should be placed on the next line after the end of the initializer expression, and should not be indented (the `else` keyword should be aligned with the `let` keyword). +Otherwise, the `else` keyword and opening brace should be placed on the next +line after the end of the initializer expression, and the `else` keyword should +have the same indentation level as the `let` keyword. For example: @@ -153,11 +202,6 @@ fn main() { return }; - let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name - else { - return; - }; - let Some(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb else { @@ -166,31 +210,6 @@ fn main() { } ``` -##### Single line let-else statements - -The entire let-else statement may be formatted on a single line if all the following are true: - -* the entire statement is *short* -* the `else` block contains a single-line expression and no statements -* the `else` block contains no comments -* the let statement components preceding the `else` block can be formatted on a single line - -```rust -let Some(1) = opt else { return }; - -let Some(1) = opt else { - return; -}; - -let Some(1) = opt else { - // nope - return -}; -``` - -Formatters may allow users to configure the value of the threshold -used to determine whether a let-else statement is *short*. - ### Macros in statement position A macro use in statement position should use parentheses or square brackets as From e5e480504f1dffff5f05e07de47234c14547512d Mon Sep 17 00:00:00 2001 From: Preveen P <31464911+preveen-stack@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:59:31 +0530 Subject: [PATCH 2/8] Update runtests.py : grammar correction --- src/etc/test-float-parse/runtests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/test-float-parse/runtests.py b/src/etc/test-float-parse/runtests.py index cf7279534dc86..cc5e31a051fc2 100755 --- a/src/etc/test-float-parse/runtests.py +++ b/src/etc/test-float-parse/runtests.py @@ -127,7 +127,7 @@ def write_errors(): if not have_seen_error: have_seen_error = True msg("Something is broken:", *args) - msg("Future errors logged to errors.txt") + msg("Future errors will be logged to errors.txt") exit_status = 101 From 5a0c8e3a08245166c4f922787647641411a9c445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 23 Jun 2023 18:47:13 +0200 Subject: [PATCH 3/8] issue template: add clippy entry which points to the clippy repo --- .github/ISSUE_TEMPLATE/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7d4cfaece4481..a2878a0e01208 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -6,3 +6,6 @@ contact_links: - name: Feature Request url: https://internals.rust-lang.org/ about: Please discuss language feature requests on the internals forum. + - name: Clippy Bug + url: https://github.com/rust-lang/rust-clippy/issues/new/choose + about: Please report Clippy bugs such as false positives in the Clippy repo. From 13cc8dd580eea454e7fde2331c60c62eb7c9fe80 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 24 Jun 2023 14:27:58 +0900 Subject: [PATCH 4/8] Add a regression test for #109141 Signed-off-by: Yuki Okushi --- .../generic_const_exprs/issue-109141.rs | 13 ++++++++++ .../generic_const_exprs/issue-109141.stderr | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-109141.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-109141.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs new file mode 100644 index 0000000000000..148c3bda8d287 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs @@ -0,0 +1,13 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +impl EntriesBuffer { + fn a(&self) -> impl Iterator { + self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference + } +} + +struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); +//~^ ERROR: cannot find value `HashesEntryLEN` in this scope + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr new file mode 100644 index 0000000000000..f61edd60e3b65 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr @@ -0,0 +1,26 @@ +error[E0425]: cannot find value `HashesEntryLEN` in this scope + --> $DIR/issue-109141.rs:10:32 + | +LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); + | ^^^^^^^^^^^^^^ not found in this scope + | +help: you might be missing a const parameter + | +LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); + | ++++++++++++++++++++++++++++++++++ + +error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference + --> $DIR/issue-109141.rs:6:9 + | +LL | self.0.iter_mut() + | ^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | +help: consider changing this to be a mutable reference + | +LL | fn a(&mut self) -> impl Iterator { + | ~~~~~~~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0425, E0596. +For more information about an error, try `rustc --explain E0425`. From a72013f7f039ddf9d248e2194ea87c9e40213e34 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 16 Jun 2023 12:33:11 +0000 Subject: [PATCH 5/8] instantiate hidden types in root universe --- compiler/rustc_borrowck/src/type_check/mod.rs | 5 +- compiler/rustc_infer/src/infer/mod.rs | 1 + .../member-constraints-in-root-universe.rs | 17 ++++++ .../normalize-hidden-types.current.stderr | 55 +++++++++++++++++ .../normalize-hidden-types.rs | 60 +++++++++++++++++++ 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/new-solver/member-constraints-in-root-universe.rs create mode 100644 tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/normalize-hidden-types.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 00fd3762fa773..d9abe53c238b0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -50,7 +50,6 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; -use crate::renumber::RegionCtxt; use crate::session_diagnostics::MoveUnsized; use crate::{ borrow_set::BorrowSet, @@ -1041,9 +1040,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .collect(); let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| { - self.infcx.next_nll_region_var( + self.infcx.next_nll_region_var_in_universe( NllRegionVariableOrigin::Existential { from_forall: false }, - || RegionCtxt::Unknown, + ty::UniverseIndex::ROOT, ) }); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9526ed144c349..7dbc18908d5fe 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1474,6 +1474,7 @@ impl<'tcx> InferCtxt<'tcx> { /// universes. Updates `self.universe` to that new universe. pub fn create_next_universe(&self) -> ty::UniverseIndex { let u = self.universe.get().next_universe(); + debug!("create_next_universe {u:?}"); self.universe.set(u); u } diff --git a/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs b/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs new file mode 100644 index 0000000000000..97c4430586447 --- /dev/null +++ b/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Trait { + type Ty; +} + +impl Trait for for<'a> fn(&'a u8, &'a u8) { + type Ty = (); +} + +// argument is necessary to create universes before registering the hidden type. +fn test<'a>(_: ::Ty) -> impl Sized { + "hidden type is `&'?0 str` with '?0 member of ['static,]" +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr new file mode 100644 index 0000000000000..dd2737c706d6b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -0,0 +1,55 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/normalize-hidden-types.rs:25:20 + | +LL | fn define() -> Opaque { + | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` + | +note: previous use here + --> $DIR/normalize-hidden-types.rs:27:9 + | +LL | dyn_hoops::<_>(0) + | ^^^^^^^^^^^^^^^^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/normalize-hidden-types.rs:34:22 + | +LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } + | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` + | +note: previous use here + --> $DIR/normalize-hidden-types.rs:34:31 + | +LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/normalize-hidden-types.rs:44:25 + | +LL | type Opaque = impl Sized; + | ---------- the expected opaque type +... +LL | let _: Opaque = dyn_hoops::(0); + | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` + | | + | expected due to this + | + = note: expected opaque type `typeck::Opaque` + found raw pointer `*const (dyn FnOnce(()) + 'static)` + = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: concrete type differs from previous defining opaque type use + --> $DIR/normalize-hidden-types.rs:54:25 + | +LL | let _: Opaque = dyn_hoops::<_>(0); + | ^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` + | +note: previous use here + --> $DIR/normalize-hidden-types.rs:56:9 + | +LL | None + | ^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs new file mode 100644 index 0000000000000..8d80546444ada --- /dev/null +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs @@ -0,0 +1,60 @@ +// Regression test for #112691 +// +// revisions: current next +// [next] compile-flags: -Ztrait-solver=next +// [next] check-pass +// [current]: known-bug: #112691 + +#![feature(type_alias_impl_trait)] + +trait Trait { + type Gat<'lt>; +} + +impl Trait for u8 { + type Gat<'lt> = (); +} + +fn dyn_hoops(_: T) -> *const dyn FnOnce(T::Gat<'_>) { + loop {} +} + +mod typeof_1 { + use super::*; + type Opaque = impl Sized; + fn define() -> Opaque { + //[current]~^ ERROR concrete type differs + dyn_hoops::<_>(0) + } +} + +mod typeof_2 { + use super::*; + type Opaque = impl Sized; + fn define_1() -> Opaque { dyn_hoops::<_>(0) } + //[current]~^ ERROR concrete type differs + fn define_2() -> Opaque { dyn_hoops::(0) } +} + +mod typeck { + use super::*; + type Opaque = impl Sized; + fn define() -> Option { + let _: Opaque = dyn_hoops::<_>(0); + let _: Opaque = dyn_hoops::(0); + //[current]~^ ERROR mismatched types + None + } +} + +mod borrowck { + use super::*; + type Opaque = impl Sized; + fn define() -> Option { + let _: Opaque = dyn_hoops::<_>(0); + //[current]~^ ERROR concrete type differs + None + } +} + +fn main() {} From 8c8c7ef78a213af0b65f22f1748b1d569181a9d3 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 21 Jun 2023 02:20:55 +0800 Subject: [PATCH 6/8] fix: add cfg diagnostic for unresolved import error --- compiler/rustc_resolve/src/imports.rs | 13 +++++++- tests/ui/cfg/diagnostics-reexport.rs | 24 +++++++++++++++ tests/ui/cfg/diagnostics-reexport.stderr | 38 ++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4445330992004..c458fc872aaef 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -609,7 +609,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn throw_unresolved_import_error(&self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) { + fn throw_unresolved_import_error(&mut self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) { if errors.is_empty() { return; } @@ -679,6 +679,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => {} } } + + match &import.kind { + ImportKind::Single { source, .. } => { + if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get() + && let Some(module) = module.opt_def_id() + { + self.find_cfg_stripped(&mut diag, &source.name, module) + } + }, + _ => {} + } } diag.emit(); diff --git a/tests/ui/cfg/diagnostics-reexport.rs b/tests/ui/cfg/diagnostics-reexport.rs index 1d43d6ba02f56..b9548e911831e 100644 --- a/tests/ui/cfg/diagnostics-reexport.rs +++ b/tests/ui/cfg/diagnostics-reexport.rs @@ -9,6 +9,30 @@ pub mod inner { //~^ NOTE found an item that was configured out } +pub use a::x; +//~^ ERROR unresolved import `a::x` +//~| NOTE no `x` in `a` + +mod a { + #[cfg(no)] + pub fn x() {} + //~^ NOTE found an item that was configured out +} + +pub use b::{x, y}; +//~^ ERROR unresolved imports `b::x`, `b::y` +//~| NOTE no `x` in `b` +//~| NOTE no `y` in `b` + +mod b { + #[cfg(no)] + pub fn x() {} + //~^ NOTE found an item that was configured out + #[cfg(no)] + pub fn y() {} + //~^ NOTE found an item that was configured out +} + fn main() { // There is no uwu at this path - no diagnostic. inner::uwu(); //~ ERROR cannot find function diff --git a/tests/ui/cfg/diagnostics-reexport.stderr b/tests/ui/cfg/diagnostics-reexport.stderr index 6c977cbfa4172..e25b7cf86e210 100644 --- a/tests/ui/cfg/diagnostics-reexport.stderr +++ b/tests/ui/cfg/diagnostics-reexport.stderr @@ -1,5 +1,36 @@ +error[E0432]: unresolved import `a::x` + --> $DIR/diagnostics-reexport.rs:12:9 + | +LL | pub use a::x; + | ^^^^ no `x` in `a` + | +note: found an item that was configured out + --> $DIR/diagnostics-reexport.rs:18:12 + | +LL | pub fn x() {} + | ^ + +error[E0432]: unresolved imports `b::x`, `b::y` + --> $DIR/diagnostics-reexport.rs:22:13 + | +LL | pub use b::{x, y}; + | ^ ^ no `y` in `b` + | | + | no `x` in `b` + | +note: found an item that was configured out + --> $DIR/diagnostics-reexport.rs:29:12 + | +LL | pub fn x() {} + | ^ +note: found an item that was configured out + --> $DIR/diagnostics-reexport.rs:32:12 + | +LL | pub fn y() {} + | ^ + error[E0425]: cannot find function `uwu` in module `inner` - --> $DIR/diagnostics-reexport.rs:14:12 + --> $DIR/diagnostics-reexport.rs:38:12 | LL | inner::uwu(); | ^^^ not found in `inner` @@ -10,6 +41,7 @@ note: found an item that was configured out LL | pub use super::uwu; | ^^^ -error: aborting due to previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0425, E0432. +For more information about an error, try `rustc --explain E0425`. From ce326918ec0d66b5460ef343553f2e99f3880283 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 24 Jun 2023 10:20:52 -0700 Subject: [PATCH 7/8] bootstrap: Backup `settings.json` to the correct filename The old code actually replaced `.json` with `.bak` (so, `settings.bak`), rather than appending `.bak` as claimed (`settings.json.bak`). `Path::set_extension` can instead be used with dots: > The new extension may contain dots and will be used in its entirety, > but only the part after the final dot will be reflected in > self.extension. --- src/bootstrap/setup.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 7eb70de91f84e..9811cf163e5f4 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -582,7 +582,7 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<()> { Some(false) => { // exists and is not current version or outdated, so back it up let mut backup = vscode_settings.clone(); - backup.set_extension("bak"); + backup.set_extension("json.bak"); eprintln!("warning: copying `settings.json` to `settings.json.bak`"); fs::copy(&vscode_settings, &backup)?; "Updated" From f799e78d772abaf1df4c157b39d39b28d1602f41 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 24 Jun 2023 19:45:42 +0200 Subject: [PATCH 8/8] Fix old python deprecation check in x.py The warning suppression variable was not checked correctly. --- x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x.py b/x.py index 7163df5cfe99b..ba959a3047ed9 100755 --- a/x.py +++ b/x.py @@ -31,7 +31,7 @@ # soft deprecation of old python versions skip_check = os.environ.get("RUST_IGNORE_OLD_PYTHON") == "1" - if major < 3 or (major == 3 and minor < 6): + if not skip_check and (major < 3 or (major == 3 and minor < 6)): msg = cleandoc(""" Using python {}.{} but >= 3.6 is recommended. Your python version should continue to work for the near future, but this will