From 889bb17b63723e5333ff294dda34d64210b132df Mon Sep 17 00:00:00 2001 From: gimbles Date: Thu, 3 Nov 2022 21:07:27 +0530 Subject: [PATCH 001/482] deny global_asm in unsafe_code --- compiler/rustc_lint/src/builtin.rs | 4 ++++ compiler/rustc_middle/src/lint.rs | 5 ++++- src/test/ui/lint/lint-global_asm-is-unsafe.rs | 7 +++++++ src/test/ui/lint/lint-global_asm-is-unsafe.stderr | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/lint-global_asm-is-unsafe.rs create mode 100644 src/test/ui/lint/lint-global_asm-is-unsafe.stderr diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 27c04d828111d..c88f1f021e730 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -431,6 +431,10 @@ impl EarlyLintPass for UnsafeCode { } } + ast::ItemKind::GlobalAsm(..) => { + self.report_unsafe(cx, it.span, "usage of `global_asm` is unsafe", |lint| lint) + } + _ => {} } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 79522bd0b2b2a..af70b0c6470e5 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -483,7 +483,10 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { DesugaringKind::ForLoop | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy, ) => false, ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" - ExpnKind::Macro(MacroKind::Bang, _) => { + ExpnKind::Macro(MacroKind::Bang, id) => { + if id.as_str() == "core::arch::global_asm" { + return false; + } // Dummy span for the `def_site` means it's an external macro. expn_data.def_site.is_dummy() || sess.source_map().is_imported(expn_data.def_site) } diff --git a/src/test/ui/lint/lint-global_asm-is-unsafe.rs b/src/test/ui/lint/lint-global_asm-is-unsafe.rs new file mode 100644 index 0000000000000..9ccf18efa97cf --- /dev/null +++ b/src/test/ui/lint/lint-global_asm-is-unsafe.rs @@ -0,0 +1,7 @@ +#![deny(unsafe_code)] + +core::arch::global_asm! { "nop" } //~ ERROR: 3:1: 3:34: usage of `global_asm` is unsafe [unsafe_code] + +fn main() { + +} diff --git a/src/test/ui/lint/lint-global_asm-is-unsafe.stderr b/src/test/ui/lint/lint-global_asm-is-unsafe.stderr new file mode 100644 index 0000000000000..f905b639be3a3 --- /dev/null +++ b/src/test/ui/lint/lint-global_asm-is-unsafe.stderr @@ -0,0 +1,15 @@ +error: usage of `global_asm` is unsafe + --> $DIR/lint-global_asm-is-unsafe.rs:3:1 + | +LL | core::arch::global_asm! { "nop" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-global_asm-is-unsafe.rs:1:9 + | +LL | #![deny(unsafe_code)] + | ^^^^^^^^^^^ + = note: this error originates in the macro `core::arch::global_asm` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + From a3d552878483808f2376d0c44389ac8653e036b7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 24 Oct 2022 21:58:42 +0400 Subject: [PATCH 002/482] rustc_metadata: Encode even less doc comments --- compiler/rustc_metadata/src/rmeta/encoder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c907ee6462870..6a73e14e9f58b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -788,8 +788,7 @@ fn should_encode_attr( } else if attr.doc_str().is_some() { // We keep all public doc comments because they might be "imported" into downstream crates // if they use `#[doc(inline)]` to copy an item's documentation into their own. - *is_def_id_public - .get_or_insert_with(|| tcx.effective_visibilities(()).effective_vis(def_id).is_some()) + *is_def_id_public.get_or_insert_with(|| tcx.effective_visibilities(()).is_exported(def_id)) } else if attr.has_name(sym::doc) { // If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can // remove it. It won't be inlinable in downstream crates. From 765ab520824fd04e847110ffc8b967d243aa9ce4 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 4 Oct 2022 19:02:13 -0500 Subject: [PATCH 003/482] Make PROC_MACRO_DERIVE_RESOLUTION_FALLBACK a hard error --- compiler/rustc_lint_defs/src/builtin.rs | 68 ----------- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 75 ++---------- compiler/rustc_resolve/src/lib.rs | 6 +- src/test/ui/proc-macro/generate-mod.rs | 7 +- src/test/ui/proc-macro/generate-mod.stderr | 129 ++++++--------------- 6 files changed, 49 insertions(+), 238 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 61ee467f59577..389f3ccf72acf 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1982,73 +1982,6 @@ declare_lint! { }; } -declare_lint! { - /// The `proc_macro_derive_resolution_fallback` lint detects proc macro - /// derives using inaccessible names from parent modules. - /// - /// ### Example - /// - /// ```rust,ignore (proc-macro) - /// // foo.rs - /// #![crate_type = "proc-macro"] - /// - /// extern crate proc_macro; - /// - /// use proc_macro::*; - /// - /// #[proc_macro_derive(Foo)] - /// pub fn foo1(a: TokenStream) -> TokenStream { - /// drop(a); - /// "mod __bar { static mut BAR: Option = None; }".parse().unwrap() - /// } - /// ``` - /// - /// ```rust,ignore (needs-dependency) - /// // bar.rs - /// #[macro_use] - /// extern crate foo; - /// - /// struct Something; - /// - /// #[derive(Foo)] - /// struct Another; - /// - /// fn main() {} - /// ``` - /// - /// This will produce: - /// - /// ```text - /// warning: cannot find type `Something` in this scope - /// --> src/main.rs:8:10 - /// | - /// 8 | #[derive(Foo)] - /// | ^^^ names from parent modules are not accessible without an explicit import - /// | - /// = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default - /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - /// = note: for more information, see issue #50504 - /// ``` - /// - /// ### Explanation - /// - /// If a proc-macro generates a module, the compiler unintentionally - /// allowed items in that module to refer to items in the crate root - /// without importing them. This is a [future-incompatible] lint to - /// transition this to a hard error in the future. See [issue #50504] for - /// more details. - /// - /// [issue #50504]: https://github.com/rust-lang/rust/issues/50504 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - Deny, - "detects proc macro derives using inaccessible names from parent modules", - @future_incompatible = FutureIncompatibleInfo { - reference: "issue #83583 ", - reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, - }; -} - declare_lint! { /// The `macro_use_extern_crate` lint detects the use of the /// [`macro_use` attribute]. @@ -3287,7 +3220,6 @@ declare_lint_pass! { UNSTABLE_NAME_COLLISIONS, IRREFUTABLE_LET_PATTERNS, WHERE_CLAUSES_OBJECT_SAFETY, - PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, ILL_FORMED_ATTRIBUTE_INPUT, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 5029c33996329..ee64e1adfd99c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1202,7 +1202,7 @@ impl<'a> Resolver<'a> { let root_module = this.resolve_crate_root(root_ident); this.add_module_candidates(root_module, &mut suggestions, filter_fn, None); } - Scope::Module(module, _) => { + Scope::Module(module) => { this.add_module_candidates(module, &mut suggestions, filter_fn, None); } Scope::MacroUsePrelude => { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e0542d5479fa0..a24ee7db00843 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1,11 +1,9 @@ -use rustc_ast::{self as ast, NodeId}; +use rustc_ast as ast; use rustc_feature::is_builtin_attr_name; use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::PrimTy; use rustc_middle::bug; use rustc_middle::ty; -use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; -use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::def_id::LocalDefId; use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; @@ -101,7 +99,7 @@ impl<'a> Resolver<'a> { }; let mut scope = match ns { _ if is_absolute_path => Scope::CrateRoot, - TypeNS | ValueNS => Scope::Module(module, None), + TypeNS | ValueNS => Scope::Module(module), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; let mut ctxt = ctxt.normalize_to_macros_2_0(); @@ -165,7 +163,7 @@ impl<'a> Resolver<'a> { MacroRulesScope::Invocation(invoc_id) => { Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules) } - MacroRulesScope::Empty => Scope::Module(module, None), + MacroRulesScope::Empty => Scope::Module(module), }, Scope::CrateRoot => match ns { TypeNS => { @@ -174,16 +172,10 @@ impl<'a> Resolver<'a> { } ValueNS | MacroNS => break, }, - Scope::Module(module, prev_lint_id) => { + Scope::Module(module) => { use_prelude = !module.no_implicit_prelude; - let derive_fallback_lint_id = match scope_set { - ScopeSet::Late(.., lint_id) => lint_id, - _ => None, - }; - match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) { - Some((parent_module, lint_id)) => { - Scope::Module(parent_module, lint_id.or(prev_lint_id)) - } + match self.hygienic_lexical_parent(module, &mut ctxt) { + Some(parent_module) => Scope::Module(parent_module), None => { ctxt.adjust(ExpnId::root()); match ns { @@ -215,45 +207,13 @@ impl<'a> Resolver<'a> { &mut self, module: Module<'a>, ctxt: &mut SyntaxContext, - derive_fallback_lint_id: Option, - ) -> Option<(Module<'a>, Option)> { + ) -> Option> { if !module.expansion.outer_expn_is_descendant_of(*ctxt) { - return Some((self.expn_def_scope(ctxt.remove_mark()), None)); + return Some(self.expn_def_scope(ctxt.remove_mark())); } if let ModuleKind::Block = module.kind { - return Some((module.parent.unwrap().nearest_item_scope(), None)); - } - - // We need to support the next case under a deprecation warning - // ``` - // struct MyStruct; - // ---- begin: this comes from a proc macro derive - // mod implementation_details { - // // Note that `MyStruct` is not in scope here. - // impl SomeTrait for MyStruct { ... } - // } - // ---- end - // ``` - // So we have to fall back to the module's parent during lexical resolution in this case. - if derive_fallback_lint_id.is_some() { - if let Some(parent) = module.parent { - // Inner module is inside the macro, parent module is outside of the macro. - if module.expansion != parent.expansion - && module.expansion.is_descendant_of(parent.expansion) - { - // The macro is a proc macro derive - if let Some(def_id) = module.expansion.expn_data().macro_def_id { - let ext = self.get_macro_by_def_id(def_id).ext; - if ext.builtin_name.is_none() - && ext.macro_kind() == MacroKind::Derive - && parent.expansion.outer_expn_is_descendant_of(*ctxt) - { - return Some((parent, derive_fallback_lint_id)); - } - } - } - } + return Some(module.parent.unwrap().nearest_item_scope()); } None @@ -510,7 +470,7 @@ impl<'a> Resolver<'a> { Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), } } - Scope::Module(module, derive_fallback_lint_id) => { + Scope::Module(module) => { let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), @@ -523,21 +483,6 @@ impl<'a> Resolver<'a> { ); match binding { Ok(binding) => { - if let Some(lint_id) = derive_fallback_lint_id { - this.lint_buffer.buffer_lint_with_diagnostic( - PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - lint_id, - orig_ident.span, - &format!( - "cannot find {} `{}` in this scope", - ns.descr(), - ident - ), - BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback( - orig_ident.span, - ), - ); - } let misc_flags = if ptr::eq(module, this.graph_root) { Flags::MISC_SUGGEST_CRATE } else if module.is_normal() { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 11b70a38da58d..cd85ffd098279 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -104,9 +104,7 @@ enum Scope<'a> { DeriveHelpersCompat, MacroRules(MacroRulesScopeRef<'a>), CrateRoot, - // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` - // lint if it should be reported. - Module(Module<'a>, Option), + Module(Module<'a>), MacroUsePrelude, BuiltinAttrs, ExternPrelude, @@ -1551,7 +1549,7 @@ impl<'a> Resolver<'a> { self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| { match scope { - Scope::Module(module, _) => { + Scope::Module(module) => { this.traits_in_module(module, assoc_item, &mut found_traits); } Scope::StdLibPrelude => { diff --git a/src/test/ui/proc-macro/generate-mod.rs b/src/test/ui/proc-macro/generate-mod.rs index 471f317edf964..9eea630c310ec 100644 --- a/src/test/ui/proc-macro/generate-mod.rs +++ b/src/test/ui/proc-macro/generate-mod.rs @@ -15,19 +15,16 @@ struct S; #[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` in this scope //~| ERROR cannot find type `OuterDerive` in this scope - //~| WARN this was previously accepted - //~| WARN this was previously accepted struct Z; fn inner_block() { #[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` in this scope //~| ERROR cannot find type `OuterDerive` in this scope - //~| WARN this was previously accepted - //~| WARN this was previously accepted struct InnerZ; } -#[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed +#[derive(generate_mod::CheckDeriveLint)] //~ ERROR cannot find type `OuterDeriveLint` in this scope + //~| ERROR cannot find type `FromOutside` in this scope struct W; fn main() {} diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index 39bf28dba9684..64042ca0ecdea 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -38,127 +38,66 @@ LL | #[generate_mod::check_attr] OuterAttr = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default + = note: consider importing this struct: + FromOutside = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` in this scope +error[E0412]: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:23:14 - | -LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 + = note: consider importing this struct: + OuterDerive = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:23:14 +error[E0412]: cannot find type `FromOutside` in this scope + --> $DIR/generate-mod.rs:21:14 | LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0412`. -Future incompatibility report: Future breakage diagnostic: -error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:16:10 - | -LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) - -Future breakage diagnostic: -error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:16:10 - | -LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default + = note: consider importing this struct: + FromOutside = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -Future breakage diagnostic: -error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:23:14 +error[E0412]: cannot find type `OuterDerive` in this scope + --> $DIR/generate-mod.rs:21:14 | LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default + = note: consider importing this struct: + OuterDerive = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -Future breakage diagnostic: -error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:23:14 +error[E0412]: cannot find type `FromOutside` in this scope + --> $DIR/generate-mod.rs:26:10 | -LL | #[derive(generate_mod::CheckDerive)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import +LL | #[derive(generate_mod::CheckDeriveLint)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: consider importing this struct: + FromOutside + = note: this error originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) -Future breakage diagnostic: -warning: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:30:10 +error[E0412]: cannot find type `OuterDeriveLint` in this scope + --> $DIR/generate-mod.rs:26:10 | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import +LL | #[derive(generate_mod::CheckDeriveLint)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 -note: the lint level is defined here - --> $DIR/generate-mod.rs:30:10 - | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: consider importing this struct: + OuterDeriveLint + = note: this error originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) -Future breakage diagnostic: -warning: cannot find type `OuterDeriveLint` in this scope - --> $DIR/generate-mod.rs:30:10 - | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 -note: the lint level is defined here - --> $DIR/generate-mod.rs:30:10 - | -LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) +error: aborting due to 10 previous errors +For more information about this error, try `rustc --explain E0412`. From abe1ffd4e309e067a4f5257a7205239b30d80363 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 30 Oct 2022 13:35:31 +0400 Subject: [PATCH 004/482] resolve: Not all imports have their own `NodeId` --- .../rustc_resolve/src/build_reduced_graph.rs | 21 +-- compiler/rustc_resolve/src/check_unused.rs | 8 +- compiler/rustc_resolve/src/diagnostics.rs | 2 +- .../src/effective_visibilities.rs | 48 ++++-- compiler/rustc_resolve/src/imports.rs | 151 +++++++++++------- compiler/rustc_resolve/src/lib.rs | 16 +- 6 files changed, 142 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a17793ecd99bd..5ac562d166369 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -364,7 +364,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { module_path: Vec, kind: ImportKind<'a>, span: Span, - id: NodeId, item: &ast::Item, root_span: Span, root_id: NodeId, @@ -377,7 +376,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { module_path, imported_module: Cell::new(None), span, - id, use_span: item.span, use_span_with_attributes: item.span_with_attributes(), has_attributes: !item.attrs.is_empty(), @@ -574,27 +572,20 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }, type_ns_only, nested, + id, additional_ids: (id1, id2), }; - self.add_import( - module_path, - kind, - use_tree.span, - id, - item, - root_span, - item.id, - vis, - ); + self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis); } ast::UseTreeKind::Glob => { let kind = ImportKind::Glob { is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(None), + id, }; self.r.visibilities.insert(self.r.local_def_id(id), vis); - self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis); + self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis); } ast::UseTreeKind::Nested(ref items) => { // Ensure there is at most one `self` in the list @@ -881,9 +872,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }) .unwrap_or((true, None, self.r.dummy_binding)); let import = self.r.arenas.alloc_import(Import { - kind: ImportKind::ExternCrate { source: orig_name, target: ident }, + kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id }, root_id: item.id, - id: item.id, parent_scope: self.parent_scope, imported_module: Cell::new(module), has_attributes: !item.attrs.is_empty(), @@ -1118,7 +1108,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { this.r.arenas.alloc_import(Import { kind: ImportKind::MacroUse, root_id: item.id, - id: item.id, parent_scope: this.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), use_span_with_attributes: item.span_with_attributes(), diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 01c3801f22329..32fb5e18276ab 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -234,7 +234,7 @@ impl Resolver<'_> { if !import.span.is_dummy() { self.lint_buffer.buffer_lint( MACRO_USE_EXTERN_CRATE, - import.id, + import.root_id, import.span, "deprecated `#[macro_use]` attribute used to \ import macros should be replaced at use sites \ @@ -244,13 +244,13 @@ impl Resolver<'_> { } } } - ImportKind::ExternCrate { .. } => { - let def_id = self.local_def_id(import.id); + ImportKind::ExternCrate { id, .. } => { + let def_id = self.local_def_id(id); self.maybe_unused_extern_crates.push((def_id, import.span)); } ImportKind::MacroUse => { let msg = "unused `#[macro_use]` import"; - self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg); + self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.root_id, import.span, msg); } _ => {} } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ee64e1adfd99c..dfc1ce68407e6 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -353,7 +353,7 @@ impl<'a> Resolver<'a> { } } } - ImportKind::ExternCrate { source, target } => { + ImportKind::ExternCrate { source, target, .. } => { suggestion = Some(format!( "extern crate {} as {};", source.unwrap_or(target.name), diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index c40669ac95bee..84fa7b89bda41 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -57,26 +57,40 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { while let NameBindingKind::Import { binding: nested_binding, import, .. } = binding.kind { - let mut update = |node_id| self.update( - self.r.local_def_id(node_id), - binding.vis.expect_local(), - prev_parent_id, - level, - ); - // In theory all the import IDs have individual visibilities and effective - // visibilities, but in practice these IDs go straigth to HIR where all - // their few uses assume that their (effective) visibility applies to the - // whole syntactic `use` item. So we update them all to the maximum value - // among the potential individual effective visibilities. Maybe HIR for - // imports shouldn't use three IDs at all. - update(import.id); - if let ImportKind::Single { additional_ids, .. } = import.kind { - update(additional_ids.0); - update(additional_ids.1); + let mut update = |node_id| { + self.update( + self.r.local_def_id(node_id), + binding.vis.expect_local(), + prev_parent_id, + level, + ) + }; + match import.kind { + ImportKind::Single { id, additional_ids, .. } => { + // In theory all the import IDs have individual visibilities and + // effective visibilities, but in practice these IDs go straigth to + // HIR where all their few uses assume that their (effective) + // visibility applies to the whole syntactic `use` item. So we + // update them all to the maximum value among the potential + // individual effective visibilities. Maybe HIR for imports + // shouldn't use three IDs at all. + update(id); + update(additional_ids.0); + update(additional_ids.1); + prev_parent_id = self.r.local_def_id(id); + } + ImportKind::Glob { id, .. } | ImportKind::ExternCrate { id, .. } => { + update(id); + prev_parent_id = self.r.local_def_id(id); + } + ImportKind::MacroUse => { + // In theory we should reset the parent id to something private + // here, but `macro_use` imports always refer to external items, + // so it doesn't matter and we can just do nothing. + } } level = Level::Reexported; - prev_parent_id = self.r.local_def_id(import.id); binding = nested_binding; } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f2cc50c199fc8..3b9bf94326295 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -44,18 +44,33 @@ pub enum ImportKind<'a> { type_ns_only: bool, /// Did this import result from a nested import? ie. `use foo::{bar, baz};` nested: bool, + /// The ID of the `UseTree` that imported this `Import`. + /// + /// In the case where the `Import` was expanded from a "nested" use tree, + /// this id is the ID of the leaf tree. For example: + /// + /// ```ignore (pacify the merciless tidy) + /// use foo::bar::{a, b} + /// ``` + /// + /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree` + /// for `a` in this field. + id: NodeId, /// Additional `NodeId`s allocated to a `ast::UseTree` for automatically generated `use` statement /// (eg. implicit struct constructors) additional_ids: (NodeId, NodeId), }, Glob { is_prelude: bool, - max_vis: Cell>, // The visibility of the greatest re-export. - // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. + // The visibility of the greatest re-export. + // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. + max_vis: Cell>, + id: NodeId, }, ExternCrate { source: Option, target: Ident, + id: NodeId, }, MacroUse, } @@ -71,6 +86,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> { ref target, ref type_ns_only, ref nested, + ref id, ref additional_ids, // Ignore the following to avoid an infinite loop while printing. source_bindings: _, @@ -81,17 +97,20 @@ impl<'a> std::fmt::Debug for ImportKind<'a> { .field("target", target) .field("type_ns_only", type_ns_only) .field("nested", nested) + .field("id", id) .field("additional_ids", additional_ids) .finish_non_exhaustive(), - Glob { ref is_prelude, ref max_vis } => f + Glob { ref is_prelude, ref max_vis, ref id } => f .debug_struct("Glob") .field("is_prelude", is_prelude) .field("max_vis", max_vis) + .field("id", id) .finish(), - ExternCrate { ref source, ref target } => f + ExternCrate { ref source, ref target, ref id } => f .debug_struct("ExternCrate") .field("source", source) .field("target", target) + .field("id", id) .finish(), MacroUse => f.debug_struct("MacroUse").finish(), } @@ -103,24 +122,15 @@ impl<'a> std::fmt::Debug for ImportKind<'a> { pub(crate) struct Import<'a> { pub kind: ImportKind<'a>, - /// The ID of the `extern crate`, `UseTree` etc that imported this `Import`. - /// - /// In the case where the `Import` was expanded from a "nested" use tree, - /// this id is the ID of the leaf tree. For example: - /// - /// ```ignore (pacify the merciless tidy) + /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id` + /// (if it exists) except in the case of "nested" use trees, in which case + /// it will be the ID of the root use tree. e.g., in the example + /// ```ignore (incomplete code) /// use foo::bar::{a, b} /// ``` - /// - /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree` - /// for `a` in this field. - pub id: NodeId, - - /// The `id` of the "root" use-kind -- this is always the same as - /// `id` except in the case of "nested" use trees, in which case - /// it will be the `id` of the root use tree. e.g., in the example - /// from `id`, this would be the ID of the `use foo::bar` - /// `UseTree` node. + /// this would be the ID of the `use foo::bar` `UseTree` node. + /// In case of imports without their own node ID it's the closest node that can be used, + /// for example, for reporting lints. pub root_id: NodeId, /// Span of the entire use statement. @@ -161,6 +171,15 @@ impl<'a> Import<'a> { pub(crate) fn expect_vis(&self) -> ty::Visibility { self.vis.get().expect("encountered cleared import visibility") } + + pub(crate) fn id(&self) -> Option { + match self.kind { + ImportKind::Single { id, .. } + | ImportKind::Glob { id, .. } + | ImportKind::ExternCrate { id, .. } => Some(id), + ImportKind::MacroUse => None, + } + } } /// Records information about the resolution of a name in a namespace of a module. @@ -368,7 +387,9 @@ impl<'a> Resolver<'a> { self.record_use(target, dummy_binding, false); } else if import.imported_module.get().is_none() { import.used.set(true); - self.used_imports.insert(import.id); + if let Some(id) = import.id() { + self.used_imports.insert(id); + } } } } @@ -718,47 +739,51 @@ impl<'a, 'b> ImportResolver<'a, 'b> { PathResult::Indeterminate => unreachable!(), }; - let (ident, target, source_bindings, target_bindings, type_ns_only) = match import.kind { - ImportKind::Single { - source, - target, - ref source_bindings, - ref target_bindings, - type_ns_only, - .. - } => (source, target, source_bindings, target_bindings, type_ns_only), - ImportKind::Glob { is_prelude, ref max_vis } => { - if import.module_path.len() <= 1 { - // HACK(eddyb) `lint_if_path_starts_with_module` needs at least - // 2 segments, so the `resolve_path` above won't trigger it. - let mut full_path = import.module_path.clone(); - full_path.push(Segment::from_ident(Ident::empty())); - self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None); - } + let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) = + match import.kind { + ImportKind::Single { + source, + target, + ref source_bindings, + ref target_bindings, + type_ns_only, + id, + .. + } => (source, target, source_bindings, target_bindings, type_ns_only, id), + ImportKind::Glob { is_prelude, ref max_vis, id } => { + if import.module_path.len() <= 1 { + // HACK(eddyb) `lint_if_path_starts_with_module` needs at least + // 2 segments, so the `resolve_path` above won't trigger it. + let mut full_path = import.module_path.clone(); + full_path.push(Segment::from_ident(Ident::empty())); + self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None); + } - if let ModuleOrUniformRoot::Module(module) = module { - if ptr::eq(module, import.parent_scope.module) { - // Importing a module into itself is not allowed. - return Some(UnresolvedImportError { - span: import.span, - label: Some(String::from("cannot glob-import a module into itself")), - note: None, - suggestion: None, - candidate: None, - }); + if let ModuleOrUniformRoot::Module(module) = module { + if ptr::eq(module, import.parent_scope.module) { + // Importing a module into itself is not allowed. + return Some(UnresolvedImportError { + span: import.span, + label: Some(String::from( + "cannot glob-import a module into itself", + )), + note: None, + suggestion: None, + candidate: None, + }); + } } - } - if !is_prelude + if !is_prelude && let Some(max_vis) = max_vis.get() && !max_vis.is_at_least(import.expect_vis(), &*self.r) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg); + self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); } - return None; - } - _ => unreachable!(), - }; + return None; + } + _ => unreachable!(), + }; let mut all_ns_err = true; self.r.per_ns(|this, ns| { @@ -960,7 +985,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ); self.r.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, - import.id, + import_id, import.span, &msg, ); @@ -1029,7 +1054,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // purposes it's good enough to just favor one over the other. self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - this.import_res_map.entry(import.id).or_default()[ns] = Some(binding.res()); + this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res()); } }); @@ -1047,6 +1072,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { target_bindings: &PerNS>>>, target: Ident, ) { + // This function is only called for single imports. + let ImportKind::Single { id, .. } = import.kind else { unreachable!() }; + // Skip if the import was produced by a macro. if import.parent_scope.expansion != LocalExpnId::ROOT { return; @@ -1094,7 +1122,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { redundant_spans.dedup(); self.r.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, - import.id, + id, import.span, &format!("the item `{}` is imported redundantly", ident), BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), @@ -1103,6 +1131,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } fn resolve_glob_import(&mut self, import: &'b Import<'b>) { + // This function is only called for glob imports. + let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; + let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { self.r.session.span_err(import.span, "cannot glob-import all possible crates"); return; @@ -1113,7 +1144,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { return; } else if ptr::eq(module, import.parent_scope.module) { return; - } else if let ImportKind::Glob { is_prelude: true, .. } = import.kind { + } else if is_prelude { self.r.prelude = Some(module); return; } @@ -1145,7 +1176,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } // Record the destination of this import - self.r.record_partial_res(import.id, PartialRes::new(module.res().unwrap())); + self.r.record_partial_res(id, PartialRes::new(module.res().unwrap())); } // Miscellaneous post-processing, including recording re-exports, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cd85ffd098279..8f47fd13d33a1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1611,10 +1611,12 @@ impl<'a> Resolver<'a> { ) -> SmallVec<[LocalDefId; 1]> { let mut import_ids = smallvec![]; while let NameBindingKind::Import { import, binding, .. } = kind { - let id = self.local_def_id(import.id); - self.maybe_unused_trait_imports.insert(id); + if let Some(node_id) = import.id() { + let def_id = self.local_def_id(node_id); + self.maybe_unused_trait_imports.insert(def_id); + import_ids.push(def_id); + } self.add_to_glob_map(&import, trait_name); - import_ids.push(id); kind = &binding.kind; } import_ids @@ -1681,7 +1683,9 @@ impl<'a> Resolver<'a> { } used.set(true); import.used.set(true); - self.used_imports.insert(import.id); + if let Some(id) = import.id() { + self.used_imports.insert(id); + } self.add_to_glob_map(&import, ident); self.record_use(ident, binding, false); } @@ -1689,8 +1693,8 @@ impl<'a> Resolver<'a> { #[inline] fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { - if import.is_glob() { - let def_id = self.local_def_id(import.id); + if let ImportKind::Glob { id, .. } = import.kind { + let def_id = self.local_def_id(id); self.glob_map.entry(def_id).or_default().insert(ident.name); } } From 8123dccb6337a3c620f9c61423edfa367b8e396b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 30 Oct 2022 15:55:58 +0400 Subject: [PATCH 005/482] resolve: Turn the binding from `#[macro_export]` into a proper `Import` --- .../rustc_resolve/src/build_reduced_graph.rs | 34 +++++++++---------- compiler/rustc_resolve/src/diagnostics.rs | 34 +++++++++++-------- .../src/effective_visibilities.rs | 12 +++---- compiler/rustc_resolve/src/ident.rs | 8 +++-- compiler/rustc_resolve/src/imports.rs | 9 +++-- compiler/rustc_resolve/src/lib.rs | 25 ++++++++------ src/test/ui/macros/issue-38715.rs | 12 ++++++- src/test/ui/macros/issue-38715.stderr | 15 ++++++-- src/test/ui/privacy/effective_visibilities.rs | 4 +-- .../ui/privacy/effective_visibilities.stderr | 4 +-- 10 files changed, 96 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 5ac562d166369..423c57275333a 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -56,21 +56,7 @@ impl<'a, Id: Into> ToNameBinding<'a> impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { - kind: NameBindingKind::Res(self.0, false), - ambiguity: None, - vis: self.1.to_def_id(), - span: self.2, - expansion: self.3, - }) - } -} - -struct IsMacroExport; - -impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroExport) { - fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { - arenas.alloc_name_binding(NameBinding { - kind: NameBindingKind::Res(self.0, true), + kind: NameBindingKind::Res(self.0), ambiguity: None, vis: self.1.to_def_id(), span: self.2, @@ -1267,8 +1253,22 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); if is_macro_export { - let module = self.r.graph_root; - self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport)); + let import = self.r.arenas.alloc_import(Import { + kind: ImportKind::MacroExport, + root_id: item.id, + parent_scope: self.parent_scope, + imported_module: Cell::new(None), + has_attributes: false, + use_span_with_attributes: span, + use_span: span, + root_span: span, + span: span, + module_path: Vec::new(), + vis: Cell::new(Some(vis)), + used: Cell::new(true), + }); + let import_binding = self.r.import(binding, import); + self.r.define(self.r.graph_root, ident, MacroNS, import_binding); } else { self.r.check_reserved_macro_name(ident, res); self.insert_unused_macro(ident, def_id, item.id, &rule_spans); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index dfc1ce68407e6..7961e3f1194e1 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -190,12 +190,12 @@ impl<'a> Resolver<'a> { ModuleKind::Block => "block", }; - let old_noun = match old_binding.is_import() { + let old_noun = match old_binding.is_import_user_facing() { true => "import", false => "definition", }; - let new_participle = match new_binding.is_import() { + let new_participle = match new_binding.is_import_user_facing() { true => "imported", false => "defined", }; @@ -226,7 +226,7 @@ impl<'a> Resolver<'a> { true => struct_span_err!(self.session, span, E0254, "{}", msg), false => struct_span_err!(self.session, span, E0260, "{}", msg), }, - _ => match (old_binding.is_import(), new_binding.is_import()) { + _ => match (old_binding.is_import_user_facing(), new_binding.is_import_user_facing()) { (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg), (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg), _ => struct_span_err!(self.session, span, E0255, "{}", msg), @@ -248,14 +248,18 @@ impl<'a> Resolver<'a> { // See https://github.com/rust-lang/rust/issues/32354 use NameBindingKind::Import; + let can_suggest = |binding: &NameBinding<'_>, import: &self::Import<'_>| { + !binding.span.is_dummy() + && !matches!(import.kind, ImportKind::MacroUse | ImportKind::MacroExport) + }; let import = match (&new_binding.kind, &old_binding.kind) { // If there are two imports where one or both have attributes then prefer removing the // import without attributes. (Import { import: new, .. }, Import { import: old, .. }) if { - !new_binding.span.is_dummy() - && !old_binding.span.is_dummy() - && (new.has_attributes || old.has_attributes) + (new.has_attributes || old.has_attributes) + && can_suggest(old_binding, old) + && can_suggest(new_binding, new) } => { if old.has_attributes { @@ -265,10 +269,10 @@ impl<'a> Resolver<'a> { } } // Otherwise prioritize the new binding. - (Import { import, .. }, other) if !new_binding.span.is_dummy() => { + (Import { import, .. }, other) if can_suggest(new_binding, import) => { Some((import, new_binding.span, other.is_import())) } - (other, Import { import, .. }) if !old_binding.span.is_dummy() => { + (other, Import { import, .. }) if can_suggest(old_binding, import) => { Some((import, old_binding.span, other.is_import())) } _ => None, @@ -1683,7 +1687,7 @@ impl<'a> Resolver<'a> { let a = if built_in.is_empty() { res.article() } else { "a" }; format!("{a}{built_in} {thing}{from}", thing = res.descr()) } else { - let introduced = if b.is_import() { "imported" } else { "defined" }; + let introduced = if b.is_import_user_facing() { "imported" } else { "defined" }; format!("the {thing} {introduced} here", thing = res.descr()) } } @@ -1742,10 +1746,10 @@ impl<'a> Resolver<'a> { /// If the binding refers to a tuple struct constructor with fields, /// returns the span of its fields. fn ctor_fields_span(&self, binding: &NameBinding<'_>) -> Option { - if let NameBindingKind::Res( - Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), - _, - ) = binding.kind + if let NameBindingKind::Res(Res::Def( + DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), + ctor_def_id, + )) = binding.kind { let def_id = self.parent(ctor_def_id); let fields = self.field_names.get(&def_id)?; @@ -1789,7 +1793,9 @@ impl<'a> Resolver<'a> { next_ident = source; Some(binding) } - ImportKind::Glob { .. } | ImportKind::MacroUse => Some(binding), + ImportKind::Glob { .. } | ImportKind::MacroUse | ImportKind::MacroExport => { + Some(binding) + } ImportKind::ExternCrate { .. } => None, }, _ => None, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 84fa7b89bda41..17ce854cb4388 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -88,6 +88,11 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { // here, but `macro_use` imports always refer to external items, // so it doesn't matter and we can just do nothing. } + ImportKind::MacroExport => { + // In theory we should reset the parent id to something public + // here, but it has the same effect as leaving the previous parent, + // so we can just do nothing. + } } level = Level::Reexported; @@ -152,13 +157,6 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> { self.update(def_id, Visibility::Public, parent_id, Level::Direct); } - // Only exported `macro_rules!` items are public, but they always are - ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => { - let parent_id = self.r.local_parent(def_id); - let vis = self.r.visibilities[&def_id]; - self.update(def_id, vis, parent_id, Level::Direct); - } - ast::ItemKind::Mod(..) => { self.set_bindings_effective_visibilities(def_id); visit::walk_item(self, item); diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index a24ee7db00843..0c4b35b88335a 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -17,7 +17,7 @@ use crate::late::{ }; use crate::macros::{sub_namespace_match, MacroRulesScope}; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize}; -use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res}; use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, Weak}; @@ -860,7 +860,11 @@ impl<'a> Resolver<'a> { } if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT { - if let NameBindingKind::Res(_, true) = binding.kind { + if let NameBindingKind::Import { + import: Import { kind: ImportKind::MacroExport, .. }, + .. + } = binding.kind + { self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3b9bf94326295..bdb852548b84e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -73,6 +73,7 @@ pub enum ImportKind<'a> { id: NodeId, }, MacroUse, + MacroExport, } /// Manually implement `Debug` for `ImportKind` because the `source/target_bindings` @@ -113,6 +114,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> { .field("id", id) .finish(), MacroUse => f.debug_struct("MacroUse").finish(), + MacroExport => f.debug_struct("MacroExport").finish(), } } } @@ -177,7 +179,7 @@ impl<'a> Import<'a> { ImportKind::Single { id, .. } | ImportKind::Glob { id, .. } | ImportKind::ExternCrate { id, .. } => Some(id), - ImportKind::MacroUse => None, + ImportKind::MacroUse | ImportKind::MacroExport => None, } } } @@ -883,7 +885,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { match binding.kind { // Never suggest the name that has binding error // i.e., the name that cannot be previously resolved - NameBindingKind::Res(Res::Err, _) => None, + NameBindingKind::Res(Res::Err) => None, _ => Some(i.name), } } @@ -1014,7 +1016,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut err = struct_span_err!(self.r.session, import.span, E0364, "{error_msg}"); match binding.kind { - NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id), _) + NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id)) // exclude decl_macro if self.r.get_macro_by_def_id(def_id).macro_rules => { @@ -1235,5 +1237,6 @@ fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String { ImportKind::Glob { .. } => "*".to_string(), ImportKind::ExternCrate { .. } => "".to_string(), ImportKind::MacroUse => "#[macro_use]".to_string(), + ImportKind::MacroExport => "#[macro_export]".to_string(), } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8f47fd13d33a1..ee1c97d5ad2b7 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -644,7 +644,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> { #[derive(Clone, Debug)] enum NameBindingKind<'a> { - Res(Res, /* is_macro_export */ bool), + Res(Res), Module(Module<'a>), Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell }, } @@ -743,7 +743,7 @@ impl<'a> NameBinding<'a> { fn res(&self) -> Res { match self.kind { - NameBindingKind::Res(res, _) => res, + NameBindingKind::Res(res) => res, NameBindingKind::Module(module) => module.res().unwrap(), NameBindingKind::Import { binding, .. } => binding.res(), } @@ -760,10 +760,10 @@ impl<'a> NameBinding<'a> { fn is_possibly_imported_variant(&self) -> bool { match self.kind { NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(), - NameBindingKind::Res( - Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _), + NameBindingKind::Res(Res::Def( + DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _, - ) => true, + )) => true, NameBindingKind::Res(..) | NameBindingKind::Module(..) => false, } } @@ -786,6 +786,13 @@ impl<'a> NameBinding<'a> { matches!(self.kind, NameBindingKind::Import { .. }) } + /// The binding introduced by `#[macro_export] macro_rules` is a public import, but it might + /// not be perceived as such by users, so treat it as a non-import in some diagnostics. + fn is_import_user_facing(&self) -> bool { + matches!(self.kind, NameBindingKind::Import { import, .. } + if !matches!(import.kind, ImportKind::MacroExport)) + } + fn is_glob_import(&self) -> bool { match self.kind { NameBindingKind::Import { import, .. } => import.is_glob(), @@ -1281,7 +1288,7 @@ impl<'a> Resolver<'a> { arenas, dummy_binding: arenas.alloc_name_binding(NameBinding { - kind: NameBindingKind::Res(Res::Err, false), + kind: NameBindingKind::Res(Res::Err), ambiguity: None, expansion: LocalExpnId::ROOT, span: DUMMY_SP, @@ -1996,11 +2003,7 @@ impl<'a> Resolver<'a> { // Items that go to reexport table encoded to metadata and visible through it to other crates. fn is_reexport(&self, binding: &NameBinding<'a>) -> Option> { - // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules` - // into the crate root to actual `NameBindingKind::Import`. - if binding.is_import() - || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true)) - { + if binding.is_import() { let res = binding.res().expect_non_local(); // Ambiguous imports are treated as errors at this point and are // not exposed to other crates (see #36837 for more details). diff --git a/src/test/ui/macros/issue-38715.rs b/src/test/ui/macros/issue-38715.rs index 9a9a501cae157..85ed97663e8a0 100644 --- a/src/test/ui/macros/issue-38715.rs +++ b/src/test/ui/macros/issue-38715.rs @@ -1,7 +1,17 @@ #[macro_export] -macro_rules! foo { ($i:ident) => {} } +macro_rules! foo { () => {} } #[macro_export] macro_rules! foo { () => {} } //~ ERROR the name `foo` is defined multiple times +mod inner1 { + #[macro_export] + macro_rules! bar { () => {} } +} + +mod inner2 { + #[macro_export] + macro_rules! bar { () => {} } //~ ERROR the name `bar` is defined multiple times +} + fn main() {} diff --git a/src/test/ui/macros/issue-38715.stderr b/src/test/ui/macros/issue-38715.stderr index c87d9f7360b98..828a7f459301f 100644 --- a/src/test/ui/macros/issue-38715.stderr +++ b/src/test/ui/macros/issue-38715.stderr @@ -1,7 +1,7 @@ error[E0428]: the name `foo` is defined multiple times --> $DIR/issue-38715.rs:5:1 | -LL | macro_rules! foo { ($i:ident) => {} } +LL | macro_rules! foo { () => {} } | ---------------- previous definition of the macro `foo` here ... LL | macro_rules! foo { () => {} } @@ -9,6 +9,17 @@ LL | macro_rules! foo { () => {} } | = note: `foo` must be defined only once in the macro namespace of this module -error: aborting due to previous error +error[E0428]: the name `bar` is defined multiple times + --> $DIR/issue-38715.rs:14:5 + | +LL | macro_rules! bar { () => {} } + | ---------------- previous definition of the macro `bar` here +... +LL | macro_rules! bar { () => {} } + | ^^^^^^^^^^^^^^^^ `bar` redefined here + | + = note: `bar` must be defined only once in the macro namespace of this module + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/privacy/effective_visibilities.rs b/src/test/ui/privacy/effective_visibilities.rs index 1d806a1d1d167..c1f9ee8dfdf73 100644 --- a/src/test/ui/privacy/effective_visibilities.rs +++ b/src/test/ui/privacy/effective_visibilities.rs @@ -38,13 +38,13 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub } #[rustc_effective_visibility] - macro_rules! none_macro { //~ Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) + macro_rules! none_macro { //~ ERROR not in the table () => {}; } #[macro_export] #[rustc_effective_visibility] - macro_rules! public_macro { //~ Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + macro_rules! public_macro { //~ ERROR Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub () => {}; } diff --git a/src/test/ui/privacy/effective_visibilities.stderr b/src/test/ui/privacy/effective_visibilities.stderr index 1c6201600b630..5a8f7db38fc8a 100644 --- a/src/test/ui/privacy/effective_visibilities.stderr +++ b/src/test/ui/privacy/effective_visibilities.stderr @@ -64,13 +64,13 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl LL | PubUnion, | ^^^^^^^^ -error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) +error: not in the table --> $DIR/effective_visibilities.rs:41:5 | LL | macro_rules! none_macro { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub +error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub --> $DIR/effective_visibilities.rs:47:5 | LL | macro_rules! public_macro { From f0240fde5f31d8ed49c7cd40d4b8b6a167fba143 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 31 Oct 2022 11:53:00 -0700 Subject: [PATCH 006/482] rustdoc: remove unnecessary CSS `.search-results { clear: both }` Since the tabs use flexbox instead of float as of 44d9b8d07014d976c88f541dbe0af37e64e37bdd, clearing does nothing. --- src/librustdoc/html/static/css/rustdoc.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 30dc84509246e..43834c136eabd 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -880,8 +880,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ .search-results.active { display: block; - /* prevent overhanging tabs from moving the first result */ - clear: both; } .search-results .desc > span { From 090fadc9b5e6b369ed84fefcb48b68c616f0718f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 31 Oct 2022 13:12:51 -0700 Subject: [PATCH 007/482] rustdoc: rename syntax highlighting CSS class `attribute` to `attr` Link classes use the abbreviation `attr`, so why shouldn't syntax highlighting? --- src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/html/highlight/fixtures/sample.html | 8 ++++---- src/librustdoc/html/highlight/tests.rs | 2 +- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/test/rustdoc-gui/highlight-colors.goml | 10 +++++----- src/test/rustdoc/issue-41783.codeblock.html | 2 +- src/test/rustdoc/issue-41783.rs | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 28136cc48d658..cd8c8c463b1ab 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -362,7 +362,7 @@ impl Class { match self { Class::Comment => "comment", Class::DocComment => "doccomment", - Class::Attribute => "attribute", + Class::Attribute => "attr", Class::KeyWord => "kw", Class::RefKeyWord => "kw-2", Class::Self_(_) => "self", diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html index 4a5a3cf609cd4..fced2eacd9e72 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.html +++ b/src/librustdoc/html/highlight/fixtures/sample.html @@ -3,16 +3,16 @@ .kw { color: #8959A8; } .kw-2, .prelude-ty { color: #4271AE; } .number, .string { color: #718C00; } -.self, .bool-val, .prelude-val, .attribute, .attribute .ident { color: #C82829; } +.self, .bool-val, .prelude-val, .attr, .attr .ident { color: #C82829; } .macro, .macro-nonterminal { color: #3E999F; } .lifetime { color: #B76514; } .question-mark { color: #ff9011; } -
#![crate_type = "lib"]
+
#![crate_type = "lib"]
 
 use std::path::{Path, PathBuf};
 
-#[cfg(target_os = "linux")]
+#[cfg(target_os = "linux")]
 #[cfg(target_os = "windows")]
 fn main() -> () {
     let foo = true && false || true;
@@ -23,7 +23,7 @@
     mac!(foo, &mut bar);
     assert!(self.length < N && index <= self.length);
     ::std::env::var("gateau").is_ok();
-    #[rustfmt::skip]
+    #[rustfmt::skip]
     let s:std::path::PathBuf = std::path::PathBuf::new();
     let mut s = String::new();
 
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index a5e633df43448..2c93b9a097f40 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -9,7 +9,7 @@ const STYLE: &str = r#"
 .kw { color: #8959A8; }
 .kw-2, .prelude-ty { color: #4271AE; }
 .number, .string { color: #718C00; }
-.self, .bool-val, .prelude-val, .attribute, .attribute .ident { color: #C82829; }
+.self, .bool-val, .prelude-val, .attr, .attr .ident { color: #C82829; }
 .macro, .macro-nonterminal { color: #3E999F; }
 .lifetime { color: #B76514; }
 .question-mark { color: #ff9011; }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 43834c136eabd..219d1b4ed53ff 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1090,7 +1090,7 @@ pre.rust .bool-val {
 pre.rust .self {
 	color: var(--code-highlight-self-color);
 }
-pre.rust .attribute {
+pre.rust .attr {
 	color: var(--code-highlight-attribute-color);
 }
 pre.rust .macro,
diff --git a/src/test/rustdoc-gui/highlight-colors.goml b/src/test/rustdoc-gui/highlight-colors.goml
index 51693314e85ef..ff1be389dcb07 100644
--- a/src/test/rustdoc-gui/highlight-colors.goml
+++ b/src/test/rustdoc-gui/highlight-colors.goml
@@ -15,7 +15,7 @@ define-function: (
         string,
         bool_val,
         self,
-        attribute,
+        attr,
         macro,
         question_mark,
         comment,
@@ -33,7 +33,7 @@ define-function: (
         ("assert-css", ("pre.rust .string", {"color": |string|}, ALL)),
         ("assert-css", ("pre.rust .bool-val", {"color": |bool_val|}, ALL)),
         ("assert-css", ("pre.rust .self", {"color": |self|}, ALL)),
-        ("assert-css", ("pre.rust .attribute", {"color": |attribute|}, ALL)),
+        ("assert-css", ("pre.rust .attr", {"color": |attr|}, ALL)),
         ("assert-css", ("pre.rust .macro", {"color": |macro|}, ALL)),
         ("assert-css", ("pre.rust .question-mark", {"color": |question_mark|}, ALL)),
         ("assert-css", ("pre.rust .comment", {"color": |comment|}, ALL)),
@@ -52,7 +52,7 @@ call-function: ("check-colors", {
     "string": "rgb(184, 204, 82)",
     "bool_val": "rgb(255, 119, 51)",
     "self": "rgb(54, 163, 217)",
-    "attribute": "rgb(230, 225, 207)",
+    "attr": "rgb(230, 225, 207)",
     "macro": "rgb(163, 122, 204)",
     "question_mark": "rgb(255, 144, 17)",
     "comment": "rgb(120, 135, 151)",
@@ -69,7 +69,7 @@ call-function: ("check-colors", {
     "string": "rgb(131, 163, 0)",
     "bool_val": "rgb(238, 104, 104)",
     "self": "rgb(238, 104, 104)",
-    "attribute": "rgb(238, 104, 104)",
+    "attr": "rgb(238, 104, 104)",
     "macro": "rgb(62, 153, 159)",
     "question_mark": "rgb(255, 144, 17)",
     "comment": "rgb(141, 141, 139)",
@@ -86,7 +86,7 @@ call-function: ("check-colors", {
     "string": "rgb(113, 140, 0)",
     "bool_val": "rgb(200, 40, 41)",
     "self": "rgb(200, 40, 41)",
-    "attribute": "rgb(200, 40, 41)",
+    "attr": "rgb(200, 40, 41)",
     "macro": "rgb(62, 153, 159)",
     "question_mark": "rgb(255, 144, 17)",
     "comment": "rgb(142, 144, 140)",
diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html
index 89987491d1b46..3bca4536cd5b6 100644
--- a/src/test/rustdoc/issue-41783.codeblock.html
+++ b/src/test/rustdoc/issue-41783.codeblock.html
@@ -1,5 +1,5 @@
 # single
 ## double
 ### triple
-#[outer]
+#[outer]
 #![inner]
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs
index 87267a750c615..769f984a274a7 100644
--- a/src/test/rustdoc/issue-41783.rs
+++ b/src/test/rustdoc/issue-41783.rs
@@ -1,10 +1,10 @@
 // @has issue_41783/struct.Foo.html
 // @!hasraw - 'space'
 // @!hasraw - 'comment'
-// @hasraw - '#[outer]'
-// @!hasraw - '#[outer]'
+// @hasraw - '#[outer]'
+// @!hasraw - '#[outer]'
 // @hasraw - '#![inner]'
-// @!hasraw - '#![inner]'
+// @!hasraw - '#![inner]'
 // @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code'
 
 /// ```no_run

From 247ba52f42587821eb00861be7f5ff31fd39aebb Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Mon, 24 Oct 2022 14:56:58 +0200
Subject: [PATCH 008/482] fix: Don't respond with an error when requesting a
 shutdown while starting

---
 .../crates/rust-analyzer/src/main_loop.rs     | 46 ++++++++++---------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 2c928a580405c..7d10dc5d15b62 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -607,30 +607,34 @@ impl GlobalState {
 
     /// Handles a request.
     fn on_request(&mut self, req: Request) {
-        if self.shutdown_requested {
-            self.respond(lsp_server::Response::new_err(
-                req.id,
-                lsp_server::ErrorCode::InvalidRequest as i32,
-                "Shutdown already requested.".to_owned(),
-            ));
-            return;
-        }
+        let mut dispatcher = RequestDispatcher { req: Some(req), global_state: self };
+        dispatcher.on_sync_mut::(|s, ()| {
+            s.shutdown_requested = true;
+            Ok(())
+        });
+
+        if let RequestDispatcher { req: Some(req), global_state: this } = &mut dispatcher {
+            if this.shutdown_requested {
+                this.respond(lsp_server::Response::new_err(
+                    req.id.clone(),
+                    lsp_server::ErrorCode::InvalidRequest as i32,
+                    "Shutdown already requested.".to_owned(),
+                ));
+                return;
+            }
 
-        // Avoid flashing a bunch of unresolved references during initial load.
-        if self.workspaces.is_empty() && !self.is_quiescent() {
-            self.respond(lsp_server::Response::new_err(
-                req.id,
-                lsp_server::ErrorCode::ContentModified as i32,
-                "waiting for cargo metadata or cargo check".to_owned(),
-            ));
-            return;
+            // Avoid flashing a bunch of unresolved references during initial load.
+            if this.workspaces.is_empty() && !this.is_quiescent() {
+                this.respond(lsp_server::Response::new_err(
+                    req.id.clone(),
+                    lsp_server::ErrorCode::ContentModified as i32,
+                    "waiting for cargo metadata or cargo check".to_owned(),
+                ));
+                return;
+            }
         }
 
-        RequestDispatcher { req: Some(req), global_state: self }
-            .on_sync_mut::(|s, ()| {
-                s.shutdown_requested = true;
-                Ok(())
-            })
+        dispatcher
             .on_sync_mut::(handlers::handle_workspace_reload)
             .on_sync_mut::(handlers::handle_memory_usage)
             .on_sync_mut::(handlers::handle_shuffle_crate_graph)

From 285db019398610d4bd5ee3c418023fbf7637edd4 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Mon, 24 Oct 2022 16:07:42 +0200
Subject: [PATCH 009/482] fix: Fix standard flycheck command not being executed
 in the workspace it is being invoked for

---
 src/tools/rust-analyzer/crates/flycheck/src/lib.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
index 73c3a48b4c5a3..8a91d6066614f 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
@@ -295,7 +295,9 @@ impl FlycheckActor {
             } => {
                 let mut cmd = Command::new(toolchain::cargo());
                 cmd.arg(command);
-                cmd.args(&["--workspace", "--message-format=json"]);
+                cmd.current_dir(&self.root);
+                cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
+                    .arg(self.root.join("Cargo.toml").as_os_str());
 
                 if let Some(target) = target_triple {
                     cmd.args(&["--target", target.as_str()]);

From 47c80b1452a4f69868fe176b1f41626f17c1d351 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Mon, 24 Oct 2022 19:38:16 +0900
Subject: [PATCH 010/482] Refactor: unwrap `Option` once in the beginning of
 closure

---
 .../rust-analyzer/crates/hir/src/source_analyzer.rs   | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 07bae2b38c796..9ec52282829a0 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -487,9 +487,9 @@ impl SourceAnalyzer {
 
         let mut prefer_value_ns = false;
         let resolved = (|| {
+            let infer = self.infer.as_deref()?;
             if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
                 let expr_id = self.expr_id(db, &path_expr.into())?;
-                let infer = self.infer.as_ref()?;
                 if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
                     let assoc = match assoc {
                         AssocItemId::FunctionId(f_in_trait) => {
@@ -520,18 +520,18 @@ impl SourceAnalyzer {
                 prefer_value_ns = true;
             } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
                 let pat_id = self.pat_id(&path_pat.into())?;
-                if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
+                if let Some(assoc) = infer.assoc_resolutions_for_pat(pat_id) {
                     return Some(PathResolution::Def(AssocItem::from(assoc).into()));
                 }
                 if let Some(VariantId::EnumVariantId(variant)) =
-                    self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
+                    infer.variant_resolution_for_pat(pat_id)
                 {
                     return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
                 }
             } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
                 let expr_id = self.expr_id(db, &rec_lit.into())?;
                 if let Some(VariantId::EnumVariantId(variant)) =
-                    self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
+                    infer.variant_resolution_for_expr(expr_id)
                 {
                     return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
                 }
@@ -541,8 +541,7 @@ impl SourceAnalyzer {
                     || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
                 if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
                     let pat_id = self.pat_id(&pat)?;
-                    let variant_res_for_pat =
-                        self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
+                    let variant_res_for_pat = infer.variant_resolution_for_pat(pat_id);
                     if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
                         return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
                     }

From 0b873f39dcef7254a28b1fc43f2cfd1f3fb9d17b Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Mon, 24 Oct 2022 23:28:53 +0900
Subject: [PATCH 011/482] Let `InferenceTable::unify()` relate `Zip` values

---
 .../rust-analyzer/crates/hir-ty/src/infer/unify.rs   | 12 ++++++++----
 .../crates/hir-ty/src/method_resolution.rs           |  2 +-
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index b00e3216b2d2c..12f45f00f9c4d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -340,8 +340,8 @@ impl<'a> InferenceTable<'a> {
         self.resolve_with_fallback(t, &|_, _, d, _| d)
     }
 
-    /// Unify two types and register new trait goals that arise from that.
-    pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
+    /// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
+    pub(crate) fn unify>(&mut self, ty1: &T, ty2: &T) -> bool {
         let result = match self.try_unify(ty1, ty2) {
             Ok(r) => r,
             Err(_) => return false,
@@ -350,9 +350,13 @@ impl<'a> InferenceTable<'a> {
         true
     }
 
-    /// Unify two types and return new trait goals arising from it, so the
+    /// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
     /// caller needs to deal with them.
-    pub(crate) fn try_unify>(&mut self, t1: &T, t2: &T) -> InferResult<()> {
+    pub(crate) fn try_unify>(
+        &mut self,
+        t1: &T,
+        t2: &T,
+    ) -> InferResult<()> {
         match self.var_unification_table.relate(
             Interner,
             &self.db,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 3a1a3f4fdeb3b..3c6646333a06e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -1214,7 +1214,7 @@ fn is_valid_fn_candidate(
             let expected_receiver =
                 sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
 
-            check_that!(table.unify(&receiver_ty, &expected_receiver));
+            check_that!(table.unify(receiver_ty, &expected_receiver));
         }
 
         if let ItemContainerId::ImplId(impl_id) = container {

From b56fdf892c610d794cb22add400d434f5629e28e Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Tue, 25 Oct 2022 21:20:16 +0900
Subject: [PATCH 012/482] Test all generic args for trait when finding matching
 impl

---
 .../crates/hir-ty/src/method_resolution.rs    | 82 ++++++++++++-------
 .../crates/hir/src/source_analyzer.rs         | 54 +++++-------
 .../crates/ide/src/goto_definition.rs         | 82 +++++++++++++++++++
 3 files changed, 156 insertions(+), 62 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 3c6646333a06e..50859475e1d94 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -22,10 +22,10 @@ use crate::{
     from_foreign_def_id,
     infer::{unify::InferenceTable, Adjust, Adjustment, AutoBorrow, OverloadedDeref, PointerCast},
     primitive::{FloatTy, IntTy, UintTy},
-    static_lifetime,
+    static_lifetime, to_chalk_trait_id,
     utils::all_super_traits,
     AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
-    Scalar, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
+    Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
 };
 
 /// This is used as a key for indexing impls.
@@ -624,52 +624,76 @@ pub(crate) fn iterate_method_candidates(
     slot
 }
 
+/// Looks up the impl method that actually runs for the trait method `func`.
+///
+/// Returns `func` if it's not a method defined in a trait or the lookup failed.
 pub fn lookup_impl_method(
-    self_ty: &Ty,
     db: &dyn HirDatabase,
     env: Arc,
-    trait_: TraitId,
+    func: FunctionId,
+    fn_subst: Substitution,
+) -> FunctionId {
+    let trait_id = match func.lookup(db.upcast()).container {
+        ItemContainerId::TraitId(id) => id,
+        _ => return func,
+    };
+    let trait_params = db.generic_params(trait_id.into()).type_or_consts.len();
+    let fn_params = fn_subst.len(Interner) - trait_params;
+    let trait_ref = TraitRef {
+        trait_id: to_chalk_trait_id(trait_id),
+        substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).skip(fn_params)),
+    };
+
+    let name = &db.function_data(func).name;
+    lookup_impl_method_for_trait_ref(trait_ref, db, env, name).unwrap_or(func)
+}
+
+fn lookup_impl_method_for_trait_ref(
+    trait_ref: TraitRef,
+    db: &dyn HirDatabase,
+    env: Arc,
     name: &Name,
 ) -> Option {
-    let self_ty_fp = TyFingerprint::for_trait_impl(self_ty)?;
-    let trait_impls = db.trait_impls_in_deps(env.krate);
-    let impls = trait_impls.for_trait_and_self_ty(trait_, self_ty_fp);
-    let mut table = InferenceTable::new(db, env.clone());
-    find_matching_impl(impls, &mut table, &self_ty).and_then(|data| {
-        data.items.iter().find_map(|it| match it {
-            AssocItemId::FunctionId(f) => (db.function_data(*f).name == *name).then(|| *f),
-            _ => None,
-        })
+    let self_ty = trait_ref.self_type_parameter(Interner);
+    let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
+    let impls = db.trait_impls_in_deps(env.krate);
+    let impls = impls.for_trait_and_self_ty(trait_ref.hir_trait_id(), self_ty_fp);
+
+    let table = InferenceTable::new(db, env);
+
+    let impl_data = find_matching_impl(impls, table, trait_ref)?;
+    impl_data.items.iter().find_map(|it| match it {
+        AssocItemId::FunctionId(f) => (db.function_data(*f).name == *name).then(|| *f),
+        _ => None,
     })
 }
 
 fn find_matching_impl(
     mut impls: impl Iterator,
-    table: &mut InferenceTable<'_>,
-    self_ty: &Ty,
+    mut table: InferenceTable<'_>,
+    actual_trait_ref: TraitRef,
 ) -> Option> {
     let db = table.db;
     loop {
         let impl_ = impls.next()?;
         let r = table.run_in_snapshot(|table| {
             let impl_data = db.impl_data(impl_);
-            let substs =
+            let impl_substs =
                 TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
-            let impl_ty = db.impl_self_ty(impl_).substitute(Interner, &substs);
-
-            table
-                .unify(self_ty, &impl_ty)
-                .then(|| {
-                    let wh_goals =
-                        crate::chalk_db::convert_where_clauses(db, impl_.into(), &substs)
-                            .into_iter()
-                            .map(|b| b.cast(Interner));
+            let trait_ref = db
+                .impl_trait(impl_)
+                .expect("non-trait method in find_matching_impl")
+                .substitute(Interner, &impl_substs);
 
-                    let goal = crate::Goal::all(Interner, wh_goals);
+            if !table.unify(&trait_ref, &actual_trait_ref) {
+                return None;
+            }
 
-                    table.try_obligation(goal).map(|_| impl_data)
-                })
-                .flatten()
+            let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs)
+                .into_iter()
+                .map(|b| b.cast(Interner));
+            let goal = crate::Goal::all(Interner, wcs);
+            table.try_obligation(goal).map(|_| impl_data)
         });
         if r.is_some() {
             break r;
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 9ec52282829a0..f86c571005367 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -270,7 +270,7 @@ impl SourceAnalyzer {
         let expr_id = self.expr_id(db, &call.clone().into())?;
         let (f_in_trait, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
 
-        Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
     }
 
     pub(crate) fn resolve_await_to_poll(
@@ -311,7 +311,7 @@ impl SourceAnalyzer {
         // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
         // doesn't have any generic parameters, so we skip building another subst for `poll()`.
         let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
-        Some(self.resolve_impl_method_or_trait_def(db, poll_fn, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs))
     }
 
     pub(crate) fn resolve_prefix_expr(
@@ -331,7 +331,7 @@ impl SourceAnalyzer {
         // don't have any generic parameters, so we skip building another subst for the methods.
         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
 
-        Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
     }
 
     pub(crate) fn resolve_index_expr(
@@ -351,7 +351,7 @@ impl SourceAnalyzer {
             .push(base_ty.clone())
             .push(index_ty.clone())
             .build();
-        Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
     }
 
     pub(crate) fn resolve_bin_expr(
@@ -372,7 +372,7 @@ impl SourceAnalyzer {
             .push(rhs.clone())
             .build();
 
-        Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
     }
 
     pub(crate) fn resolve_try_expr(
@@ -392,7 +392,7 @@ impl SourceAnalyzer {
         // doesn't have any generic parameters, so we skip building another subst for `branch()`.
         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
 
-        Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
     }
 
     pub(crate) fn resolve_field(
@@ -497,9 +497,12 @@ impl SourceAnalyzer {
                                 None => assoc,
                                 Some(func_ty) => {
                                     if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) {
-                                        self.resolve_impl_method(db, f_in_trait, subs)
-                                            .map(AssocItemId::FunctionId)
-                                            .unwrap_or(assoc)
+                                        self.resolve_impl_method_or_trait_def(
+                                            db,
+                                            f_in_trait,
+                                            subs.clone(),
+                                        )
+                                        .into()
                                     } else {
                                         assoc
                                     }
@@ -779,37 +782,22 @@ impl SourceAnalyzer {
         false
     }
 
-    fn resolve_impl_method(
+    fn resolve_impl_method_or_trait_def(
         &self,
         db: &dyn HirDatabase,
         func: FunctionId,
-        substs: &Substitution,
-    ) -> Option {
-        let impled_trait = match func.lookup(db.upcast()).container {
-            ItemContainerId::TraitId(trait_id) => trait_id,
-            _ => return None,
-        };
-        if substs.is_empty(Interner) {
-            return None;
-        }
-        let self_ty = substs.at(Interner, 0).ty(Interner)?;
+        substs: Substitution,
+    ) -> FunctionId {
         let krate = self.resolver.krate();
-        let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
+        let owner = match self.resolver.body_owner() {
+            Some(it) => it,
+            None => return func,
+        };
+        let env = owner.as_generic_def_id().map_or_else(
             || Arc::new(hir_ty::TraitEnvironment::empty(krate)),
             |d| db.trait_environment(d),
         );
-
-        let fun_data = db.function_data(func);
-        method_resolution::lookup_impl_method(self_ty, db, trait_env, impled_trait, &fun_data.name)
-    }
-
-    fn resolve_impl_method_or_trait_def(
-        &self,
-        db: &dyn HirDatabase,
-        func: FunctionId,
-        substs: &Substitution,
-    ) -> FunctionId {
-        self.resolve_impl_method(db, func, substs).unwrap_or(func)
+        method_resolution::lookup_impl_method(db, env, func, substs)
     }
 
     fn lang_trait_fn(
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index d0be1b3f40479..f97c67b144ac1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -1834,4 +1834,86 @@ fn f() {
 "#,
         );
     }
+
+    #[test]
+    fn goto_bin_op_multiple_impl() {
+        check(
+            r#"
+//- minicore: add
+struct S;
+impl core::ops::Add for S {
+    fn add(
+     //^^^
+    ) {}
+}
+impl core::ops::Add for S {
+    fn add(
+    ) {}
+}
+
+fn f() {
+    S +$0 S
+}
+"#,
+        );
+
+        check(
+            r#"
+//- minicore: add
+struct S;
+impl core::ops::Add for S {
+    fn add(
+    ) {}
+}
+impl core::ops::Add for S {
+    fn add(
+     //^^^
+    ) {}
+}
+
+fn f() {
+    S +$0 0usize
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn path_call_multiple_trait_impl() {
+        check(
+            r#"
+trait Trait {
+    fn f(_: T);
+}
+impl Trait for usize {
+    fn f(_: i32) {}
+     //^
+}
+impl Trait for usize {
+    fn f(_: i64) {}
+}
+fn main() {
+    usize::f$0(0i32);
+}
+"#,
+        );
+
+        check(
+            r#"
+trait Trait {
+    fn f(_: T);
+}
+impl Trait for usize {
+    fn f(_: i32) {}
+}
+impl Trait for usize {
+    fn f(_: i64) {}
+     //^
+}
+fn main() {
+    usize::f$0(0i64);
+}
+"#,
+        )
+    }
 }

From c6e3237bfb714f858ec9cea10123470756b1e9c3 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Wed, 26 Oct 2022 16:41:11 +0900
Subject: [PATCH 013/482] refactor: remove obsolete code

---
 src/tools/rust-analyzer/crates/hir-ty/src/lib.rs | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index c4b700cbce6db..8458a4fe1cd15 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -124,14 +124,6 @@ pub type ConstrainedSubst = chalk_ir::ConstrainedSubst;
 pub type Guidance = chalk_solve::Guidance;
 pub type WhereClause = chalk_ir::WhereClause;
 
-// FIXME: get rid of this
-pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
-    Substitution::from_iter(
-        Interner,
-        s.as_slice(Interner)[..std::cmp::min(s.len(Interner), n)].iter().cloned(),
-    )
-}
-
 /// Return an index of a parameter in the generic type parameter list by it's id.
 pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option {
     generics(db.upcast(), id.parent).param_idx(id)
@@ -382,7 +374,6 @@ pub(crate) fn fold_tys_and_consts + TypeFold
 pub fn replace_errors_with_variables(t: &T) -> Canonical
 where
     T: HasInterner + TypeFoldable + Clone,
-    T: HasInterner,
 {
     use chalk_ir::{
         fold::{FallibleTypeFolder, TypeSuperFoldable},

From 07ef106316994fdf82a583dbbf84d77a99655b88 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Thu, 27 Oct 2022 17:05:22 +0900
Subject: [PATCH 014/482] Display generic arguments for associated types

---
 .../crates/hir-ty/src/display.rs              | 36 +++++++++++++------
 .../hir-ty/src/tests/display_source_code.rs   | 31 ++++++++++++++++
 .../rust-analyzer/crates/hir-ty/src/tls.rs    | 28 +++++++++++----
 3 files changed, 78 insertions(+), 17 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 0221f922feb2f..5ad6613263534 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -289,16 +289,18 @@ impl HirDisplay for ProjectionTy {
             return write!(f, "{}", TYPE_HINT_TRUNCATION);
         }
 
-        let trait_ = f.db.trait_data(self.trait_(f.db));
+        let trait_ref = self.trait_ref(f.db);
         write!(f, "<")?;
-        self.self_type_parameter(f.db).hir_fmt(f)?;
-        write!(f, " as {}", trait_.name)?;
-        if self.substitution.len(Interner) > 1 {
+        fmt_trait_ref(&trait_ref, f, true)?;
+        write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
+        let proj_params_count =
+            self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
+        let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
+        if !proj_params.is_empty() {
             write!(f, "<")?;
-            f.write_joined(&self.substitution.as_slice(Interner)[1..], ", ")?;
+            f.write_joined(proj_params, ", ")?;
             write!(f, ">")?;
         }
-        write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
         Ok(())
     }
 }
@@ -641,9 +643,12 @@ impl HirDisplay for Ty {
                 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
                 if f.display_target.is_test() {
                     write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
+                    // Note that the generic args for the associated type come before those for the
+                    // trait (including the self type).
+                    // FIXME: reconsider the generic args order upon formatting?
                     if parameters.len(Interner) > 0 {
                         write!(f, "<")?;
-                        f.write_joined(&*parameters.as_slice(Interner), ", ")?;
+                        f.write_joined(parameters.as_slice(Interner), ", ")?;
                         write!(f, ">")?;
                     }
                 } else {
@@ -972,9 +977,20 @@ fn write_bounds_like_dyn_trait(
                     angle_open = true;
                 }
                 if let AliasTy::Projection(proj) = alias {
-                    let type_alias =
-                        f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
-                    write!(f, "{} = ", type_alias.name)?;
+                    let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
+                    let type_alias = f.db.type_alias_data(assoc_ty_id);
+                    write!(f, "{}", type_alias.name)?;
+
+                    let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self();
+                    if proj_arg_count > 0 {
+                        write!(f, "<")?;
+                        f.write_joined(
+                            &proj.substitution.as_slice(Interner)[..proj_arg_count],
+                            ", ",
+                        )?;
+                        write!(f, ">")?;
+                    }
+                    write!(f, " = ")?;
                 }
                 ty.hir_fmt(f)?;
             }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
index 8a8ff08cfe8cd..425432479e815 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
@@ -196,3 +196,34 @@ fn test(
 "#,
     );
 }
+
+#[test]
+fn projection_type_correct_arguments_order() {
+    check_types_source_code(
+        r#"
+trait Foo {
+    type Assoc;
+}
+fn f>(a: T::Assoc) {
+    a;
+  //^ >::Assoc
+}
+"#,
+    );
+}
+
+#[test]
+fn generic_associated_type_binding_in_impl_trait() {
+    check_types_source_code(
+        r#"
+//- minicore: sized
+trait Foo {
+    type Assoc;
+}
+fn f(a: impl Foo = i32>) {
+    a;
+  //^ impl Foo = i32>
+}
+        "#,
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
index 547850b021c3c..92711a24fe39f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
@@ -5,7 +5,7 @@ use itertools::Itertools;
 
 use crate::{
     chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
-    CallableDefId, Interner,
+    CallableDefId, Interner, ProjectionTyExt,
 };
 use hir_def::{AdtId, ItemContainerId, Lookup, TypeAliasId};
 
@@ -63,17 +63,31 @@ impl DebugContext<'_> {
             ItemContainerId::TraitId(t) => t,
             _ => panic!("associated type not in trait"),
         };
-        let trait_data = self.0.trait_data(trait_);
-        let params = projection_ty.substitution.as_slice(Interner);
-        write!(fmt, "<{:?} as {}", ¶ms[0], trait_data.name,)?;
-        if params.len() > 1 {
+        let trait_name = &self.0.trait_data(trait_).name;
+        let trait_ref = projection_ty.trait_ref(self.0);
+        let trait_params = trait_ref.substitution.as_slice(Interner);
+        let self_ty = trait_ref.self_type_parameter(Interner);
+        write!(fmt, "<{:?} as {}", self_ty, trait_name)?;
+        if trait_params.len() > 1 {
+            write!(
+                fmt,
+                "<{}>",
+                trait_params[1..].iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
+            )?;
+        }
+        write!(fmt, ">::{}", type_alias_data.name)?;
+
+        let proj_params_count = projection_ty.substitution.len(Interner) - trait_params.len();
+        let proj_params = &projection_ty.substitution.as_slice(Interner)[..proj_params_count];
+        if !proj_params.is_empty() {
             write!(
                 fmt,
                 "<{}>",
-                ¶ms[1..].iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
+                proj_params.iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
             )?;
         }
-        write!(fmt, ">::{}", type_alias_data.name)
+
+        Ok(())
     }
 
     pub(crate) fn debug_fn_def_id(

From 2fcec1f0e2137531e941023a5bc91a80e2bf205c Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Wed, 26 Oct 2022 17:21:08 +0900
Subject: [PATCH 015/482] Lower generic arguments for associated types in paths

---
 .../crates/hir-ty/src/chalk_ext.rs            |  17 ++-
 .../crates/hir-ty/src/infer/path.rs           |   2 +-
 .../rust-analyzer/crates/hir-ty/src/lower.rs  |  93 +++++++++-----
 .../crates/hir-ty/src/tests/traits.rs         | 120 ++++++++++++++++++
 4 files changed, 193 insertions(+), 39 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
index e2099d7e50927..996b42f5bd83c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
@@ -11,9 +11,9 @@ use syntax::SmolStr;
 
 use crate::{
     db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
-    from_placeholder_idx, to_chalk_trait_id, AdtId, AliasEq, AliasTy, Binders, CallableDefId,
-    CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause,
-    Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
+    from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
+    CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
+    QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
 };
 
 pub trait TyExt {
@@ -338,10 +338,13 @@ pub trait ProjectionTyExt {
 
 impl ProjectionTyExt for ProjectionTy {
     fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
-        TraitRef {
-            trait_id: to_chalk_trait_id(self.trait_(db)),
-            substitution: self.substitution.clone(),
-        }
+        // FIXME: something like `Split` trait from chalk-solve might be nice.
+        let generics = generics(db.upcast(), from_assoc_type_id(self.associated_ty_id).into());
+        let substitution = Substitution::from_iter(
+            Interner,
+            self.substitution.iter(Interner).skip(generics.len_self()),
+        );
+        TraitRef { trait_id: to_chalk_trait_id(self.trait_(db)), substitution }
     }
 
     fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
index 7a4754cdc7bb8..ebe9d6fb5e014 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -157,7 +157,7 @@ impl<'a> InferenceContext<'a> {
                     remaining_segments_for_ty,
                     true,
                 );
-                if let TyKind::Error = ty.kind(Interner) {
+                if ty.is_unknown() {
                     return None;
                 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 223d705b157b3..4447927451896 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -447,12 +447,31 @@ impl<'a> TyLoweringContext<'a> {
                             .db
                             .trait_data(trait_ref.hir_trait_id())
                             .associated_type_by_name(segment.name);
+
                         match found {
                             Some(associated_ty) => {
-                                // FIXME handle type parameters on the segment
+                                // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
+                                // generic params. It's inefficient to splice the `Substitution`s, so we may want
+                                // that method to optionally take parent `Substitution` as we already know them at
+                                // this point (`trait_ref.substitution`).
+                                let substitution = self.substs_from_path_segment(
+                                    segment,
+                                    Some(associated_ty.into()),
+                                    false,
+                                    None,
+                                );
+                                let len_self =
+                                    generics(self.db.upcast(), associated_ty.into()).len_self();
+                                let substitution = Substitution::from_iter(
+                                    Interner,
+                                    substitution
+                                        .iter(Interner)
+                                        .take(len_self)
+                                        .chain(trait_ref.substitution.iter(Interner)),
+                                );
                                 TyKind::Alias(AliasTy::Projection(ProjectionTy {
                                     associated_ty_id: to_assoc_type_id(associated_ty),
-                                    substitution: trait_ref.substitution,
+                                    substitution,
                                 }))
                                 .intern(Interner)
                             }
@@ -590,36 +609,48 @@ impl<'a> TyLoweringContext<'a> {
             res,
             Some(segment.name.clone()),
             move |name, t, associated_ty| {
-                if name == segment.name {
-                    let substs = match self.type_param_mode {
-                        ParamLoweringMode::Placeholder => {
-                            // if we're lowering to placeholders, we have to put
-                            // them in now
-                            let generics = generics(
-                                self.db.upcast(),
-                                self.resolver
-                                    .generic_def()
-                                    .expect("there should be generics if there's a generic param"),
-                            );
-                            let s = generics.placeholder_subst(self.db);
-                            s.apply(t.substitution.clone(), Interner)
-                        }
-                        ParamLoweringMode::Variable => t.substitution.clone(),
-                    };
-                    // We need to shift in the bound vars, since
-                    // associated_type_shorthand_candidates does not do that
-                    let substs = substs.shifted_in_from(Interner, self.in_binders);
-                    // FIXME handle type parameters on the segment
-                    Some(
-                        TyKind::Alias(AliasTy::Projection(ProjectionTy {
-                            associated_ty_id: to_assoc_type_id(associated_ty),
-                            substitution: substs,
-                        }))
-                        .intern(Interner),
-                    )
-                } else {
-                    None
+                if name != segment.name {
+                    return None;
                 }
+
+                // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
+                // generic params. It's inefficient to splice the `Substitution`s, so we may want
+                // that method to optionally take parent `Substitution` as we already know them at
+                // this point (`t.substitution`).
+                let substs = self.substs_from_path_segment(
+                    segment.clone(),
+                    Some(associated_ty.into()),
+                    false,
+                    None,
+                );
+
+                let len_self = generics(self.db.upcast(), associated_ty.into()).len_self();
+
+                let substs = Substitution::from_iter(
+                    Interner,
+                    substs.iter(Interner).take(len_self).chain(t.substitution.iter(Interner)),
+                );
+
+                let substs = match self.type_param_mode {
+                    ParamLoweringMode::Placeholder => {
+                        // if we're lowering to placeholders, we have to put
+                        // them in now
+                        let generics = generics(self.db.upcast(), def);
+                        let s = generics.placeholder_subst(self.db);
+                        s.apply(substs, Interner)
+                    }
+                    ParamLoweringMode::Variable => substs,
+                };
+                // We need to shift in the bound vars, since
+                // associated_type_shorthand_candidates does not do that
+                let substs = substs.shifted_in_from(Interner, self.in_binders);
+                Some(
+                    TyKind::Alias(AliasTy::Projection(ProjectionTy {
+                        associated_ty_id: to_assoc_type_id(associated_ty),
+                        substitution: substs,
+                    }))
+                    .intern(Interner),
+                )
             },
         );
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index 555b6972fb71e..2b8468e85a172 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -3963,3 +3963,123 @@ fn g(t: &(dyn T + Send)) {
         "#,
     );
 }
+
+#[test]
+fn gats_in_path() {
+    check_infer_with_mismatches(
+        r#"
+//- minicore: deref
+use core::ops::Deref;
+trait PointerFamily {
+    type Pointer: Deref;
+}
+
+fn f(p: P::Pointer) {
+    let a = *p;
+}
+fn g(p: 

::Pointer) { + let a = *p; +} + "#, + expect![[r#" + 110..111 'p': PointerFamily::Pointer + 130..149 '{ ... *p; }': () + 140..141 'a': i32 + 144..146 '*p': i32 + 145..146 'p': PointerFamily::Pointer + 173..174 'p': PointerFamily::Pointer + 212..231 '{ ... *p; }': () + 222..223 'a': i32 + 226..228 '*p': i32 + 227..228 'p': PointerFamily::Pointer + "#]], + ); +} + +#[test] +fn gats_with_impl_trait() { + // FIXME: the last function (`fn h()`) is not valid Rust as of this writing because you cannot + // specify the same associated type multiple times even if their arguments are different. + // Reconsider how to treat these invalid types. + check_infer_with_mismatches( + r#" +//- minicore: deref +use core::ops::Deref; + +trait Trait { + type Assoc: Deref; + fn get(&self) -> Self::Assoc; +} + +fn f(v: impl Trait) { + v.get::().deref(); + v.get::().deref(); +} +fn g(v: impl Trait = &'a T>) { + let a = v.get::(); + let a = v.get::<()>(); +} +fn h(v: impl Trait = &'a i32, Assoc = &'a i64> { + let a = v.get::(); + let a = v.get::(); +} + "#, + expect![[r#" + 90..94 'self': &Self + 126..127 'v': impl Trait + 141..198 '{ ...f(); }': () + 147..148 'v': impl Trait + 147..161 'v.get::()': Trait::Assoc + 147..169 'v.get:...eref()': &i32 + 175..176 'v': impl Trait + 175..187 'v.get::()': Trait::Assoc + 175..195 'v.get:...eref()': &T + 207..208 'v': impl Trait = &T> + 240..296 '{ ...>(); }': () + 250..251 'a': &T + 254..255 'v': impl Trait = &T> + 254..266 'v.get::()': &T + 276..277 'a': Trait::Assoc<(), impl Trait = &T>> + 280..281 'v': impl Trait = &T> + 280..293 'v.get::<()>()': Trait::Assoc<(), impl Trait = &T>> + 302..303 'v': impl Trait = &i32, Assoc = &i64> + 360..419 '{ ...>(); }': () + 370..371 'a': &i32 + 374..375 'v': impl Trait = &i32, Assoc = &i64> + 374..388 'v.get::()': &i32 + 398..399 'a': &i64 + 402..403 'v': impl Trait = &i32, Assoc = &i64> + 402..416 'v.get::()': &i64 + "#]], + ); +} + +#[test] +fn gats_with_dyn() { + // This test is here to keep track of how we infer things despite traits with GATs being not + // object-safe currently. + // FIXME: reconsider how to treat these invalid types. + check_infer_with_mismatches( + r#" +//- minicore: deref +use core::ops::Deref; + +trait Trait { + type Assoc: Deref; + fn get(&self) -> Self::Assoc; +} + +fn f<'a>(v: &dyn Trait = &'a i32>) { + v.get::().deref(); +} + "#, + expect![[r#" + 90..94 'self': &Self + 127..128 'v': &(dyn Trait = &i32>) + 164..195 '{ ...f(); }': () + 170..171 'v': &(dyn Trait = &i32>) + 170..184 'v.get::()': &i32 + 170..192 'v.get:...eref()': &i32 + "#]], + ); +} From 68b5966477413d29a4948ba0577cf0e80c752bbc Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Wed, 26 Oct 2022 22:52:04 +0900 Subject: [PATCH 016/482] Collect generic arguments in associated type bindings --- .../crates/hir-def/src/item_tree/lower.rs | 8 ++- .../rust-analyzer/crates/hir-def/src/path.rs | 3 ++ .../crates/hir-def/src/path/lower.rs | 8 ++- .../rust-analyzer/crates/syntax/rust.ungram | 2 +- .../crates/syntax/src/ast/generated/nodes.rs | 54 +++++++++---------- 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 077a1b619dd5a..79249757d9e9b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -662,8 +662,12 @@ fn desugar_future_path(orig: TypeRef) -> Path { let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments().len() - 1).collect(); let mut last = GenericArgs::empty(); - let binding = - AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() }; + let binding = AssociatedTypeBinding { + name: name![Output], + args: None, + type_ref: Some(orig), + bounds: Vec::new(), + }; last.bindings.push(binding); generic_args.push(Some(Interned::new(last))); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs index 2f13a9fbf0e40..592223f7d85fe 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs @@ -68,6 +68,9 @@ pub struct GenericArgs { pub struct AssociatedTypeBinding { /// The name of the associated type. pub name: Name, + /// The generic arguments to the associated type. e.g. For `Trait = &'a T>`, this + /// would be `['a, T]`. + pub args: Option>, /// The type bound to this associated type (in `Item = T`, this would be the /// `T`). This can be `None` if there are bounds instead. pub type_ref: Option, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index 0428f1a398b1a..cfa3a6baaf8b4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -163,6 +163,10 @@ pub(super) fn lower_generic_args( ast::GenericArg::AssocTypeArg(assoc_type_arg) => { if let Some(name_ref) = assoc_type_arg.name_ref() { let name = name_ref.as_name(); + let args = assoc_type_arg + .generic_arg_list() + .and_then(|args| lower_generic_args(lower_ctx, args)) + .map(Interned::new); let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { l.bounds() @@ -171,7 +175,7 @@ pub(super) fn lower_generic_args( } else { Vec::new() }; - bindings.push(AssociatedTypeBinding { name, type_ref, bounds }); + bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds }); } } ast::GenericArg::LifetimeArg(lifetime_arg) => { @@ -214,6 +218,7 @@ fn lower_generic_args_from_fn_path( let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty()); bindings.push(AssociatedTypeBinding { name: name![Output], + args: None, type_ref: Some(type_ref), bounds: Vec::new(), }); @@ -222,6 +227,7 @@ fn lower_generic_args_from_fn_path( let type_ref = TypeRef::Tuple(Vec::new()); bindings.push(AssociatedTypeBinding { name: name![Output], + args: None, type_ref: Some(type_ref), bounds: Vec::new(), }); diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 894795435451c..5379732ac6c37 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -51,7 +51,7 @@ TypeArg = Type AssocTypeArg = - NameRef GenericParamList? (':' TypeBoundList | ('=' Type | ConstArg)) + NameRef GenericArgList? (':' TypeBoundList | ('=' Type | ConstArg)) LifetimeArg = Lifetime diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 449402e5f5b30..6cfb98d92fcf2 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -120,7 +120,7 @@ pub struct AssocTypeArg { impl ast::HasTypeBounds for AssocTypeArg {} impl AssocTypeArg { pub fn name_ref(&self) -> Option { support::child(&self.syntax) } - pub fn generic_param_list(&self) -> Option { support::child(&self.syntax) } + pub fn generic_arg_list(&self) -> Option { support::child(&self.syntax) } pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } pub fn ty(&self) -> Option { support::child(&self.syntax) } pub fn const_arg(&self) -> Option { support::child(&self.syntax) } @@ -142,16 +142,6 @@ impl ConstArg { pub fn expr(&self) -> Option { support::child(&self.syntax) } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericParamList { - pub(crate) syntax: SyntaxNode, -} -impl GenericParamList { - pub fn l_angle_token(&self) -> Option { support::token(&self.syntax, T![<]) } - pub fn generic_params(&self) -> AstChildren { support::children(&self.syntax) } - pub fn r_angle_token(&self) -> Option { support::token(&self.syntax, T![>]) } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TypeBoundList { pub(crate) syntax: SyntaxNode, @@ -527,6 +517,16 @@ impl Abi { pub fn extern_token(&self) -> Option { support::token(&self.syntax, T![extern]) } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct GenericParamList { + pub(crate) syntax: SyntaxNode, +} +impl GenericParamList { + pub fn l_angle_token(&self) -> Option { support::token(&self.syntax, T![<]) } + pub fn generic_params(&self) -> AstChildren { support::children(&self.syntax) } + pub fn r_angle_token(&self) -> Option { support::token(&self.syntax, T![>]) } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct WhereClause { pub(crate) syntax: SyntaxNode, @@ -1834,17 +1834,6 @@ impl AstNode for ConstArg { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for GenericParamList { - fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST } - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxNode { &self.syntax } -} impl AstNode for TypeBoundList { fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST } fn cast(syntax: SyntaxNode) -> Option { @@ -2153,6 +2142,17 @@ impl AstNode for Abi { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for GenericParamList { + fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for WhereClause { fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE } fn cast(syntax: SyntaxNode) -> Option { @@ -4263,11 +4263,6 @@ impl std::fmt::Display for ConstArg { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for GenericParamList { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for TypeBoundList { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -4408,6 +4403,11 @@ impl std::fmt::Display for Abi { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for GenericParamList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for WhereClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) From 0c70a716608e9eff44a76c2e16b94010b2c0e351 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Thu, 27 Oct 2022 17:11:16 +0900 Subject: [PATCH 017/482] Lower generic arguments for GATs in associated type bindings --- .../rust-analyzer/crates/hir-ty/src/lower.rs | 31 +++++++++++++++- .../crates/hir-ty/src/tests/traits.rs | 37 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 4447927451896..22a85cf154587 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -808,7 +808,15 @@ impl<'a> TyLoweringContext<'a> { // handle defaults. In expression or pattern path segments without // explicitly specified type arguments, missing type arguments are inferred // (i.e. defaults aren't used). - if !infer_args || had_explicit_args { + // Generic parameters for associated types are not supposed to have defaults, so we just + // ignore them. + let is_assoc_ty = if let GenericDefId::TypeAliasId(id) = def { + let container = id.lookup(self.db.upcast()).container; + matches!(container, ItemContainerId::TraitId(_)) + } else { + false + }; + if !is_assoc_ty && (!infer_args || had_explicit_args) { let defaults = self.db.generic_defaults(def); assert_eq!(total_len, defaults.len()); let parent_from = item_len - substs.len(); @@ -997,9 +1005,28 @@ impl<'a> TyLoweringContext<'a> { None => return SmallVec::new(), Some(t) => t, }; + // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent + // generic params. It's inefficient to splice the `Substitution`s, so we may want + // that method to optionally take parent `Substitution` as we already know them at + // this point (`super_trait_ref.substitution`). + let substitution = self.substs_from_path_segment( + // FIXME: This is hack. We shouldn't really build `PathSegment` directly. + PathSegment { name: &binding.name, args_and_bindings: binding.args.as_deref() }, + Some(associated_ty.into()), + false, // this is not relevant + Some(super_trait_ref.self_type_parameter(Interner)), + ); + let self_params = generics(self.db.upcast(), associated_ty.into()).len_self(); + let substitution = Substitution::from_iter( + Interner, + substitution + .iter(Interner) + .take(self_params) + .chain(super_trait_ref.substitution.iter(Interner)), + ); let projection_ty = ProjectionTy { associated_ty_id: to_assoc_type_id(associated_ty), - substitution: super_trait_ref.substitution, + substitution, }; let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity( binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 2b8468e85a172..7995f6446d07b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4083,3 +4083,40 @@ fn f<'a>(v: &dyn Trait = &'a i32>) { "#]], ); } + +#[test] +fn gats_in_associated_type_binding() { + check_infer_with_mismatches( + r#" +trait Trait { + type Assoc; + fn get(&self) -> Self::Assoc; +} + +fn f(t: T) +where + T: Trait = u32>, + T: Trait = usize>, +{ + let a = t.get::(); + let a = t.get::(); + let a = t.get::<()>(); +} + + "#, + expect![[r#" + 48..52 'self': &Self + 84..85 't': T + 164..252 '{ ...>(); }': () + 174..175 'a': u32 + 178..179 't': T + 178..192 't.get::()': u32 + 202..203 'a': usize + 206..207 't': T + 206..222 't.get:...ize>()': usize + 232..233 'a': Trait::Assoc<(), T> + 236..237 't': T + 236..249 't.get::<()>()': Trait::Assoc<(), T> + "#]], + ) +} From 818a00090530aa4eabb369e5f566a5ac27a1a325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Thu, 27 Oct 2022 16:35:07 +0300 Subject: [PATCH 018/482] Clarify feature policy --- src/tools/rust-analyzer/docs/dev/architecture.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/rust-analyzer/docs/dev/architecture.md b/src/tools/rust-analyzer/docs/dev/architecture.md index c173a239feab3..e3a4fdfda90c2 100644 --- a/src/tools/rust-analyzer/docs/dev/architecture.md +++ b/src/tools/rust-analyzer/docs/dev/architecture.md @@ -479,7 +479,9 @@ It is not cheap enough to enable in prod, and this is a bug which should be fixe ### Configurability rust-analyzer strives to be as configurable as possible while offering reasonable defaults where no configuration exists yet. +The rule of thumb is to enable most features by default unless they are buggy or degrade performance too much. There will always be features that some people find more annoying than helpful, so giving the users the ability to tweak or disable these is a big part of offering a good user experience. +Enabling them by default is a matter of discoverability, as many users end up don't know about some features even though they are presented in the manual. Mind the code--architecture gap: at the moment, we are using fewer feature flags than we really should. ### Serialization From ef5d73ec2d0e04eb8507f0b4a9bc666c696e9739 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Oct 2022 23:10:10 +0200 Subject: [PATCH 019/482] feat: Clicking the status bar item stops and starts the server --- src/tools/rust-analyzer/editors/code/src/ctx.ts | 13 ++++++++++--- src/tools/rust-analyzer/editors/code/src/main.ts | 4 +--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts index 044a9470aa947..8592950e1023d 100644 --- a/src/tools/rust-analyzer/editors/code/src/ctx.ts +++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts @@ -204,13 +204,13 @@ export class Ctx { } } - setServerStatus(status: ServerStatusParams) { + setServerStatus(status: ServerStatusParams | { health: "stopped" }) { let icon = ""; const statusBar = this.statusBar; switch (status.health) { case "ok": - statusBar.tooltip = status.message ?? "Ready"; - statusBar.command = undefined; + statusBar.tooltip = (status.message ?? "Ready") + "Click to stop."; + statusBar.command = "rust-analyzer.stopServer"; statusBar.color = undefined; statusBar.backgroundColor = undefined; break; @@ -234,6 +234,13 @@ export class Ctx { statusBar.backgroundColor = new vscode.ThemeColor("statusBarItem.errorBackground"); icon = "$(error) "; break; + case "stopped": + statusBar.tooltip = "Server is stopped. Click to start."; + statusBar.command = "rust-analyzer.startServer"; + statusBar.color = undefined; + statusBar.backgroundColor = undefined; + statusBar.text = `$(stop-circle) rust-analyzer`; + return; } if (!status.quiescent) icon = "$(sync~spin) "; statusBar.text = `${icon}rust-analyzer`; diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts index 8c3a676ffb056..5970533472667 100644 --- a/src/tools/rust-analyzer/editors/code/src/main.ts +++ b/src/tools/rust-analyzer/editors/code/src/main.ts @@ -120,9 +120,7 @@ function createCommands(): Record { // FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed await ctx.stop(); ctx.setServerStatus({ - health: "ok", - quiescent: true, - message: "server is not running", + health: "stopped", }); }, }, From 0b26bdd27fb38dbfebe37f48902d69352e84df47 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 29 Oct 2022 00:44:37 +0200 Subject: [PATCH 020/482] Always set up VSCode commands --- .../editors/code/src/commands.ts | 129 +++++++++--------- .../rust-analyzer/editors/code/src/ctx.ts | 102 ++++++++------ .../rust-analyzer/editors/code/src/main.ts | 30 ++-- .../rust-analyzer/editors/code/src/run.ts | 6 +- 4 files changed, 139 insertions(+), 128 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts index 12ceb4f2df8e1..312087e4cffef 100644 --- a/src/tools/rust-analyzer/editors/code/src/commands.ts +++ b/src/tools/rust-analyzer/editors/code/src/commands.ts @@ -3,7 +3,7 @@ import * as lc from "vscode-languageclient"; import * as ra from "./lsp_ext"; import * as path from "path"; -import { Ctx, Cmd } from "./ctx"; +import { Ctx, Cmd, CtxInit } from "./ctx"; import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets"; import { spawnSync } from "child_process"; import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run"; @@ -16,14 +16,14 @@ import { LINKED_COMMANDS } from "./client"; export * from "./ast_inspector"; export * from "./run"; -export function analyzerStatus(ctx: Ctx): Cmd { +export function analyzerStatus(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-status://status"); readonly eventEmitter = new vscode.EventEmitter(); async provideTextDocumentContent(_uri: vscode.Uri): Promise { if (!vscode.window.activeTextEditor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; const params: ra.AnalyzerStatusParams = {}; const doc = ctx.activeRustEditor?.document; @@ -52,7 +52,7 @@ export function analyzerStatus(ctx: Ctx): Cmd { }; } -export function memoryUsage(ctx: Ctx): Cmd { +export function memoryUsage(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-memory://memory"); readonly eventEmitter = new vscode.EventEmitter(); @@ -60,14 +60,9 @@ export function memoryUsage(ctx: Ctx): Cmd { provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult { if (!vscode.window.activeTextEditor) return ""; - return ctx - .getClient() - .then((it) => it.sendRequest(ra.memoryUsage)) - .then((mem: any) => { - return ( - "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)" - ); - }); + return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => { + return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)"; + }); } get onDidChange(): vscode.Event { @@ -86,18 +81,18 @@ export function memoryUsage(ctx: Ctx): Cmd { }; } -export function shuffleCrateGraph(ctx: Ctx): Cmd { +export function shuffleCrateGraph(ctx: CtxInit): Cmd { return async () => { - return ctx.getClient().then((it) => it.sendRequest(ra.shuffleCrateGraph)); + return ctx.client.sendRequest(ra.shuffleCrateGraph); }; } -export function matchingBrace(ctx: Ctx): Cmd { +export function matchingBrace(ctx: CtxInit): Cmd { return async () => { const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const response = await client.sendRequest(ra.matchingBrace, { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), @@ -114,12 +109,12 @@ export function matchingBrace(ctx: Ctx): Cmd { }; } -export function joinLines(ctx: Ctx): Cmd { +export function joinLines(ctx: CtxInit): Cmd { return async () => { const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, { ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)), @@ -134,19 +129,19 @@ export function joinLines(ctx: Ctx): Cmd { }; } -export function moveItemUp(ctx: Ctx): Cmd { +export function moveItemUp(ctx: CtxInit): Cmd { return moveItem(ctx, ra.Direction.Up); } -export function moveItemDown(ctx: Ctx): Cmd { +export function moveItemDown(ctx: CtxInit): Cmd { return moveItem(ctx, ra.Direction.Down); } -export function moveItem(ctx: Ctx, direction: ra.Direction): Cmd { +export function moveItem(ctx: CtxInit, direction: ra.Direction): Cmd { return async () => { const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const lcEdits = await client.sendRequest(ra.moveItem, { range: client.code2ProtocolConverter.asRange(editor.selection), @@ -161,13 +156,13 @@ export function moveItem(ctx: Ctx, direction: ra.Direction): Cmd { }; } -export function onEnter(ctx: Ctx): Cmd { +export function onEnter(ctx: CtxInit): Cmd { async function handleKeypress() { const editor = ctx.activeRustEditor; if (!editor) return false; - const client = await ctx.getClient(); + const client = ctx.client; const lcEdits = await client .sendRequest(ra.onEnter, { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier( @@ -193,13 +188,13 @@ export function onEnter(ctx: Ctx): Cmd { }; } -export function parentModule(ctx: Ctx): Cmd { +export function parentModule(ctx: CtxInit): Cmd { return async () => { const editor = vscode.window.activeTextEditor; if (!editor) return; if (!(isRustDocument(editor.document) || isCargoTomlDocument(editor.document))) return; - const client = await ctx.getClient(); + const client = ctx.client; const locations = await client.sendRequest(ra.parentModule, { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), @@ -230,12 +225,12 @@ export function parentModule(ctx: Ctx): Cmd { }; } -export function openCargoToml(ctx: Ctx): Cmd { +export function openCargoToml(ctx: CtxInit): Cmd { return async () => { const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const response = await client.sendRequest(ra.openCargoToml, { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), }); @@ -251,12 +246,12 @@ export function openCargoToml(ctx: Ctx): Cmd { }; } -export function ssr(ctx: Ctx): Cmd { +export function ssr(ctx: CtxInit): Cmd { return async () => { const editor = vscode.window.activeTextEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const position = editor.selection.active; const selections = editor.selections; @@ -308,7 +303,7 @@ export function ssr(ctx: Ctx): Cmd { }; } -export function serverVersion(ctx: Ctx): Cmd { +export function serverVersion(ctx: CtxInit): Cmd { return async () => { if (!ctx.serverPath) { void vscode.window.showWarningMessage(`rust-analyzer server is not running`); @@ -324,7 +319,7 @@ export function serverVersion(ctx: Ctx): Cmd { // Opens the virtual file that will show the syntax tree // // The contents of the file come from the `TextDocumentContentProvider` -export function syntaxTree(ctx: Ctx): Cmd { +export function syntaxTree(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-syntax-tree://syntaxtree/tree.rast"); readonly eventEmitter = new vscode.EventEmitter(); @@ -360,7 +355,7 @@ export function syntaxTree(ctx: Ctx): Cmd { ): Promise { const rustEditor = ctx.activeRustEditor; if (!rustEditor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; // When the range based query is enabled we take the range of the selection const range = @@ -407,7 +402,7 @@ export function syntaxTree(ctx: Ctx): Cmd { // Opens the virtual file that will show the HIR of the function containing the cursor position // // The contents of the file come from the `TextDocumentContentProvider` -export function viewHir(ctx: Ctx): Cmd { +export function viewHir(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-hir://viewHir/hir.rs"); readonly eventEmitter = new vscode.EventEmitter(); @@ -444,7 +439,7 @@ export function viewHir(ctx: Ctx): Cmd { const rustEditor = ctx.activeRustEditor; if (!rustEditor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; const params = { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier( rustEditor.document @@ -473,7 +468,7 @@ export function viewHir(ctx: Ctx): Cmd { }; } -export function viewFileText(ctx: Ctx): Cmd { +export function viewFileText(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-file-text://viewFileText/file.rs"); readonly eventEmitter = new vscode.EventEmitter(); @@ -509,7 +504,7 @@ export function viewFileText(ctx: Ctx): Cmd { ): Promise { const rustEditor = ctx.activeRustEditor; if (!rustEditor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; const params = client.code2ProtocolConverter.asTextDocumentIdentifier( rustEditor.document @@ -536,7 +531,7 @@ export function viewFileText(ctx: Ctx): Cmd { }; } -export function viewItemTree(ctx: Ctx): Cmd { +export function viewItemTree(ctx: CtxInit): Cmd { const tdcp = new (class implements vscode.TextDocumentContentProvider { readonly uri = vscode.Uri.parse("rust-analyzer-item-tree://viewItemTree/itemtree.rs"); readonly eventEmitter = new vscode.EventEmitter(); @@ -572,7 +567,7 @@ export function viewItemTree(ctx: Ctx): Cmd { ): Promise { const rustEditor = ctx.activeRustEditor; if (!rustEditor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; const params = { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier( @@ -601,7 +596,7 @@ export function viewItemTree(ctx: Ctx): Cmd { }; } -function crateGraph(ctx: Ctx, full: boolean): Cmd { +function crateGraph(ctx: CtxInit, full: boolean): Cmd { return async () => { const nodeModulesPath = vscode.Uri.file(path.join(ctx.extensionPath, "node_modules")); @@ -618,7 +613,7 @@ function crateGraph(ctx: Ctx, full: boolean): Cmd { const params = { full: full, }; - const client = await ctx.getClient(); + const client = ctx.client; const dot = await client.sendRequest(ra.viewCrateGraph, params); const uri = panel.webview.asWebviewUri(nodeModulesPath); @@ -664,18 +659,18 @@ function crateGraph(ctx: Ctx, full: boolean): Cmd { }; } -export function viewCrateGraph(ctx: Ctx): Cmd { +export function viewCrateGraph(ctx: CtxInit): Cmd { return crateGraph(ctx, false); } -export function viewFullCrateGraph(ctx: Ctx): Cmd { +export function viewFullCrateGraph(ctx: CtxInit): Cmd { return crateGraph(ctx, true); } // Opens the virtual file that will show the syntax tree // // The contents of the file come from the `TextDocumentContentProvider` -export function expandMacro(ctx: Ctx): Cmd { +export function expandMacro(ctx: CtxInit): Cmd { function codeFormat(expanded: ra.ExpandedMacro): string { let result = `// Recursive expansion of ${expanded.name}! macro\n`; result += "// " + "=".repeat(result.length - 3); @@ -691,7 +686,7 @@ export function expandMacro(ctx: Ctx): Cmd { async provideTextDocumentContent(_uri: vscode.Uri): Promise { const editor = vscode.window.activeTextEditor; if (!editor) return ""; - const client = await ctx.getClient(); + const client = ctx.client; const position = editor.selection.active; @@ -723,8 +718,8 @@ export function expandMacro(ctx: Ctx): Cmd { }; } -export function reloadWorkspace(ctx: Ctx): Cmd { - return async () => (await ctx.getClient()).sendRequest(ra.reloadWorkspace); +export function reloadWorkspace(ctx: CtxInit): Cmd { + return async () => ctx.client.sendRequest(ra.reloadWorkspace); } async function showReferencesImpl( @@ -743,13 +738,13 @@ async function showReferencesImpl( } } -export function showReferences(ctx: Ctx): Cmd { +export function showReferences(ctx: CtxInit): Cmd { return async (uri: string, position: lc.Position, locations: lc.Location[]) => { - await showReferencesImpl(await ctx.getClient(), uri, position, locations); + await showReferencesImpl(ctx.client, uri, position, locations); }; } -export function applyActionGroup(_ctx: Ctx): Cmd { +export function applyActionGroup(_ctx: CtxInit): Cmd { return async (actions: { label: string; arguments: lc.CodeAction }[]) => { const selectedAction = await vscode.window.showQuickPick(actions); if (!selectedAction) return; @@ -760,9 +755,9 @@ export function applyActionGroup(_ctx: Ctx): Cmd { }; } -export function gotoLocation(ctx: Ctx): Cmd { +export function gotoLocation(ctx: CtxInit): Cmd { return async (locationLink: lc.LocationLink) => { - const client = await ctx.getClient(); + const client = ctx.client; const uri = client.protocol2CodeConverter.asUri(locationLink.targetUri); let range = client.protocol2CodeConverter.asRange(locationLink.targetSelectionRange); // collapse the range to a cursor position @@ -772,13 +767,13 @@ export function gotoLocation(ctx: Ctx): Cmd { }; } -export function openDocs(ctx: Ctx): Cmd { +export function openDocs(ctx: CtxInit): Cmd { return async () => { const editor = vscode.window.activeTextEditor; if (!editor) { return; } - const client = await ctx.getClient(); + const client = ctx.client; const position = editor.selection.active; const textDocument = { uri: editor.document.uri.toString() }; @@ -791,16 +786,16 @@ export function openDocs(ctx: Ctx): Cmd { }; } -export function cancelFlycheck(ctx: Ctx): Cmd { +export function cancelFlycheck(ctx: CtxInit): Cmd { return async () => { - const client = await ctx.getClient(); + const client = ctx.client; await client.sendRequest(ra.cancelFlycheck); }; } -export function resolveCodeAction(ctx: Ctx): Cmd { +export function resolveCodeAction(ctx: CtxInit): Cmd { return async (params: lc.CodeAction) => { - const client = await ctx.getClient(); + const client = ctx.client; params.command = undefined; const item = await client?.sendRequest(lc.CodeActionResolveRequest.type, params); if (!item?.edit) { @@ -825,13 +820,13 @@ export function resolveCodeAction(ctx: Ctx): Cmd { }; } -export function applySnippetWorkspaceEditCommand(_ctx: Ctx): Cmd { +export function applySnippetWorkspaceEditCommand(_ctx: CtxInit): Cmd { return async (edit: vscode.WorkspaceEdit) => { await applySnippetWorkspaceEdit(edit); }; } -export function run(ctx: Ctx): Cmd { +export function run(ctx: CtxInit): Cmd { let prevRunnable: RunnableQuickPick | undefined; return async () => { @@ -845,11 +840,11 @@ export function run(ctx: Ctx): Cmd { }; } -export function peekTests(ctx: Ctx): Cmd { +export function peekTests(ctx: CtxInit): Cmd { return async () => { const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; await vscode.window.withProgress( { @@ -878,7 +873,7 @@ export function peekTests(ctx: Ctx): Cmd { }; } -export function runSingle(ctx: Ctx): Cmd { +export function runSingle(ctx: CtxInit): Cmd { return async (runnable: ra.Runnable) => { const editor = ctx.activeRustEditor; if (!editor) return; @@ -895,7 +890,7 @@ export function runSingle(ctx: Ctx): Cmd { }; } -export function copyRunCommandLine(ctx: Ctx) { +export function copyRunCommandLine(ctx: CtxInit) { let prevRunnable: RunnableQuickPick | undefined; return async () => { const item = await selectRunnable(ctx, prevRunnable); @@ -907,7 +902,7 @@ export function copyRunCommandLine(ctx: Ctx) { }; } -export function debug(ctx: Ctx): Cmd { +export function debug(ctx: CtxInit): Cmd { let prevDebuggee: RunnableQuickPick | undefined; return async () => { @@ -920,13 +915,13 @@ export function debug(ctx: Ctx): Cmd { }; } -export function debugSingle(ctx: Ctx): Cmd { +export function debugSingle(ctx: CtxInit): Cmd { return async (config: ra.Runnable) => { await startDebugSession(ctx, config); }; } -export function newDebugConfig(ctx: Ctx): Cmd { +export function newDebugConfig(ctx: CtxInit): Cmd { return async () => { const item = await selectRunnable(ctx, undefined, true, false); if (!item) return; diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts index 8592950e1023d..d198d4e938348 100644 --- a/src/tools/rust-analyzer/editors/code/src/ctx.ts +++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts @@ -10,6 +10,7 @@ import { PersistentState } from "./persistent_state"; import { bootstrap } from "./bootstrap"; export type Workspace = + | { kind: "Empty" } | { kind: "Workspace Folder"; } @@ -19,15 +20,20 @@ export type Workspace = }; export type CommandFactory = { - enabled: (ctx: Ctx) => Cmd; + enabled: (ctx: CtxInit) => Cmd; disabled?: (ctx: Ctx) => Cmd; }; +export type CtxInit = Ctx & { + readonly client: lc.LanguageClient; +}; + export class Ctx { readonly statusBar: vscode.StatusBarItem; readonly config: Config; + readonly workspace: Workspace; - private client: lc.LanguageClient | undefined; + private _client: lc.LanguageClient | undefined; private _serverPath: string | undefined; private traceOutputChannel: vscode.OutputChannel | undefined; private outputChannel: vscode.OutputChannel | undefined; @@ -36,18 +42,17 @@ export class Ctx { private commandFactories: Record; private commandDisposables: Disposable[]; - workspace: Workspace; + get client() { + return this._client; + } constructor( readonly extCtx: vscode.ExtensionContext, - workspace: Workspace, - commandFactories: Record + commandFactories: Record, + workspace: Workspace ) { extCtx.subscriptions.push(this); this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); - this.statusBar.text = "rust-analyzer"; - this.statusBar.tooltip = "ready"; - this.statusBar.command = "rust-analyzer.analyzerStatus"; this.statusBar.show(); this.workspace = workspace; this.clientSubscriptions = []; @@ -57,7 +62,10 @@ export class Ctx { this.state = new PersistentState(extCtx.globalState); this.config = new Config(extCtx); - this.updateCommands(); + this.updateCommands("disable"); + this.setServerStatus({ + health: "stopped", + }); } dispose() { @@ -67,16 +75,11 @@ export class Ctx { this.commandDisposables.forEach((disposable) => disposable.dispose()); } - clientFetcher() { - const self = this; - return { - get client(): lc.LanguageClient | undefined { - return self.client; - }, - }; - } + private async getOrCreateClient() { + if (this.workspace.kind === "Empty") { + return; + } - async getClient() { if (!this.traceOutputChannel) { this.traceOutputChannel = vscode.window.createOutputChannel( "Rust Analyzer Language Server Trace" @@ -88,7 +91,7 @@ export class Ctx { this.pushExtCleanup(this.outputChannel); } - if (!this.client) { + if (!this._client) { this._serverPath = await bootstrap(this.extCtx, this.config, this.state).catch( (err) => { let message = "bootstrap error. "; @@ -125,47 +128,55 @@ export class Ctx { const initializationOptions = substituteVSCodeVariables(rawInitializationOptions); - this.client = await createClient( + this._client = await createClient( this.traceOutputChannel, this.outputChannel, initializationOptions, serverOptions ); this.pushClientCleanup( - this.client.onNotification(ra.serverStatus, (params) => + this._client.onNotification(ra.serverStatus, (params) => this.setServerStatus(params) ) ); } - return this.client; + return this._client; } async activate() { log.info("Activating language client"); - const client = await this.getClient(); + const client = await this.getOrCreateClient(); + if (!client) { + return; + } await client.start(); this.updateCommands(); - return client; } async deactivate() { + if (!this._client) { + return; + } log.info("Deactivating language client"); - await this.client?.stop(); - this.updateCommands(); + this.updateCommands("disable"); + await this._client.stop(); } async stop() { + if (!this._client) { + return; + } log.info("Stopping language client"); + this.updateCommands("disable"); await this.disposeClient(); - this.updateCommands(); } private async disposeClient() { this.clientSubscriptions?.forEach((disposable) => disposable.dispose()); this.clientSubscriptions = []; - await this.client?.dispose(); + await this._client?.dispose(); this._serverPath = undefined; - this.client = undefined; + this._client = undefined; } get activeRustEditor(): RustEditor | undefined { @@ -185,21 +196,30 @@ export class Ctx { return this._serverPath; } - private updateCommands() { + private updateCommands(forceDisable?: "disable") { this.commandDisposables.forEach((disposable) => disposable.dispose()); this.commandDisposables = []; - const fetchFactory = (factory: CommandFactory, fullName: string) => { - return this.client && this.client.isRunning() - ? factory.enabled - : factory.disabled || - ((_) => () => - vscode.window.showErrorMessage( - `command ${fullName} failed: rust-analyzer server is not running` - )); + + const clientRunning = (!forceDisable && this._client?.isRunning()) ?? false; + const isClientRunning = function (_ctx: Ctx): _ctx is CtxInit { + return clientRunning; }; + for (const [name, factory] of Object.entries(this.commandFactories)) { const fullName = `rust-analyzer.${name}`; - const callback = fetchFactory(factory, fullName)(this); + let callback; + if (isClientRunning(this)) { + // we asserted that `client` is defined + callback = factory.enabled(this); + } else if (factory.disabled) { + callback = factory.disabled(this); + } else { + callback = () => + vscode.window.showErrorMessage( + `command ${fullName} failed: rust-analyzer server is not running` + ); + } + this.commandDisposables.push(vscode.commands.registerCommand(fullName, callback)); } } @@ -209,7 +229,7 @@ export class Ctx { const statusBar = this.statusBar; switch (status.health) { case "ok": - statusBar.tooltip = (status.message ?? "Ready") + "Click to stop."; + statusBar.tooltip = (status.message ?? "Ready") + "\nClick to stop server."; statusBar.command = "rust-analyzer.stopServer"; statusBar.color = undefined; statusBar.backgroundColor = undefined; @@ -235,7 +255,7 @@ export class Ctx { icon = "$(error) "; break; case "stopped": - statusBar.tooltip = "Server is stopped. Click to start."; + statusBar.tooltip = "Server is stopped.\nClick to start."; statusBar.command = "rust-analyzer.startServer"; statusBar.color = undefined; statusBar.backgroundColor = undefined; diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts index 5970533472667..54e0c16e5e08b 100644 --- a/src/tools/rust-analyzer/editors/code/src/main.ts +++ b/src/tools/rust-analyzer/editors/code/src/main.ts @@ -10,7 +10,6 @@ import { setContextValue } from "./util"; const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; export interface RustAnalyzerExtensionApi { - // FIXME: this should be non-optional readonly client?: lc.LanguageClient; } @@ -42,22 +41,18 @@ export async function activate( isRustDocument(document) ); - if (folders.length === 0 && rustDocuments.length === 0) { - // FIXME: Ideally we would choose not to activate at all (and avoid registering - // non-functional editor commands), but VS Code doesn't seem to have a good way of doing - // that - return {}; - } - + // FIXME: This can change over time const workspace: Workspace = folders.length === 0 - ? { - kind: "Detached Files", - files: rustDocuments, - } + ? rustDocuments.length === 0 + ? { kind: "Empty" } + : { + kind: "Detached Files", + files: rustDocuments, + } : { kind: "Workspace Folder" }; - const ctx = new Ctx(context, workspace, createCommands()); + const ctx = new Ctx(context, createCommands(), workspace); // VS Code doesn't show a notification when an extension fails to activate // so we do it ourselves. const api = await activateServer(ctx).catch((err) => { @@ -77,16 +72,16 @@ async function activateServer(ctx: Ctx): Promise { vscode.workspace.onDidChangeConfiguration( async (_) => { - await ctx - .clientFetcher() - .client?.sendNotification("workspace/didChangeConfiguration", { settings: "" }); + await ctx.client?.sendNotification("workspace/didChangeConfiguration", { + settings: "", + }); }, null, ctx.subscriptions ); await ctx.activate(); - return ctx.clientFetcher(); + return ctx; } function createCommands(): Record { @@ -123,6 +118,7 @@ function createCommands(): Record { health: "stopped", }); }, + disabled: (_) => async () => {}, }, analyzerStatus: { enabled: commands.analyzerStatus }, diff --git a/src/tools/rust-analyzer/editors/code/src/run.ts b/src/tools/rust-analyzer/editors/code/src/run.ts index dadaa41b1d162..35627e2fc6beb 100644 --- a/src/tools/rust-analyzer/editors/code/src/run.ts +++ b/src/tools/rust-analyzer/editors/code/src/run.ts @@ -3,7 +3,7 @@ import * as lc from "vscode-languageclient"; import * as ra from "./lsp_ext"; import * as tasks from "./tasks"; -import { Ctx } from "./ctx"; +import { CtxInit } from "./ctx"; import { makeDebugConfig } from "./debug"; import { Config, RunnableEnvCfg } from "./config"; @@ -12,7 +12,7 @@ const quickPickButtons = [ ]; export async function selectRunnable( - ctx: Ctx, + ctx: CtxInit, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true @@ -20,7 +20,7 @@ export async function selectRunnable( const editor = ctx.activeRustEditor; if (!editor) return; - const client = await ctx.getClient(); + const client = ctx.client; const textDocument: lc.TextDocumentIdentifier = { uri: editor.document.uri.toString(), }; From a20c9b3d00733cca41bbee81cc50193860105d89 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 29 Oct 2022 01:28:32 +0200 Subject: [PATCH 021/482] Properly handle vscode workspace changes --- .../rust-analyzer/editors/code/src/ctx.ts | 67 +++++++++++++++++-- .../rust-analyzer/editors/code/src/main.ts | 45 ++++--------- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts index d198d4e938348..3e366525ee295 100644 --- a/src/tools/rust-analyzer/editors/code/src/ctx.ts +++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts @@ -4,11 +4,15 @@ import * as ra from "./lsp_ext"; import { Config, substituteVariablesInEnv, substituteVSCodeVariables } from "./config"; import { createClient } from "./client"; -import { isRustEditor, log, RustEditor } from "./util"; +import { isRustDocument, isRustEditor, log, RustEditor } from "./util"; import { ServerStatusParams } from "./lsp_ext"; import { PersistentState } from "./persistent_state"; import { bootstrap } from "./bootstrap"; +// We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if +// only those are in use. We use "Empty" to represent these scenarios +// (r-a still somewhat works with Live Share, because commands are tunneled to the host) + export type Workspace = | { kind: "Empty" } | { @@ -19,6 +23,24 @@ export type Workspace = files: vscode.TextDocument[]; }; +export function fetchWorkspace(): Workspace { + const folders = (vscode.workspace.workspaceFolders || []).filter( + (folder) => folder.uri.scheme === "file" + ); + const rustDocuments = vscode.workspace.textDocuments.filter((document) => + isRustDocument(document) + ); + + return folders.length === 0 + ? rustDocuments.length === 0 + ? { kind: "Empty" } + : { + kind: "Detached Files", + files: rustDocuments, + } + : { kind: "Workspace Folder" }; +} + export type CommandFactory = { enabled: (ctx: CtxInit) => Cmd; disabled?: (ctx: Ctx) => Cmd; @@ -75,6 +97,31 @@ export class Ctx { this.commandDisposables.forEach((disposable) => disposable.dispose()); } + async onWorkspaceFolderChanges() { + const workspace = fetchWorkspace(); + if (workspace.kind === "Detached Files" && this.workspace.kind === "Detached Files") { + if (workspace.files !== this.workspace.files) { + if (this.client?.isRunning()) { + // Ideally we wouldn't need to tear down the server here, but currently detached files + // are only specified at server start + await this.stopAndDispose(); + await this.start(); + } + return; + } + } + if (workspace.kind === "Workspace Folder" && this.workspace.kind === "Workspace Folder") { + return; + } + if (workspace.kind === "Empty") { + await this.stopAndDispose(); + return; + } + if (this.client?.isRunning()) { + await this.restart(); + } + } + private async getOrCreateClient() { if (this.workspace.kind === "Empty") { return; @@ -143,8 +190,8 @@ export class Ctx { return this._client; } - async activate() { - log.info("Activating language client"); + async start() { + log.info("Starting language client"); const client = await this.getOrCreateClient(); if (!client) { return; @@ -153,20 +200,26 @@ export class Ctx { this.updateCommands(); } - async deactivate() { + async restart() { + // FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed + await this.stopAndDispose(); + await this.start(); + } + + async stop() { if (!this._client) { return; } - log.info("Deactivating language client"); + log.info("Stopping language client"); this.updateCommands("disable"); await this._client.stop(); } - async stop() { + async stopAndDispose() { if (!this._client) { return; } - log.info("Stopping language client"); + log.info("Disposing language client"); this.updateCommands("disable"); await this.disposeClient(); } diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts index 54e0c16e5e08b..e76b657c1bfb5 100644 --- a/src/tools/rust-analyzer/editors/code/src/main.ts +++ b/src/tools/rust-analyzer/editors/code/src/main.ts @@ -2,8 +2,7 @@ import * as vscode from "vscode"; import * as lc from "vscode-languageclient/node"; import * as commands from "./commands"; -import { CommandFactory, Ctx, Workspace } from "./ctx"; -import { isRustDocument } from "./util"; +import { CommandFactory, Ctx, fetchWorkspace } from "./ctx"; import { activateTaskProvider } from "./tasks"; import { setContextValue } from "./util"; @@ -31,28 +30,7 @@ export async function activate( .then(() => {}, console.error); } - // We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if - // only those are in use. - // (r-a still somewhat works with Live Share, because commands are tunneled to the host) - const folders = (vscode.workspace.workspaceFolders || []).filter( - (folder) => folder.uri.scheme === "file" - ); - const rustDocuments = vscode.workspace.textDocuments.filter((document) => - isRustDocument(document) - ); - - // FIXME: This can change over time - const workspace: Workspace = - folders.length === 0 - ? rustDocuments.length === 0 - ? { kind: "Empty" } - : { - kind: "Detached Files", - files: rustDocuments, - } - : { kind: "Workspace Folder" }; - - const ctx = new Ctx(context, createCommands(), workspace); + const ctx = new Ctx(context, createCommands(), fetchWorkspace()); // VS Code doesn't show a notification when an extension fails to activate // so we do it ourselves. const api = await activateServer(ctx).catch((err) => { @@ -70,6 +48,11 @@ async function activateServer(ctx: Ctx): Promise { ctx.pushExtCleanup(activateTaskProvider(ctx.config)); } + vscode.workspace.onDidChangeWorkspaceFolders( + async (_) => ctx.onWorkspaceFolderChanges(), + null, + ctx.subscriptions + ); vscode.workspace.onDidChangeConfiguration( async (_) => { await ctx.client?.sendNotification("workspace/didChangeConfiguration", { @@ -80,7 +63,7 @@ async function activateServer(ctx: Ctx): Promise { ctx.subscriptions ); - await ctx.activate(); + await ctx.start(); return ctx; } @@ -93,27 +76,25 @@ function createCommands(): Record { reload: { enabled: (ctx) => async () => { void vscode.window.showInformationMessage("Reloading rust-analyzer..."); - // FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed - await ctx.stop(); - await ctx.activate(); + await ctx.restart(); }, disabled: (ctx) => async () => { void vscode.window.showInformationMessage("Reloading rust-analyzer..."); - await ctx.activate(); + await ctx.start(); }, }, startServer: { enabled: (ctx) => async () => { - await ctx.activate(); + await ctx.start(); }, disabled: (ctx) => async () => { - await ctx.activate(); + await ctx.start(); }, }, stopServer: { enabled: (ctx) => async () => { // FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed - await ctx.stop(); + await ctx.stopAndDispose(); ctx.setServerStatus({ health: "stopped", }); From 0581c23be1f3a16f8b4b8411f18fcc26972fd332 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 28 Oct 2022 20:33:19 +0900 Subject: [PATCH 022/482] Replace expect test for GATs with `check_types` --- .../crates/hir-ty/src/tests/traits.rs | 92 ++++++------------- 1 file changed, 28 insertions(+), 64 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 7995f6446d07b..7d42b8b9bc8d8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -3966,7 +3966,7 @@ fn g(t: &(dyn T + Send)) { #[test] fn gats_in_path() { - check_infer_with_mismatches( + check_types( r#" //- minicore: deref use core::ops::Deref; @@ -3976,32 +3976,22 @@ trait PointerFamily { fn f(p: P::Pointer) { let a = *p; + //^ i32 } fn g(p:

::Pointer) { let a = *p; + //^ i32 } "#, - expect![[r#" - 110..111 'p': PointerFamily::Pointer - 130..149 '{ ... *p; }': () - 140..141 'a': i32 - 144..146 '*p': i32 - 145..146 'p': PointerFamily::Pointer - 173..174 'p': PointerFamily::Pointer - 212..231 '{ ... *p; }': () - 222..223 'a': i32 - 226..228 '*p': i32 - 227..228 'p': PointerFamily::Pointer - "#]], ); } #[test] fn gats_with_impl_trait() { - // FIXME: the last function (`fn h()`) is not valid Rust as of this writing because you cannot - // specify the same associated type multiple times even if their arguments are different. - // Reconsider how to treat these invalid types. - check_infer_with_mismatches( + // FIXME: the last function (`fn i()`) is not valid Rust as of this writing because you cannot + // specify the same associated type multiple times even if their arguments are different (c.f. + // `fn h()`, which is valid). Reconsider how to treat these invalid types. + check_types( r#" //- minicore: deref use core::ops::Deref; @@ -4012,45 +4002,30 @@ trait Trait { } fn f(v: impl Trait) { - v.get::().deref(); - v.get::().deref(); + let a = v.get::().deref(); + //^ &i32 + let a = v.get::().deref(); + //^ &T } -fn g(v: impl Trait = &'a T>) { +fn g<'a, T: 'a>(v: impl Trait = &'a T>) { let a = v.get::(); + //^ &T let a = v.get::<()>(); + //^ Trait::Assoc<(), impl Trait = &T>> +} +fn h<'a>(v: impl Trait = &'a i32> + Trait = &'a i64>) { + let a = v.get::(); + //^ &i32 + let a = v.get::(); + //^ &i64 } -fn h(v: impl Trait = &'a i32, Assoc = &'a i64> { +fn i<'a>(v: impl Trait = &'a i32, Assoc = &'a i64>) { let a = v.get::(); + //^ &i32 let a = v.get::(); + //^ &i64 } "#, - expect![[r#" - 90..94 'self': &Self - 126..127 'v': impl Trait - 141..198 '{ ...f(); }': () - 147..148 'v': impl Trait - 147..161 'v.get::()': Trait::Assoc - 147..169 'v.get:...eref()': &i32 - 175..176 'v': impl Trait - 175..187 'v.get::()': Trait::Assoc - 175..195 'v.get:...eref()': &T - 207..208 'v': impl Trait = &T> - 240..296 '{ ...>(); }': () - 250..251 'a': &T - 254..255 'v': impl Trait = &T> - 254..266 'v.get::()': &T - 276..277 'a': Trait::Assoc<(), impl Trait = &T>> - 280..281 'v': impl Trait = &T> - 280..293 'v.get::<()>()': Trait::Assoc<(), impl Trait = &T>> - 302..303 'v': impl Trait = &i32, Assoc = &i64> - 360..419 '{ ...>(); }': () - 370..371 'a': &i32 - 374..375 'v': impl Trait = &i32, Assoc = &i64> - 374..388 'v.get::()': &i32 - 398..399 'a': &i64 - 402..403 'v': impl Trait = &i32, Assoc = &i64> - 402..416 'v.get::()': &i64 - "#]], ); } @@ -4086,7 +4061,7 @@ fn f<'a>(v: &dyn Trait = &'a i32>) { #[test] fn gats_in_associated_type_binding() { - check_infer_with_mismatches( + check_types( r#" trait Trait { type Assoc; @@ -4099,24 +4074,13 @@ where T: Trait = usize>, { let a = t.get::(); + //^ u32 let a = t.get::(); + //^ usize let a = t.get::<()>(); + //^ Trait::Assoc<(), T> } "#, - expect![[r#" - 48..52 'self': &Self - 84..85 't': T - 164..252 '{ ...>(); }': () - 174..175 'a': u32 - 178..179 't': T - 178..192 't.get::()': u32 - 202..203 'a': usize - 206..207 't': T - 206..222 't.get:...ize>()': usize - 232..233 'a': Trait::Assoc<(), T> - 236..237 't': T - 236..249 't.get::<()>()': Trait::Assoc<(), T> - "#]], - ) + ); } From 6d1681f480d365acf76c9376114f412f732d865b Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 28 Oct 2022 21:17:16 +0900 Subject: [PATCH 023/482] Document the ordering constraint on `Binders` and `Substitution` --- src/tools/rust-analyzer/crates/hir-ty/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 8458a4fe1cd15..42c3b58d5ada5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -81,7 +81,20 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; pub type VariableKind = chalk_ir::VariableKind; pub type VariableKinds = chalk_ir::VariableKinds; pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds; +/// Represents generic parameters and an item bound by them. When the item has parent, the binders +/// also contain the generic parameters for its parent. See chalk's documentation for details. +/// +/// One thing to keep in mind when working with `Binders` (and `Substitution`s, which represent +/// generic arguments) in rust-analyzer is that the ordering within *is* significant - the generic +/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate +/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its +/// motivation in detail. pub type Binders = chalk_ir::Binders; +/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for +/// it contains generic arguments for both its parent and itself. See chalk's documentation for +/// details. +/// +/// See `Binders` for the constraint on the ordering. pub type Substitution = chalk_ir::Substitution; pub type GenericArg = chalk_ir::GenericArg; pub type GenericArgData = chalk_ir::GenericArgData; From bf2c4e42a6ae3b681e6ad45f2f7712e6158ad206 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 19 Oct 2022 00:08:20 +0200 Subject: [PATCH 024/482] Implement -Ztrack-diagnostics --- compiler/rustc_driver/src/lib.rs | 1 + compiler/rustc_errors/src/diagnostic.rs | 29 +++++++++++++++ .../rustc_errors/src/diagnostic_builder.rs | 5 +++ compiler/rustc_errors/src/emitter.rs | 36 ++++++++++++++++--- compiler/rustc_errors/src/json.rs | 8 +++++ compiler/rustc_errors/src/json/tests.rs | 1 + compiler/rustc_errors/src/lib.rs | 30 ++++++++++++++++ compiler/rustc_expand/src/tests.rs | 1 + compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 30 ++++++++++++++-- src/librustdoc/core.rs | 2 ++ src/librustdoc/doctest.rs | 3 ++ src/test/ui/track-diagnostics/track.rs | 6 ++++ src/test/ui/track-diagnostics/track.stderr | 26 ++++++++++++++ src/tools/clippy/clippy_lints/src/doc.rs | 1 + src/tools/clippy/src/driver.rs | 1 + src/tools/rustfmt/src/parse/session.rs | 1 + 18 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/track-diagnostics/track.rs create mode 100644 src/test/ui/track-diagnostics/track.stderr diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index cfa734c7df39c..cf4bcc7c158fc 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1200,6 +1200,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { false, None, false, + false, )); let handler = rustc_errors::Handler::with_emitter(true, None, emitter); diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 23f29a24fe79f..45c017df918e8 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP}; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; +use std::panic::Location; /// Error type for `Diagnostic`'s `suggestions` field, indicating that /// `.disable_suggestions()` was called on the `Diagnostic`. @@ -107,6 +108,31 @@ pub struct Diagnostic { /// If diagnostic is from Lint, custom hash function ignores notes /// otherwise hash is based on the all the fields pub is_lint: bool, + + /// With `-Ztrack_diagnostics` enabled, + /// we print where in rustc this error was emitted. + pub emitted_at: DiagnosticLocation, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub struct DiagnosticLocation { + file: Cow<'static, str>, + line: u32, + col: u32, +} + +impl DiagnosticLocation { + #[track_caller] + fn caller() -> Self { + let loc = Location::caller(); + DiagnosticLocation { file: loc.file().into(), line: loc.line(), col: loc.column() } + } +} + +impl fmt::Display for DiagnosticLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}:{}:{}", self.file, self.line, self.col) + } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] @@ -173,10 +199,12 @@ impl StringPart { } impl Diagnostic { + #[track_caller] pub fn new>(level: Level, message: M) -> Self { Diagnostic::new_with_code(level, None, message) } + #[track_caller] pub fn new_with_code>( level: Level, code: Option, @@ -192,6 +220,7 @@ impl Diagnostic { args: Default::default(), sort_span: DUMMY_SP, is_lint: false, + emitted_at: DiagnosticLocation::caller(), } } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9b41234dcfb66..ecf8570e81f71 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -133,6 +133,7 @@ mod sealed_level_is_error { impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new_guaranteeing_error, const L: Level>( handler: &'a Handler, message: M, @@ -196,6 +197,7 @@ impl EmissionGuarantee for ErrorGuaranteed { } } + #[track_caller] fn make_diagnostic_builder( handler: &Handler, msg: impl Into, @@ -209,6 +211,7 @@ impl EmissionGuarantee for ErrorGuaranteed { impl<'a> DiagnosticBuilder<'a, ()> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new>( handler: &'a Handler, level: Level, @@ -220,6 +223,7 @@ impl<'a> DiagnosticBuilder<'a, ()> { /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. + #[track_caller] pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { debug!("Created new diagnostic"); Self { @@ -308,6 +312,7 @@ impl EmissionGuarantee for Noted { impl<'a> DiagnosticBuilder<'a, !> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); Self::new_diagnostic_fatal(handler, diagnostic) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index cd6413bc3ec62..b9b9a59e354b2 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -16,10 +16,10 @@ use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Styl use crate::styled_buffer::StyledBuffer; use crate::translation::{to_fluent_args, Translate}; use crate::{ - CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler, - LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle, + diagnostic::DiagnosticLocation, CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, + FluentBundle, Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, + SubstitutionHighlight, SuggestionStyle, }; - use rustc_lint_defs::pluralize; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; @@ -64,6 +64,7 @@ impl HumanReadableErrorType { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); @@ -77,6 +78,7 @@ impl HumanReadableErrorType { color, diagnostic_width, macro_backtrace, + track_diagnostics, ) } } @@ -557,6 +559,7 @@ impl Emitter for EmitterWriter { &primary_span, &children, &suggestions, + Some(&diag.emitted_at), ); } @@ -650,6 +653,7 @@ pub struct EmitterWriter { diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } #[derive(Debug)] @@ -669,6 +673,7 @@ impl EmitterWriter { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let dst = Destination::from_stderr(color_config); EmitterWriter { @@ -681,6 +686,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -694,6 +700,7 @@ impl EmitterWriter { colored: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { EmitterWriter { dst: Raw(dst, colored), @@ -705,6 +712,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -1327,6 +1335,7 @@ impl EmitterWriter { level: &Level, max_line_num_len: usize, is_secondary: bool, + emitted_at: Option<&DiagnosticLocation>, ) -> io::Result<()> { let mut buffer = StyledBuffer::new(); @@ -1377,7 +1386,6 @@ impl EmitterWriter { } } } - let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp); // Make sure our primary file comes first @@ -1653,6 +1661,12 @@ impl EmitterWriter { } } + if self.track_diagnostics && let Some(tracked) = emitted_at { + let track = format!("-Ztrack-diagnostics: created at {tracked}"); + let len = buffer.num_lines(); + buffer.append(len, &track, Style::NoStyle); + } + // final step: take our styled buffer, render it, then output it emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; @@ -1977,6 +1991,7 @@ impl EmitterWriter { span: &MultiSpan, children: &[SubDiagnostic], suggestions: &[CodeSuggestion], + emitted_at: Option<&DiagnosticLocation>, ) { let max_line_num_len = if self.ui_testing { ANONYMIZED_LINE_NUM.len() @@ -1985,7 +2000,16 @@ impl EmitterWriter { num_decimal_digits(n) }; - match self.emit_message_default(span, message, args, code, level, max_line_num_len, false) { + match self.emit_message_default( + span, + message, + args, + code, + level, + max_line_num_len, + false, + emitted_at, + ) { Ok(()) => { if !children.is_empty() || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden) @@ -2014,6 +2038,7 @@ impl EmitterWriter { &child.level, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", err); } @@ -2030,6 +2055,7 @@ impl EmitterWriter { &Level::Help, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", e); } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 4cc7be47fc2c6..c4498eafa4eab 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -45,6 +45,7 @@ pub struct JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } impl JsonEmitter { @@ -57,6 +58,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst: Box::new(io::BufWriter::new(io::stderr())), @@ -69,6 +71,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -79,6 +82,7 @@ impl JsonEmitter { fallback_bundle: LazyFallbackBundle, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); JsonEmitter::stderr( @@ -90,6 +94,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, ) } @@ -103,6 +108,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst, @@ -115,6 +121,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -350,6 +357,7 @@ impl Diagnostic { false, je.diagnostic_width, je.macro_backtrace, + je.track_diagnostics, ) .ui_testing(je.ui_testing) .emit_diagnostic(diag); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index d940d14e1db91..f131468971b5a 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -59,6 +59,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { HumanReadableErrorType::Short(ColorConfig::Never), None, false, + false, ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0963ea71f8023..7b33262c23937 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -492,6 +492,8 @@ pub struct HandlerFlags { pub macro_backtrace: bool, /// If true, identical diagnostics are reported only once. pub deduplicate_diagnostics: bool, + /// Track where errors are created. Enabled with `-Ztrack-diagnostics`. + pub track_diagnostics: bool, } impl Drop for HandlerInner { @@ -559,6 +561,7 @@ impl Handler { false, None, flags.macro_backtrace, + flags.track_diagnostics, )); Self::with_emitter_and_flags(emitter, flags) } @@ -664,6 +667,7 @@ impl Handler { /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_diagnostic( &self, msg: impl Into, @@ -677,6 +681,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn( &self, span: impl Into, @@ -693,6 +698,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_span_warn_with_expectation( &self, span: impl Into, @@ -706,6 +712,7 @@ impl Handler { /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_allow( &self, span: impl Into, @@ -719,6 +726,7 @@ impl Handler { /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Also include a code. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_code( &self, span: impl Into, @@ -736,6 +744,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Warning(None), msg) } @@ -746,6 +755,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -762,6 +772,7 @@ impl Handler { /// Construct a builder at the `Expect` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_expect( &self, msg: impl Into, @@ -772,6 +783,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err( &self, span: impl Into, @@ -784,6 +796,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err_with_code( &self, span: impl Into, @@ -798,6 +811,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, @@ -807,12 +821,14 @@ impl Handler { /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. #[doc(hidden)] + #[track_caller] pub fn struct_err_lint(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Error { lint: true }, msg) } /// Construct a builder at the `Error` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err_with_code( &self, msg: impl Into, @@ -825,6 +841,7 @@ impl Handler { /// Construct a builder at the `Warn` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -837,6 +854,7 @@ impl Handler { /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal( &self, span: impl Into, @@ -874,6 +892,7 @@ impl Handler { /// Construct a builder at the `Note` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_note_without_error( &self, msg: impl Into, @@ -888,6 +907,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal_with_code( &self, span: impl Into, @@ -899,6 +919,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err( &self, span: impl Into, @@ -908,6 +929,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err_with_code( &self, span: impl Into, @@ -921,11 +943,13 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn_with_code( &self, span: impl Into, @@ -935,6 +959,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } + #[track_caller] pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -950,14 +975,17 @@ impl Handler { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). + #[track_caller] pub fn delay_good_path_bug(&self, msg: impl Into) { self.inner.borrow_mut().delay_good_path_bug(msg) } + #[track_caller] pub fn span_bug_no_panic(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Bug, msg), span); } + #[track_caller] pub fn span_note_without_error( &self, span: impl Into, @@ -966,6 +994,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Note, msg), span); } + #[track_caller] pub fn span_note_diag( &self, span: Span, @@ -1452,6 +1481,7 @@ impl HandlerInner { } } + #[track_caller] fn span_bug(&mut self, sp: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); panic::panic_any(ExplicitBug); diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index e44f060819633..d82a7a54030c6 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -151,6 +151,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & false, None, false, + false, ); let handler = Handler::with_emitter(true, None, Box::new(emitter)); handler.span_err(msp, "foo"); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f2ee52262adee..856ff3d415081 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -794,6 +794,7 @@ impl UnstableOptions { report_delayed_bugs: self.report_delayed_bugs, macro_backtrace: self.macro_backtrace, deduplicate_diagnostics: self.deduplicate_diagnostics, + track_diagnostics: self.track_diagnostics, } } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 3f234a47a3d86..425b03d5b1c6e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1587,6 +1587,8 @@ options! { "choose the TLS model to use (`rustc --print tls-models` for details)"), trace_macros: bool = (false, parse_bool, [UNTRACKED], "for every macro invocation, print its name and arguments (default: no)"), + track_diagnostics: bool = (false, parse_bool, [TRACKED], + "Tracks where in rustc a diagnostic was emitted"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 100c66f63641c..c94d7c637531d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -286,6 +286,7 @@ impl Session { } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn>( &self, sp: S, @@ -294,6 +295,7 @@ impl Session { self.diagnostic().struct_span_warn(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_expectation>( &self, sp: S, @@ -303,6 +305,7 @@ impl Session { self.diagnostic().struct_span_warn_with_expectation(sp, msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_code>( &self, sp: S, @@ -312,10 +315,12 @@ impl Session { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_warn(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -344,6 +349,7 @@ impl Session { self.diagnostic().struct_expect(msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err>( &self, sp: S, @@ -352,6 +358,7 @@ impl Session { self.diagnostic().struct_span_err(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err_with_code>( &self, sp: S, @@ -362,12 +369,14 @@ impl Session { } // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { self.parse_sess.struct_err(msg) } + #[track_caller] #[rustc_lint_diagnostics] pub fn struct_err_with_code( &self, @@ -377,6 +386,7 @@ impl Session { self.diagnostic().struct_err_with_code(msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -424,6 +434,7 @@ impl Session { self.diagnostic().fatal(msg).raise() } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err_or_warn>( &self, is_warning: bool, @@ -437,6 +448,7 @@ impl Session { } } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err>( &self, sp: S, @@ -457,12 +469,14 @@ impl Session { pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { self.diagnostic().err(msg) } + #[track_caller] pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { self.parse_sess.create_err(err) } + #[track_caller] pub fn create_feature_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, @@ -1213,6 +1227,7 @@ fn default_emitter( fallback_bundle: LazyFallbackBundle, ) -> Box { let macro_backtrace = sopts.unstable_opts.macro_backtrace; + let track_diagnostics = sopts.unstable_opts.track_diagnostics; match sopts.error_format { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -1236,6 +1251,7 @@ fn default_emitter( sopts.unstable_opts.teach, sopts.diagnostic_width, macro_backtrace, + track_diagnostics, ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } @@ -1250,6 +1266,7 @@ fn default_emitter( json_rendered, sopts.diagnostic_width, macro_backtrace, + track_diagnostics, ) .ui_testing(sopts.unstable_opts.ui_testing), ), @@ -1552,11 +1569,18 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler false, None, false, + false, )) } - config::ErrorOutputType::Json { pretty, json_rendered } => { - Box::new(JsonEmitter::basic(pretty, json_rendered, None, fallback_bundle, None, false)) - } + config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic( + pretty, + json_rendered, + None, + fallback_bundle, + None, + false, + false, + )), }; rustc_errors::Handler::with_emitter(true, None, emitter) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 3961802529b29..404e0a59d865b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -166,6 +166,7 @@ pub(crate) fn new_handler( unstable_opts.teach, diagnostic_width, false, + false, ) .ui_testing(unstable_opts.ui_testing), ) @@ -184,6 +185,7 @@ pub(crate) fn new_handler( json_rendered, diagnostic_width, false, + false, ) .ui_testing(unstable_opts.ui_testing), ) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index db70029f6ec59..7cbe2f1e22738 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -551,6 +551,7 @@ pub(crate) fn make_test( false, Some(80), false, + false, ) .supports_color(); @@ -564,6 +565,7 @@ pub(crate) fn make_test( false, None, false, + false, ); // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser @@ -748,6 +750,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { false, None, false, + false, ); let handler = Handler::with_emitter(false, None, Box::new(emitter)); diff --git a/src/test/ui/track-diagnostics/track.rs b/src/test/ui/track-diagnostics/track.rs new file mode 100644 index 0000000000000..3427c593e856e --- /dev/null +++ b/src/test/ui/track-diagnostics/track.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +fn main() { + break rust +} diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr new file mode 100644 index 0000000000000..83ff935dbabd6 --- /dev/null +++ b/src/test/ui/track-diagnostics/track.stderr @@ -0,0 +1,26 @@ +error[E0425]: cannot find value `rust` in this scope + --> $DIR/track.rs:5:11 + | +LL | break rust + | ^^^^ not found in this scope +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:289:28 + +error[E0268]: `break` outside of a loop + --> $DIR/track.rs:5:5 + | +LL | break rust + | ^^^^^^^^^^ cannot `break` outside of a loop +-Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:957:10 + +error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? + +note: the compiler expectedly panicked. this is a feature. + +note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675 + +note: rustc 1.66.0-dev running on x86_64-pc-windows-msvc + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0268, E0425. +For more information about an error, try `rustc --explain E0268`. diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 24d6a6951af8b..daaab79fef9ae 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -691,6 +691,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { false, None, false, + false, ); let handler = Handler::with_emitter(false, None, Box::new(emitter)); let sess = ParseSess::with_span_handler(handler, sm); diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index b12208ac62a88..ae54b2078a65b 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -179,6 +179,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { false, None, false, + false, )); let handler = rustc_errors::Handler::with_emitter(true, None, emitter); diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 6efeee98fea6c..6bfec79cd7030 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -134,6 +134,7 @@ fn default_handler( false, None, false, + false, )) }; Handler::with_emitter( From 2df1ea1850e05753bfd0263549d0d9e825927837 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 24 Oct 2022 20:52:51 +0200 Subject: [PATCH 025/482] Address some comments --- compiler/rustc_errors/src/emitter.rs | 4 ++-- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/options.rs | 4 ++-- src/librustdoc/core.rs | 4 ++-- src/test/rustdoc-ui/track-diagnostics.rs | 6 ++++++ src/test/rustdoc-ui/track-diagnostics.stderr | 10 ++++++++++ src/test/rustdoc-ui/z-help.stdout | 1 + src/tools/clippy/tests/ui/track-diagnostics.rs | 8 ++++++++ src/tools/clippy/tests/ui/track-diagnostics.stderr | 10 ++++++++++ 9 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc-ui/track-diagnostics.rs create mode 100644 src/test/rustdoc-ui/track-diagnostics.stderr create mode 100644 src/tools/clippy/tests/ui/track-diagnostics.rs create mode 100644 src/tools/clippy/tests/ui/track-diagnostics.stderr diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index b9b9a59e354b2..b7b8fe3f25a04 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -559,7 +559,7 @@ impl Emitter for EmitterWriter { &primary_span, &children, &suggestions, - Some(&diag.emitted_at), + self.track_diagnostics.then_some(&diag.emitted_at), ); } @@ -1661,7 +1661,7 @@ impl EmitterWriter { } } - if self.track_diagnostics && let Some(tracked) = emitted_at { + if let Some(tracked) = emitted_at { let track = format!("-Ztrack-diagnostics: created at {tracked}"); let len = buffer.num_lines(); buffer.append(len, &track, Style::NoStyle); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index eb8e65a6d59d3..52949232fa55b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -690,6 +690,7 @@ fn test_unstable_options_tracking_hash() { untracked!(time_llvm_passes, true); untracked!(time_passes, true); untracked!(trace_macros, true); + untracked!(track_diagnostics, false); untracked!(trim_diagnostic_paths, false); untracked!(ui_testing, true); untracked!(unpretty, Some("expanded".to_string())); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 425b03d5b1c6e..e93c4138e61b0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1587,8 +1587,8 @@ options! { "choose the TLS model to use (`rustc --print tls-models` for details)"), trace_macros: bool = (false, parse_bool, [UNTRACKED], "for every macro invocation, print its name and arguments (default: no)"), - track_diagnostics: bool = (false, parse_bool, [TRACKED], - "Tracks where in rustc a diagnostic was emitted"), + track_diagnostics: bool = (false, parse_bool, [UNTRACKED], + "tracks where in rustc a diagnostic was emitted"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 404e0a59d865b..893249e88cf7b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -166,7 +166,7 @@ pub(crate) fn new_handler( unstable_opts.teach, diagnostic_width, false, - false, + unstable_opts.track_diagnostics, ) .ui_testing(unstable_opts.ui_testing), ) @@ -185,7 +185,7 @@ pub(crate) fn new_handler( json_rendered, diagnostic_width, false, - false, + unstable_opts.track_diagnostics, ) .ui_testing(unstable_opts.ui_testing), ) diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs new file mode 100644 index 0000000000000..fc5343a982e18 --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +struct A; +struct B; +const S: A = B; diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr new file mode 100644 index 0000000000000..76453cfe220ce --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:6:14 + | +LL | const S: A = B; + | ^ expected struct `A`, found struct `B` +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 46f11d2e5d1eb..47f68f1b66b12 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -171,6 +171,7 @@ -Z time-passes=val -- measure time of each rustc pass (default: no) -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) + -Z track-diagnostics=val -- Tracks where in rustc a diagnostic was emitted -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs new file mode 100644 index 0000000000000..8c96f46d57a2f --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +struct A; +struct B; +const S: A = B; + +fn main() {} diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr new file mode 100644 index 0000000000000..76453cfe220ce --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:6:14 + | +LL | const S: A = B; + | ^ expected struct `A`, found struct `B` +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 490b232d17d4e60ee2eee19764f46b35c78b033b Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 24 Oct 2022 23:19:48 +0200 Subject: [PATCH 026/482] Add more normalization and tests --- src/test/rustdoc-ui/track-diagnostics.rs | 4 ++++ src/test/rustdoc-ui/track-diagnostics.stderr | 4 ++-- src/test/rustdoc-ui/z-help.stdout | 2 +- src/test/ui/track-diagnostics/track.rs | 5 +++++ src/test/ui/track-diagnostics/track.stderr | 10 +++++----- src/test/ui/track-diagnostics/track2.rs | 10 ++++++++++ src/test/ui/track-diagnostics/track2.stderr | 13 +++++++++++++ src/test/ui/track-diagnostics/track3.rs | 10 ++++++++++ src/test/ui/track-diagnostics/track3.stderr | 18 ++++++++++++++++++ src/test/ui/track-diagnostics/track4.rs | 13 +++++++++++++ src/test/ui/track-diagnostics/track4.stderr | 14 ++++++++++++++ src/tools/clippy/tests/ui/track-diagnostics.rs | 4 ++++ .../clippy/tests/ui/track-diagnostics.stderr | 4 ++-- 13 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/track-diagnostics/track2.rs create mode 100644 src/test/ui/track-diagnostics/track2.stderr create mode 100644 src/test/ui/track-diagnostics/track3.rs create mode 100644 src/test/ui/track-diagnostics/track3.stderr create mode 100644 src/test/ui/track-diagnostics/track4.rs create mode 100644 src/test/ui/track-diagnostics/track4.stderr diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs index fc5343a982e18..3da80adbf448c 100644 --- a/src/test/rustdoc-ui/track-diagnostics.rs +++ b/src/test/rustdoc-ui/track-diagnostics.rs @@ -1,6 +1,10 @@ // compile-flags: -Z track-diagnostics // error-pattern: created at +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" + struct A; struct B; const S: A = B; diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr index 76453cfe220ce..5a0982ff731a7 100644 --- a/src/test/rustdoc-ui/track-diagnostics.stderr +++ b/src/test/rustdoc-ui/track-diagnostics.stderr @@ -1,9 +1,9 @@ error[E0308]: mismatched types - --> $DIR/track-diagnostics.rs:6:14 + --> $DIR/track-diagnostics.rs:$LINE::$COL | LL | const S: A = B; | ^ expected struct `A`, found struct `B` --Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:$LINE::$COL error: aborting due to previous error diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 47f68f1b66b12..22e3782132288 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -171,7 +171,7 @@ -Z time-passes=val -- measure time of each rustc pass (default: no) -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) - -Z track-diagnostics=val -- Tracks where in rustc a diagnostic was emitted + -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output diff --git a/src/test/ui/track-diagnostics/track.rs b/src/test/ui/track-diagnostics/track.rs index 3427c593e856e..23c0c8c4ed8f9 100644 --- a/src/test/ui/track-diagnostics/track.rs +++ b/src/test/ui/track-diagnostics/track.rs @@ -1,6 +1,11 @@ // compile-flags: -Z track-diagnostics // error-pattern: created at +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" + fn main() { break rust } diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr index 83ff935dbabd6..ed5c70b5a06e0 100644 --- a/src/test/ui/track-diagnostics/track.stderr +++ b/src/test/ui/track-diagnostics/track.stderr @@ -1,16 +1,16 @@ error[E0425]: cannot find value `rust` in this scope - --> $DIR/track.rs:5:11 + --> $DIR/track.rs:$LINE::$COL | LL | break rust | ^^^^ not found in this scope --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:289:28 +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL error[E0268]: `break` outside of a loop - --> $DIR/track.rs:5:5 + --> $DIR/track.rs:$LINE::$COL | LL | break rust | ^^^^^^^^^^ cannot `break` outside of a loop --Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:957:10 +-Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:$LINE::$COL error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? @@ -18,7 +18,7 @@ note: the compiler expectedly panicked. this is a feature. note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675 -note: rustc 1.66.0-dev running on x86_64-pc-windows-msvc +note: rustc $VERSION running on $TARGET error: aborting due to 3 previous errors diff --git a/src/test/ui/track-diagnostics/track2.rs b/src/test/ui/track-diagnostics/track2.rs new file mode 100644 index 0000000000000..45afd081566ff --- /dev/null +++ b/src/test/ui/track-diagnostics/track2.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" + +fn main() { + let _moved @ _from = String::from("foo"); +} diff --git a/src/test/ui/track-diagnostics/track2.stderr b/src/test/ui/track-diagnostics/track2.stderr new file mode 100644 index 0000000000000..28d17f1e141f7 --- /dev/null +++ b/src/test/ui/track-diagnostics/track2.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value + --> $DIR/track2.rs:$LINE::$COL + | +LL | let _moved @ _from = String::from("foo"); + | ^^^^^^ ----- ------------------- move occurs because value has type `String`, which does not implement the `Copy` trait + | | | + | | value moved here + | value used here after move +-Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:$LINE::$COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/track-diagnostics/track3.rs b/src/test/ui/track-diagnostics/track3.rs new file mode 100644 index 0000000000000..e9316a421890c --- /dev/null +++ b/src/test/ui/track-diagnostics/track3.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" + +fn main() { + let _unimported = Blah { field: u8 }; +} diff --git a/src/test/ui/track-diagnostics/track3.stderr b/src/test/ui/track-diagnostics/track3.stderr new file mode 100644 index 0000000000000..005380df4306a --- /dev/null +++ b/src/test/ui/track-diagnostics/track3.stderr @@ -0,0 +1,18 @@ +error[E0422]: cannot find struct, variant or union type `Blah` in this scope + --> $DIR/track3.rs:$LINE::$COL + | +LL | let _unimported = Blah { field: u8 }; + | ^^^^ not found in this scope +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL + +error[E0423]: expected value, found builtin type `u8` + --> $DIR/track3.rs:$LINE::$COL + | +LL | let _unimported = Blah { field: u8 }; + | ^^ not a value +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0422, E0423. +For more information about an error, try `rustc --explain E0422`. diff --git a/src/test/ui/track-diagnostics/track4.rs b/src/test/ui/track-diagnostics/track4.rs new file mode 100644 index 0000000000000..065cc604604c9 --- /dev/null +++ b/src/test/ui/track-diagnostics/track4.rs @@ -0,0 +1,13 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" + +pub onion { + Owo(u8), + Uwu(i8), +} + +fn main() {} diff --git a/src/test/ui/track-diagnostics/track4.stderr b/src/test/ui/track-diagnostics/track4.stderr new file mode 100644 index 0000000000000..e0cedcee0d37e --- /dev/null +++ b/src/test/ui/track-diagnostics/track4.stderr @@ -0,0 +1,14 @@ +error: missing `struct` for struct definition + --> $DIR/track4.rs:$LINE::$COL + | +LL | pub onion { + | ^ +-Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/diagnostics.rs:$LINE::$COL + | +help: add `struct` here to parse `onion` as a public struct + | +LL | pub struct onion { + | ++++++ + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs index 8c96f46d57a2f..550ccd7b3d364 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.rs +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -1,6 +1,10 @@ // compile-flags: -Z track-diagnostics // error-pattern: created at +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" + struct A; struct B; const S: A = B; diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr index 76453cfe220ce..5a0982ff731a7 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -1,9 +1,9 @@ error[E0308]: mismatched types - --> $DIR/track-diagnostics.rs:6:14 + --> $DIR/track-diagnostics.rs:$LINE::$COL | LL | const S: A = B; | ^ expected struct `A`, found struct `B` --Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:$LINE::$COL error: aborting due to previous error From 7e4c5da88af31804626fd4248cd5c5854c94a53a Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 26 Oct 2022 13:41:57 +0200 Subject: [PATCH 027/482] Adjust normalization --- src/test/rustdoc-ui/track-diagnostics.rs | 2 +- src/test/rustdoc-ui/track-diagnostics.stderr | 4 ++-- src/test/ui/track-diagnostics/track.rs | 2 +- src/test/ui/track-diagnostics/track.stderr | 8 ++++---- src/test/ui/track-diagnostics/track2.rs | 2 +- src/test/ui/track-diagnostics/track2.stderr | 4 ++-- src/test/ui/track-diagnostics/track3.rs | 2 +- src/test/ui/track-diagnostics/track3.stderr | 8 ++++---- src/test/ui/track-diagnostics/track4.rs | 2 +- src/test/ui/track-diagnostics/track4.stderr | 4 ++-- src/tools/clippy/tests/ui/track-diagnostics.rs | 2 +- src/tools/clippy/tests/ui/track-diagnostics.stderr | 4 ++-- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs index 3da80adbf448c..fcc50a7aba07d 100644 --- a/src/test/rustdoc-ui/track-diagnostics.rs +++ b/src/test/rustdoc-ui/track-diagnostics.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr index 5a0982ff731a7..ec30318625311 100644 --- a/src/test/rustdoc-ui/track-diagnostics.stderr +++ b/src/test/rustdoc-ui/track-diagnostics.stderr @@ -1,9 +1,9 @@ error[E0308]: mismatched types - --> $DIR/track-diagnostics.rs:$LINE::$COL + --> $DIR/track-diagnostics.rs:LL:CC | LL | const S: A = B; | ^ expected struct `A`, found struct `B` --Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC error: aborting due to previous error diff --git a/src/test/ui/track-diagnostics/track.rs b/src/test/ui/track-diagnostics/track.rs index 23c0c8c4ed8f9..61b9137eadd90 100644 --- a/src/test/ui/track-diagnostics/track.rs +++ b/src/test/ui/track-diagnostics/track.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" // normalize-stderr-test "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" fn main() { diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr index ed5c70b5a06e0..d23f625c2d177 100644 --- a/src/test/ui/track-diagnostics/track.stderr +++ b/src/test/ui/track-diagnostics/track.stderr @@ -1,16 +1,16 @@ error[E0425]: cannot find value `rust` in this scope - --> $DIR/track.rs:$LINE::$COL + --> $DIR/track.rs:LL:CC | LL | break rust | ^^^^ not found in this scope --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error[E0268]: `break` outside of a loop - --> $DIR/track.rs:$LINE::$COL + --> $DIR/track.rs:LL:CC | LL | break rust | ^^^^^^^^^^ cannot `break` outside of a loop --Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:LL:CC error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? diff --git a/src/test/ui/track-diagnostics/track2.rs b/src/test/ui/track-diagnostics/track2.rs index 45afd081566ff..dc105c61d723b 100644 --- a/src/test/ui/track-diagnostics/track2.rs +++ b/src/test/ui/track-diagnostics/track2.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _moved @ _from = String::from("foo"); diff --git a/src/test/ui/track-diagnostics/track2.stderr b/src/test/ui/track-diagnostics/track2.stderr index 28d17f1e141f7..38a621da81644 100644 --- a/src/test/ui/track-diagnostics/track2.stderr +++ b/src/test/ui/track-diagnostics/track2.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value - --> $DIR/track2.rs:$LINE::$COL + --> $DIR/track2.rs:LL:CC | LL | let _moved @ _from = String::from("foo"); | ^^^^^^ ----- ------------------- move occurs because value has type `String`, which does not implement the `Copy` trait | | | | | value moved here | value used here after move --Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC error: aborting due to previous error diff --git a/src/test/ui/track-diagnostics/track3.rs b/src/test/ui/track-diagnostics/track3.rs index e9316a421890c..0699239503a97 100644 --- a/src/test/ui/track-diagnostics/track3.rs +++ b/src/test/ui/track-diagnostics/track3.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _unimported = Blah { field: u8 }; diff --git a/src/test/ui/track-diagnostics/track3.stderr b/src/test/ui/track-diagnostics/track3.stderr index 005380df4306a..dc468d7e8eeb1 100644 --- a/src/test/ui/track-diagnostics/track3.stderr +++ b/src/test/ui/track-diagnostics/track3.stderr @@ -1,16 +1,16 @@ error[E0422]: cannot find struct, variant or union type `Blah` in this scope - --> $DIR/track3.rs:$LINE::$COL + --> $DIR/track3.rs:LL:CC | LL | let _unimported = Blah { field: u8 }; | ^^^^ not found in this scope --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error[E0423]: expected value, found builtin type `u8` - --> $DIR/track3.rs:$LINE::$COL + --> $DIR/track3.rs:LL:CC | LL | let _unimported = Blah { field: u8 }; | ^^ not a value --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error: aborting due to 2 previous errors diff --git a/src/test/ui/track-diagnostics/track4.rs b/src/test/ui/track-diagnostics/track4.rs index 065cc604604c9..35eec799bba99 100644 --- a/src/test/ui/track-diagnostics/track4.rs +++ b/src/test/ui/track-diagnostics/track4.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" pub onion { Owo(u8), diff --git a/src/test/ui/track-diagnostics/track4.stderr b/src/test/ui/track-diagnostics/track4.stderr index e0cedcee0d37e..c4668444c4bbb 100644 --- a/src/test/ui/track-diagnostics/track4.stderr +++ b/src/test/ui/track-diagnostics/track4.stderr @@ -1,9 +1,9 @@ error: missing `struct` for struct definition - --> $DIR/track4.rs:$LINE::$COL + --> $DIR/track4.rs:LL:CC | LL | pub onion { | ^ --Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/diagnostics.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/diagnostics.rs:LL:CC | help: add `struct` here to parse `onion` as a public struct | diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs index 550ccd7b3d364..fa9221ed02d74 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.rs +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:$$LINE::$$COL" +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr index 5a0982ff731a7..ec30318625311 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -1,9 +1,9 @@ error[E0308]: mismatched types - --> $DIR/track-diagnostics.rs:$LINE::$COL + --> $DIR/track-diagnostics.rs:LL:CC | LL | const S: A = B; | ^ expected struct `A`, found struct `B` --Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:$LINE::$COL +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC error: aborting due to previous error From 65d36e9cf7b27802577502f5ba13b12d939e073d Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 26 Oct 2022 13:42:41 +0200 Subject: [PATCH 028/482] fix tracking hash test --- compiler/rustc_interface/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 52949232fa55b..a03e7b0dae527 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -690,7 +690,7 @@ fn test_unstable_options_tracking_hash() { untracked!(time_llvm_passes, true); untracked!(time_passes, true); untracked!(trace_macros, true); - untracked!(track_diagnostics, false); + untracked!(track_diagnostics, true); untracked!(trim_diagnostic_paths, false); untracked!(ui_testing, true); untracked!(unpretty, Some("expanded".to_string())); From fd3fde365b81a9acfc8e197ef24dda3a109d00fa Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Sun, 30 Oct 2022 13:55:13 +0100 Subject: [PATCH 029/482] Add parser test --- src/test/ui/track-diagnostics/track5.rs | 8 ++++++++ src/test/ui/track-diagnostics/track5.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/track-diagnostics/track5.rs create mode 100644 src/test/ui/track-diagnostics/track5.stderr diff --git a/src/test/ui/track-diagnostics/track5.rs b/src/test/ui/track-diagnostics/track5.rs new file mode 100644 index 0000000000000..c41d9424e85a9 --- /dev/null +++ b/src/test/ui/track-diagnostics/track5.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" + +} diff --git a/src/test/ui/track-diagnostics/track5.stderr b/src/test/ui/track-diagnostics/track5.stderr new file mode 100644 index 0000000000000..aa54f92b6c022 --- /dev/null +++ b/src/test/ui/track-diagnostics/track5.stderr @@ -0,0 +1,9 @@ +error: unexpected closing delimiter: `}` + --> $DIR/track5.rs:LL:CC + | +LL | } + | ^ unexpected closing delimiter +-Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC + +error: aborting due to previous error + From 110d44ecb6a70932fbf5b47d039011294b44bbd4 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 31 Oct 2022 16:14:29 +0100 Subject: [PATCH 030/482] Add more track_caller --- compiler/rustc_errors/src/lib.rs | 6 ++++-- compiler/rustc_hir_analysis/src/errors.rs | 1 + .../rustc_macros/src/diagnostics/diagnostic.rs | 3 +++ compiler/rustc_metadata/src/errors.rs | 2 ++ compiler/rustc_monomorphize/src/errors.rs | 1 + compiler/rustc_parse/src/errors.rs | 2 ++ compiler/rustc_passes/src/errors.rs | 5 +++++ compiler/rustc_session/src/parse.rs | 6 ++++++ compiler/rustc_session/src/session.rs | 15 +++++++++++++++ compiler/rustc_trait_selection/src/errors.rs | 1 + src/test/ui/track-diagnostics/track.stderr | 2 +- src/test/ui/track-diagnostics/track6.rs | 14 ++++++++++++++ src/test/ui/track-diagnostics/track6.stderr | 13 +++++++++++++ 13 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/track-diagnostics/track6.rs create mode 100644 src/test/ui/track-diagnostics/track6.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 7b33262c23937..f390495b53de4 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -766,6 +766,7 @@ impl Handler { /// Construct a builder at the `Allow` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Allow, msg) } @@ -867,6 +868,7 @@ impl Handler { /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal_with_code( &self, span: impl Into, @@ -880,6 +882,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { DiagnosticBuilder::new_fatal(self, msg) } @@ -901,6 +904,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); FatalError.raise() @@ -959,7 +963,6 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } - #[track_caller] pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -975,7 +978,6 @@ impl Handler { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). - #[track_caller] pub fn delay_good_path_bug(&self, msg: impl Into) { self.inner.borrow_mut().delay_good_path_bug(msg) } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index d5b1a7ce1c269..9442ed9d8053a 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -156,6 +156,7 @@ pub struct MissingTypeParams { // Manual implementation of `IntoDiagnostic` to be able to call `span_to_snippet`. impl<'a> IntoDiagnostic<'a> for MissingTypeParams { + #[track_caller] fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index ef1985b960e36..ab38a9ccc8f8d 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -69,6 +69,8 @@ impl<'a> DiagnosticDerive<'a> { for @Self where G: rustc_errors::EmissionGuarantee { + + #[track_caller] fn into_diagnostic( self, #handler: &'__diagnostic_handler_sess rustc_errors::Handler @@ -133,6 +135,7 @@ impl<'a> LintDiagnosticDerive<'a> { let diag = &builder.diag; structure.gen_impl(quote! { gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self { + #[track_caller] fn decorate_lint<'__b>( self, #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 289fa53aa5ef6..e5b91d566e524 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -603,6 +603,7 @@ pub struct InvalidMetadataFiles { } impl IntoDiagnostic<'_> for InvalidMetadataFiles { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, @@ -631,6 +632,7 @@ pub struct CannotFindCrate { } impl IntoDiagnostic<'_> for CannotFindCrate { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 870d50728bda4..f1ca72de8dbe4 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -39,6 +39,7 @@ pub struct UnusedGenericParams { } impl IntoDiagnostic<'_> for UnusedGenericParams { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 9b177c5189bfb..230c42d6d5991 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -918,6 +918,7 @@ pub(crate) struct ExpectedIdentifier { } impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, @@ -963,6 +964,7 @@ pub(crate) struct ExpectedSemi { } impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4a5cfd2d429cd..51ae7b9c043c0 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -736,6 +736,7 @@ pub struct InvalidAttrAtCrateLevel { } impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, @@ -868,6 +869,7 @@ pub struct BreakNonLoop<'a> { } impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, @@ -1005,6 +1007,7 @@ pub struct NakedFunctionsAsmBlock { } impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, @@ -1128,6 +1131,7 @@ pub struct NoMainErr { } impl<'a> IntoDiagnostic<'a> for NoMainErr { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, @@ -1188,6 +1192,7 @@ pub struct DuplicateLangItem { } impl IntoDiagnostic<'_> for DuplicateLangItem { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index a199947ebed05..f9f4f2979c4ea 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -97,6 +97,7 @@ pub fn feature_err<'a>( /// /// This variant allows you to control whether it is a library or language feature. /// Almost always, you want to use this for a language feature. If so, prefer `feature_err`. +#[track_caller] pub fn feature_err_issue<'a>( sess: &'a ParseSess, feature: Symbol, @@ -332,6 +333,7 @@ impl ParseSess { self.proc_macro_quoted_spans.lock().clone() } + #[track_caller] pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, @@ -339,10 +341,12 @@ impl ParseSess { err.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.create_err(err).emit() } + #[track_caller] pub fn create_warning<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, @@ -350,6 +354,7 @@ impl ParseSess { warning.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { self.create_warning(warning).emit() } @@ -377,6 +382,7 @@ impl ParseSess { } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c94d7c637531d..6d3cda684a62a 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -329,6 +329,7 @@ impl Session { self.diagnostic().struct_warn_with_expectation(msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_allow>( &self, sp: S, @@ -337,10 +338,12 @@ impl Session { self.diagnostic().struct_span_allow(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_allow(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_expect( &self, msg: impl Into, @@ -395,6 +398,7 @@ impl Session { self.diagnostic().struct_warn_with_code(msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal>( &self, sp: S, @@ -417,6 +421,7 @@ impl Session { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal>(&self, sp: S, msg: impl Into) -> ! { self.diagnostic().span_fatal(sp, msg) } @@ -489,33 +494,40 @@ impl Session { add_feature_diagnostics(&mut err, &self.parse_sess, feature); err } + #[track_caller] pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.parse_sess.emit_err(err) } + #[track_caller] pub fn create_warning<'a>( &'a self, err: impl IntoDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { self.parse_sess.create_warning(err) } + #[track_caller] pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { self.parse_sess.emit_warning(warning) } + #[track_caller] pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, Noted>, ) -> DiagnosticBuilder<'a, Noted> { self.parse_sess.create_note(note) } + #[track_caller] pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted { self.parse_sess.emit_note(note) } + #[track_caller] pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, ) -> DiagnosticBuilder<'a, !> { self.parse_sess.create_fatal(fatal) } + #[track_caller] pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! { self.parse_sess.emit_fatal(fatal) } @@ -555,6 +567,7 @@ impl Session { } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] + #[track_caller] pub fn span_warn>(&self, sp: S, msg: impl Into) { self.diagnostic().span_warn(sp, msg) } @@ -601,6 +614,8 @@ impl Session { pub fn note_without_error(&self, msg: impl Into) { self.diagnostic().note_without_error(msg) } + + #[track_caller] pub fn span_note_without_error>( &self, sp: S, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 7f87058244454..23c3715860ea6 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -67,6 +67,7 @@ pub struct NegativePositiveConflict<'a> { } impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> { + #[track_caller] fn into_diagnostic( self, handler: &Handler, diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr index d23f625c2d177..ba26cf7c7454b 100644 --- a/src/test/ui/track-diagnostics/track.stderr +++ b/src/test/ui/track-diagnostics/track.stderr @@ -10,7 +10,7 @@ error[E0268]: `break` outside of a loop | LL | break rust | ^^^^^^^^^^ cannot `break` outside of a loop --Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:LL:CC +-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? diff --git a/src/test/ui/track-diagnostics/track6.rs b/src/test/ui/track-diagnostics/track6.rs new file mode 100644 index 0000000000000..307e3101849a9 --- /dev/null +++ b/src/test/ui/track-diagnostics/track6.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + + + +pub trait Foo { + fn bar(); +} + +impl Foo for T { + default fn bar() {} +} + +fn main() {} diff --git a/src/test/ui/track-diagnostics/track6.stderr b/src/test/ui/track-diagnostics/track6.stderr new file mode 100644 index 0000000000000..1c7537633ff23 --- /dev/null +++ b/src/test/ui/track-diagnostics/track6.stderr @@ -0,0 +1,13 @@ +error[E0658]: specialization is unstable + --> $DIR/track6.rs:11:5 + | +LL | default fn bar() {} + | ^^^^^^^^^^^^^^^^^^^ +-Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:93:5 + | + = note: see issue #31844 for more information + = help: add `#![feature(specialization)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From bf5232c0ec0b4ea033eb4b24a0dbc9f410f6cfd1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 14 Oct 2022 16:11:28 -0700 Subject: [PATCH 031/482] compiletest: set the dylib path when gathering target cfg If the compiler is built with `rpath = false`, then it won't find its own libraries unless the library search path is set. We already do that while running the actual compiletests, but #100260 added another rustc command for getting the target cfg. Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) thread 'main' panicked at 'error: failed to get cfg info from "[...]/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" --- stdout --- stderr [...]/build/x86_64-unknown-linux-gnu/stage1/bin/rustc: error while loading shared libraries: librustc_driver-a2a76dc626cd02d2.so: cannot open shared object file: No such file or directory ', src/tools/compiletest/src/common.rs:476:13 Now the library path is set here as well, so it works without rpath. --- src/tools/compiletest/src/common.rs | 20 +++++++++++--------- src/tools/compiletest/src/runtest.rs | 27 +++------------------------ src/tools/compiletest/src/util.rs | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 0260f68483864..9a432f11f82ff 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -2,11 +2,12 @@ pub use self::Mode::*; use std::ffi::OsString; use std::fmt; +use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; -use crate::util::PathBufExt; +use crate::util::{add_dylib_path, PathBufExt}; use lazycell::LazyCell; use test::ColorConfig; @@ -385,8 +386,7 @@ impl Config { } fn target_cfg(&self) -> &TargetCfg { - self.target_cfg - .borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target, &self.target_rustcflags)) + self.target_cfg.borrow_with(|| TargetCfg::new(self)) } pub fn matches_arch(&self, arch: &str) -> bool { @@ -457,21 +457,23 @@ pub enum Endian { } impl TargetCfg { - fn new(rustc_path: &Path, target: &str, target_rustcflags: &Vec) -> TargetCfg { - let output = match Command::new(rustc_path) + fn new(config: &Config) -> TargetCfg { + let mut command = Command::new(&config.rustc_path); + add_dylib_path(&mut command, iter::once(&config.compile_lib_path)); + let output = match command .arg("--print=cfg") .arg("--target") - .arg(target) - .args(target_rustcflags) + .arg(&config.target) + .args(&config.target_rustcflags) .output() { Ok(output) => output, - Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path), + Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path), }; if !output.status.success() { panic!( "error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}", - rustc_path, + config.rustc_path, String::from_utf8(output.stdout).unwrap(), String::from_utf8(output.stderr).unwrap(), ); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8af5f1da694b9..f8903f754f09f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -13,7 +13,7 @@ use crate::errors::{self, Error, ErrorKind}; use crate::header::TestProps; use crate::json; use crate::read2::read2_abbreviated; -use crate::util::{logv, PathBufExt}; +use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt}; use crate::ColorConfig; use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; @@ -26,6 +26,7 @@ use std::fs::{self, create_dir_all, File, OpenOptions}; use std::hash::{Hash, Hasher}; use std::io::prelude::*; use std::io::{self, BufReader}; +use std::iter; use std::path::{Path, PathBuf}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; @@ -72,19 +73,6 @@ fn disable_error_reporting R, R>(f: F) -> R { f() } -/// The name of the environment variable that holds dynamic library locations. -pub fn dylib_env_var() -> &'static str { - if cfg!(windows) { - "PATH" - } else if cfg!(target_os = "macos") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else { - "LD_LIBRARY_PATH" - } -} - /// The platform-specific library name pub fn get_lib_name(lib: &str, dylib: bool) -> String { // In some casess (e.g. MUSL), we build a static @@ -1811,16 +1799,7 @@ impl<'test> TestCx<'test> { // Need to be sure to put both the lib_path and the aux path in the dylib // search path for the child. - let mut path = - env::split_paths(&env::var_os(dylib_env_var()).unwrap_or_default()).collect::>(); - if let Some(p) = aux_path { - path.insert(0, PathBuf::from(p)) - } - path.insert(0, PathBuf::from(lib_path)); - - // Add the new dylib search path var - let newpath = env::join_paths(&path).unwrap(); - command.env(dylib_env_var(), newpath); + add_dylib_path(&mut command, iter::once(lib_path).chain(aux_path)); let mut child = disable_error_reporting(|| command.spawn()) .unwrap_or_else(|_| panic!("failed to exec `{:?}`", &command)); diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index e5ff0906be8a5..ec36f1e4fb72e 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -2,6 +2,7 @@ use crate::common::Config; use std::env; use std::ffi::OsStr; use std::path::PathBuf; +use std::process::Command; use tracing::*; @@ -111,3 +112,25 @@ impl PathBufExt for PathBuf { } } } + +/// The name of the environment variable that holds dynamic library locations. +pub fn dylib_env_var() -> &'static str { + if cfg!(windows) { + "PATH" + } else if cfg!(target_os = "macos") { + "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" + } else { + "LD_LIBRARY_PATH" + } +} + +/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. +/// If the dylib_path_var is already set for this cmd, the old value will be overwritten! +pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator>) { + let path_env = env::var_os(dylib_env_var()); + let old_paths = path_env.as_ref().map(env::split_paths); + let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten()); + cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap()); +} From 9bf69b5a2d2804a62bc120ceceedeac14a93166d Mon Sep 17 00:00:00 2001 From: inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Date: Sat, 15 Oct 2022 02:50:17 -0700 Subject: [PATCH 032/482] Derive `Eq` and `Hash` for `ControlFlow` --- library/core/src/ops/control_flow.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 72ebe653caff3..cd183540cd5e9 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -79,7 +79,9 @@ use crate::{convert, ops}; /// [`Break`]: ControlFlow::Break /// [`Continue`]: ControlFlow::Continue #[stable(feature = "control_flow_enum_type", since = "1.55.0")] -#[derive(Debug, Clone, Copy, PartialEq)] +// ControlFlow should not implement PartialOrd or Ord, per RFC 3058: +// https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ControlFlow { /// Move on to the next phase of the operation as normal. #[stable(feature = "control_flow_enum_type", since = "1.55.0")] From 1b3d2c3c63443357b482e170dc140d7350d512f5 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 20 Oct 2022 20:28:24 +0200 Subject: [PATCH 033/482] Add style= parameter to suggestion attributes --- .../rustc_macros/src/diagnostics/utils.rs | 87 ++++++++++++++++--- .../session-diagnostic/diagnostic-derive.rs | 7 ++ .../diagnostic-derive.stderr | 4 +- .../subdiagnostic-derive.rs | 78 +++++++++++++++++ .../subdiagnostic-derive.stderr | 56 +++++++++++- 5 files changed, 214 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 374c795d0a638..aaeb0e1aba988 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -472,7 +472,7 @@ pub(super) fn build_suggestion_code( } /// Possible styles for suggestion subdiagnostics. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub(super) enum SuggestionKind { /// `#[suggestion]` Normal, @@ -489,10 +489,10 @@ impl FromStr for SuggestionKind { fn from_str(s: &str) -> Result { match s { - "" => Ok(SuggestionKind::Normal), - "_short" => Ok(SuggestionKind::Short), - "_hidden" => Ok(SuggestionKind::Hidden), - "_verbose" => Ok(SuggestionKind::Verbose), + "normal" => Ok(SuggestionKind::Normal), + "short" => Ok(SuggestionKind::Short), + "hidden" => Ok(SuggestionKind::Hidden), + "verbose" => Ok(SuggestionKind::Verbose), _ => Err(()), } } @@ -515,6 +515,16 @@ impl SuggestionKind { } } } + + fn from_suffix(s: &str) -> Option { + match s { + "" => Some(SuggestionKind::Normal), + "_short" => Some(SuggestionKind::Short), + "_hidden" => Some(SuggestionKind::Hidden), + "_verbose" => Some(SuggestionKind::Verbose), + _ => None, + } + } } /// Types of subdiagnostics that can be created using attributes @@ -565,6 +575,8 @@ impl SubdiagnosticKind { let name = name.as_str(); let meta = attr.parse_meta()?; + + let mut opt_suggestion_kind = None; let mut kind = match name { "label" => SubdiagnosticKind::Label, "note" => SubdiagnosticKind::Note, @@ -572,18 +584,31 @@ impl SubdiagnosticKind { "warning" => SubdiagnosticKind::Warn, _ => { if let Some(suggestion_kind) = - name.strip_prefix("suggestion").and_then(|s| s.parse().ok()) + name.strip_prefix("suggestion").and_then(SuggestionKind::from_suffix) { + if suggestion_kind != SuggestionKind::Normal { + // Plain `#[suggestion]` can have a `style = "..."` attribute later, so don't set it here + opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap()); + } + SubdiagnosticKind::Suggestion { - suggestion_kind, + suggestion_kind: SuggestionKind::Normal, applicability: None, code_field: new_code_ident(), code_init: TokenStream::new(), } } else if let Some(suggestion_kind) = - name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok()) + name.strip_prefix("multipart_suggestion").and_then(SuggestionKind::from_suffix) { - SubdiagnosticKind::MultipartSuggestion { suggestion_kind, applicability: None } + if suggestion_kind != SuggestionKind::Normal { + // Plain `#[multipart_suggestion]` can have a `style = "..."` attribute later, so don't set it here + opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap()); + } + + SubdiagnosticKind::MultipartSuggestion { + suggestion_kind: SuggestionKind::Normal, + applicability: None, + } } else { throw_invalid_attr!(attr, &meta); } @@ -682,16 +707,37 @@ impl SubdiagnosticKind { }); applicability.set_once(value, span); } + ( + "style", + SubdiagnosticKind::Suggestion { .. } + | SubdiagnosticKind::MultipartSuggestion { .. }, + ) => { + let Some(value) = string_value else { + invalid_nested_attr(attr, &nested_attr).emit(); + continue; + }; + + let value = value.value().parse().unwrap_or_else(|()| { + span_err(value.span().unwrap(), "invalid suggestion style") + .help("valid styles are `normal`, `short`, `hidden` and `verbose`") + .emit(); + SuggestionKind::Normal + }); + + opt_suggestion_kind.set_once(value, span); + } // Invalid nested attribute (_, SubdiagnosticKind::Suggestion { .. }) => { invalid_nested_attr(attr, &nested_attr) - .help("only `code` and `applicability` are valid nested attributes") + .help( + "only `style`, `code` and `applicability` are valid nested attributes", + ) .emit(); } (_, SubdiagnosticKind::MultipartSuggestion { .. }) => { invalid_nested_attr(attr, &nested_attr) - .help("only `applicability` is a valid nested attributes") + .help("only `style` and `applicability` are valid nested attributes") .emit() } _ => { @@ -701,7 +747,16 @@ impl SubdiagnosticKind { } match kind { - SubdiagnosticKind::Suggestion { ref code_field, ref mut code_init, .. } => { + SubdiagnosticKind::Suggestion { + ref code_field, + ref mut code_init, + ref mut suggestion_kind, + .. + } => { + if let Some(kind) = opt_suggestion_kind.value() { + *suggestion_kind = kind; + } + *code_init = if let Some(init) = code.value() { init } else { @@ -709,11 +764,15 @@ impl SubdiagnosticKind { quote! { let #code_field = std::iter::empty(); } }; } + SubdiagnosticKind::MultipartSuggestion { ref mut suggestion_kind, .. } => { + if let Some(kind) = opt_suggestion_kind.value() { + *suggestion_kind = kind; + } + } SubdiagnosticKind::Label | SubdiagnosticKind::Note | SubdiagnosticKind::Help - | SubdiagnosticKind::Warn - | SubdiagnosticKind::MultipartSuggestion { .. } => {} + | SubdiagnosticKind::Warn => {} } Ok(Some((kind, slug))) diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index ca77e483d6ff8..6cd765827953d 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -796,3 +796,10 @@ struct SuggestionsInvalidLiteral { //~^ ERROR `code = "..."`/`code(...)` must contain only string literals sub: Span, } + +#[derive(Diagnostic)] +#[diag(compiletest_example)] +struct SuggestionStyleGood { + #[suggestion(code = "", style = "hidden")] + sub: Span, +} diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 859c272b6ba9c..5a0948e4dcb76 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -272,7 +272,7 @@ error: `#[suggestion(nonsense = ...)]` is not a valid attribute LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ | - = help: only `code` and `applicability` are valid nested attributes + = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:231:5 @@ -286,7 +286,7 @@ error: `#[suggestion(msg = ...)]` is not a valid attribute LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ | - = help: only `code` and `applicability` are valid nested attributes + = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:240:5 diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index efec85eb52c2e..9a1a57e2eaf99 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -706,3 +706,81 @@ struct BQ { span: Span, r#type: String, } + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "")] +struct SuggestionStyleDefault { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "short")] +struct SuggestionStyleShort { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "hidden")] +struct SuggestionStyleHidden { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "verbose")] +struct SuggestionStyleVerbose { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] +//~^ ERROR specified multiple times +//~| NOTE previously specified here +struct SuggestionStyleTwice { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion_hidden(parser_add_paren, code = "", style = "normal")] +//~^ ERROR specified multiple times +//~| NOTE previously specified here +struct SuggestionStyleTwiceExplicit { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "foo")] +//~^ ERROR invalid suggestion style +struct SuggestionStyleInvalid1 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = 42)] +//~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute +struct SuggestionStyleInvalid2 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style)] +//~^ ERROR `#[suggestion(style)]` is not a valid attribute +struct SuggestionStyleInvalid3 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style("foo"))] +//~^ ERROR `#[suggestion(style(...))]` is not a valid attribute +struct SuggestionStyleInvalid4 { + #[primary_span] + sub: Span, +} diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index a85a8711eaca4..d5e136fa40ccf 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -320,7 +320,7 @@ error: `#[multipart_suggestion(code = ...)]` is not a valid attribute LL | #[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")] | ^^^^^^^^^^^^ | - = help: only `applicability` is a valid nested attributes + = help: only `style` and `applicability` are valid nested attributes error: multipart suggestion without any `#[suggestion_part(...)]` fields --> $DIR/subdiagnostic-derive.rs:536:1 @@ -445,6 +445,58 @@ error: `code = "..."`/`code(...)` must contain only string literals LL | #[suggestion_part(code = 3)] | ^^^^^^^^ +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:739:61 + | +LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] + | ^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:739:43 + | +LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] + | ^^^^^^^^^^^^^^^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:748:50 + | +LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] + | ^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:748:3 + | +LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] + | ^^^^^^^^^^^^^^^^^ + +error: invalid suggestion style + --> $DIR/subdiagnostic-derive.rs:757:51 + | +LL | #[suggestion(parser_add_paren, code = "", style = "foo")] + | ^^^^^ + | + = help: valid styles are `normal`, `short`, `hidden` and `verbose` + +error: `#[suggestion(style = ...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:765:43 + | +LL | #[suggestion(parser_add_paren, code = "", style = 42)] + | ^^^^^^^^^^ + +error: `#[suggestion(style)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:773:43 + | +LL | #[suggestion(parser_add_paren, code = "", style)] + | ^^^^^ + | + = help: a diagnostic slug must be the first argument to the attribute + +error: `#[suggestion(style(...))]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:781:43 + | +LL | #[suggestion(parser_add_paren, code = "", style("foo"))] + | ^^^^^^^^^^^^ + error: cannot find attribute `foo` in this scope --> $DIR/subdiagnostic-derive.rs:63:3 | @@ -505,6 +557,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent` LL | #[label(slug)] | ^^^^ not found in `rustc_errors::fluent` -error: aborting due to 72 previous errors +error: aborting due to 78 previous errors For more information about this error, try `rustc --explain E0425`. From 6bedbb559223301e8b7de3f3510900cb74cfeb49 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 20 Oct 2022 21:09:54 +0200 Subject: [PATCH 034/482] rustfmt diagnostic derive tests --- .../session-diagnostic/diagnostic-derive.rs | 23 +++--- .../diagnostic-derive.stderr | 70 +++++++++---------- .../subdiagnostic-derive.rs | 52 +++++++------- .../subdiagnostic-derive.stderr | 20 +++--- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 6cd765827953d..b998f71e3aa5e 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -40,9 +40,9 @@ struct HelloWarn {} //~^ ERROR unsupported type attribute for diagnostic derive enum enum DiagnosticOnEnum { Foo, -//~^ ERROR diagnostic slug not specified + //~^ ERROR diagnostic slug not specified Bar, -//~^ ERROR diagnostic slug not specified + //~^ ERROR diagnostic slug not specified } #[derive(Diagnostic)] @@ -536,8 +536,7 @@ struct LabelWithTrailingList { #[derive(LintDiagnostic)] #[diag(compiletest_example)] -struct LintsGood { -} +struct LintsGood {} #[derive(LintDiagnostic)] #[diag(compiletest_example)] @@ -683,7 +682,7 @@ struct RawIdentDiagnosticArg { #[diag(compiletest_example)] struct SubdiagnosticBad { #[subdiagnostic(bad)] -//~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute + //~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute note: Note, } @@ -691,7 +690,7 @@ struct SubdiagnosticBad { #[diag(compiletest_example)] struct SubdiagnosticBadStr { #[subdiagnostic = "bad"] -//~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute + //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute note: Note, } @@ -699,7 +698,7 @@ struct SubdiagnosticBadStr { #[diag(compiletest_example)] struct SubdiagnosticBadTwice { #[subdiagnostic(bad, bad)] -//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -707,7 +706,7 @@ struct SubdiagnosticBadTwice { #[diag(compiletest_example)] struct SubdiagnosticBadLitStr { #[subdiagnostic("bad")] -//~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute + //~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute note: Note, } @@ -715,7 +714,7 @@ struct SubdiagnosticBadLitStr { #[diag(compiletest_example)] struct SubdiagnosticEagerLint { #[subdiagnostic(eager)] -//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -731,11 +730,7 @@ struct SubdiagnosticEagerCorrect { // after the `span_suggestion` call - which breaks eager translation. #[derive(Subdiagnostic)] -#[suggestion_short( - use_instead, - applicability = "machine-applicable", - code = "{correct}" -)] +#[suggestion_short(use_instead, applicability = "machine-applicable", code = "{correct}")] pub(crate) struct SubdiagnosticWithSuggestion { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 5a0948e4dcb76..5943ffa6bc2bf 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -373,7 +373,7 @@ LL | #[label(label, foo("..."))] | ^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:545:5 + --> $DIR/diagnostic-derive.rs:544:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -381,13 +381,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:565:1 + --> $DIR/diagnostic-derive.rs:564:1 | LL | #[error(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:565:1 + --> $DIR/diagnostic-derive.rs:564:1 | LL | / #[error(compiletest_example, code = "E0123")] LL | | @@ -399,13 +399,13 @@ LL | | struct ErrorAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:572:1 + --> $DIR/diagnostic-derive.rs:571:1 | LL | #[warn_(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:572:1 + --> $DIR/diagnostic-derive.rs:571:1 | LL | / #[warn_(compiletest_example, code = "E0123")] LL | | @@ -417,13 +417,13 @@ LL | | struct WarnAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:579:1 + --> $DIR/diagnostic-derive.rs:578:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:579:1 + --> $DIR/diagnostic-derive.rs:578:1 | LL | / #[lint(compiletest_example, code = "E0123")] LL | | @@ -435,19 +435,19 @@ LL | | struct LintAttributeOnSessionDiag {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:585:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:585:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:585:1 | LL | / #[lint(compiletest_example, code = "E0123")] LL | | @@ -460,19 +460,19 @@ LL | | struct LintAttributeOnLintDiag {} = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:596:44 + --> $DIR/diagnostic-derive.rs:595:44 | LL | #[suggestion(suggestion, code = "...", code = ",,,")] | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:596:30 + --> $DIR/diagnostic-derive.rs:595:30 | LL | #[suggestion(suggestion, code = "...", code = ",,,")] | ^^^^^^^^^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:605:24 + --> $DIR/diagnostic-derive.rs:604:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -480,7 +480,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:613:17 + --> $DIR/diagnostic-derive.rs:612:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -488,13 +488,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:620:5 + --> $DIR/diagnostic-derive.rs:619:5 | LL | #[suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:627:1 + --> $DIR/diagnostic-derive.rs:626:1 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -502,7 +502,7 @@ LL | #[multipart_suggestion(suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:630:1 + --> $DIR/diagnostic-derive.rs:629:1 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -510,7 +510,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:634:5 + --> $DIR/diagnostic-derive.rs:633:5 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -518,7 +518,7 @@ LL | #[multipart_suggestion(suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:642:1 + --> $DIR/diagnostic-derive.rs:641:1 | LL | #[suggestion(suggestion, code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -526,7 +526,7 @@ LL | #[suggestion(suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:651:1 + --> $DIR/diagnostic-derive.rs:650:1 | LL | #[label] | ^^^^^^^^ @@ -534,7 +534,7 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(bad)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:685:21 + --> $DIR/diagnostic-derive.rs:684:21 | LL | #[subdiagnostic(bad)] | ^^^ @@ -542,7 +542,7 @@ LL | #[subdiagnostic(bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:693:5 + --> $DIR/diagnostic-derive.rs:692:5 | LL | #[subdiagnostic = "bad"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -550,7 +550,7 @@ LL | #[subdiagnostic = "bad"] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:701:5 + --> $DIR/diagnostic-derive.rs:700:5 | LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -558,7 +558,7 @@ LL | #[subdiagnostic(bad, bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic("...")]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:709:21 + --> $DIR/diagnostic-derive.rs:708:21 | LL | #[subdiagnostic("bad")] | ^^^^^ @@ -566,7 +566,7 @@ LL | #[subdiagnostic("bad")] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:717:5 + --> $DIR/diagnostic-derive.rs:716:5 | LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -574,19 +574,19 @@ LL | #[subdiagnostic(eager)] = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:779:18 + --> $DIR/diagnostic-derive.rs:774:18 | LL | #[suggestion(code())] | ^^^^^^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:787:23 + --> $DIR/diagnostic-derive.rs:782:23 | LL | #[suggestion(code(foo))] | ^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:795:18 + --> $DIR/diagnostic-derive.rs:790:18 | LL | #[suggestion(code = 3)] | ^^^^^^^^ @@ -604,43 +604,43 @@ LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:565:3 + --> $DIR/diagnostic-derive.rs:564:3 | LL | #[error(compiletest_example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:572:3 + --> $DIR/diagnostic-derive.rs:571:3 | LL | #[warn_(compiletest_example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:579:3 + --> $DIR/diagnostic-derive.rs:578:3 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:586:3 + --> $DIR/diagnostic-derive.rs:585:3 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:627:3 + --> $DIR/diagnostic-derive.rs:626:3 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:630:3 + --> $DIR/diagnostic-derive.rs:629:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:634:7 + --> $DIR/diagnostic-derive.rs:633:7 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 9a1a57e2eaf99..50a6c816578b0 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -11,13 +11,13 @@ #![crate_type = "lib"] extern crate rustc_errors; +extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; -extern crate rustc_macros; use rustc_errors::Applicability; -use rustc_span::Span; use rustc_macros::Subdiagnostic; +use rustc_span::Span; #[derive(Subdiagnostic)] #[label(parser_add_paren)] @@ -40,7 +40,7 @@ enum B { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -165,7 +165,7 @@ enum P { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -177,7 +177,7 @@ enum Q { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -189,7 +189,7 @@ enum R { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -201,7 +201,7 @@ enum S { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -213,7 +213,7 @@ enum T { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -225,7 +225,7 @@ enum U { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -240,7 +240,7 @@ enum V { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -301,14 +301,14 @@ struct AB { #[primary_span] span: Span, #[skip_arg] - z: Z + z: Z, } #[derive(Subdiagnostic)] union AC { -//~^ ERROR unexpected unsupported untagged union + //~^ ERROR unexpected unsupported untagged union span: u32, - b: u64 + b: u64, } #[derive(Subdiagnostic)] @@ -372,7 +372,7 @@ enum AI { #[applicability] applicability: Applicability, var: String, - } + }, } #[derive(Subdiagnostic)] @@ -427,7 +427,7 @@ struct AN { } #[derive(Subdiagnostic)] -#[suggestion(parser_add_paren, code ="...", applicability = "foo")] +#[suggestion(parser_add_paren, code = "...", applicability = "foo")] //~^ ERROR invalid applicability struct AO { #[primary_span] @@ -437,7 +437,7 @@ struct AO { #[derive(Subdiagnostic)] #[help(parser_add_paren)] struct AP { - var: String + var: String, } #[derive(Subdiagnostic)] @@ -452,7 +452,7 @@ struct AR { } #[derive(Subdiagnostic)] -#[suggestion(parser_add_paren, code ="...", applicability = "machine-applicable")] +#[suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")] struct AS { #[primary_span] span: Span, @@ -467,11 +467,11 @@ enum AT { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] -#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] +#[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] struct AU { #[primary_span] span: Span, @@ -479,7 +479,7 @@ struct AU { } #[derive(Subdiagnostic)] -#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] +#[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] //~^ ERROR `var` doesn't refer to a field on this type struct AV { #[primary_span] @@ -488,22 +488,22 @@ struct AV { #[derive(Subdiagnostic)] enum AW { - #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] + #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] A { #[primary_span] span: Span, var: String, - } + }, } #[derive(Subdiagnostic)] enum AX { - #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] -//~^ ERROR `var` doesn't refer to a field on this type + #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] + //~^ ERROR `var` doesn't refer to a field on this type A { #[primary_span] span: Span, - } + }, } #[derive(Subdiagnostic)] @@ -659,7 +659,7 @@ enum BL { /// ..and the field #[primary_span] span: Span, - } + }, } #[derive(Subdiagnostic)] diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index d5e136fa40ccf..4ae7ed34230df 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -186,7 +186,7 @@ error: unexpected unsupported untagged union LL | / union AC { LL | | LL | | span: u32, -LL | | b: u64 +LL | | b: u64, LL | | } | |_^ @@ -253,10 +253,10 @@ LL | #[suggestion(parser_add_paren)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:430:45 + --> $DIR/subdiagnostic-derive.rs:430:46 | -LL | #[suggestion(parser_add_paren, code ="...", applicability = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(parser_add_paren, code = "...", applicability = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:448:1 @@ -275,16 +275,16 @@ LL | #[label] | ^^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:482:38 + --> $DIR/subdiagnostic-derive.rs:482:39 | -LL | #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:501:42 + --> $DIR/subdiagnostic-derive.rs:501:43 | -LL | #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(parser_add_paren, code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: `#[suggestion_part]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:524:5 From 7529c9b703e45cd0cade2cafc426540c1c695d86 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 20 Oct 2022 21:17:14 +0200 Subject: [PATCH 035/482] Add "tool-only" suggestion style --- compiler/rustc_macros/src/diagnostics/utils.rs | 13 ++++++++----- .../session-diagnostic/subdiagnostic-derive.rs | 7 +++++++ .../subdiagnostic-derive.stderr | 18 +++++++++--------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index aaeb0e1aba988..99ecaaae0e8c8 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -474,14 +474,11 @@ pub(super) fn build_suggestion_code( /// Possible styles for suggestion subdiagnostics. #[derive(Clone, Copy, PartialEq)] pub(super) enum SuggestionKind { - /// `#[suggestion]` Normal, - /// `#[suggestion_short]` Short, - /// `#[suggestion_hidden]` Hidden, - /// `#[suggestion_verbose]` Verbose, + ToolOnly, } impl FromStr for SuggestionKind { @@ -493,6 +490,7 @@ impl FromStr for SuggestionKind { "short" => Ok(SuggestionKind::Short), "hidden" => Ok(SuggestionKind::Hidden), "verbose" => Ok(SuggestionKind::Verbose), + "tool-only" => Ok(SuggestionKind::ToolOnly), _ => Err(()), } } @@ -513,6 +511,9 @@ impl SuggestionKind { SuggestionKind::Verbose => { quote! { rustc_errors::SuggestionStyle::ShowAlways } } + SuggestionKind::ToolOnly => { + quote! { rustc_errors::SuggestionStyle::CompletelyHidden } + } } } @@ -583,6 +584,8 @@ impl SubdiagnosticKind { "help" => SubdiagnosticKind::Help, "warning" => SubdiagnosticKind::Warn, _ => { + // FIXME(#100717): remove #[suggestion_{short,verbose,hidden}] attributes, use + // #[suggestion(style = "...")] instead if let Some(suggestion_kind) = name.strip_prefix("suggestion").and_then(SuggestionKind::from_suffix) { @@ -719,7 +722,7 @@ impl SubdiagnosticKind { let value = value.value().parse().unwrap_or_else(|()| { span_err(value.span().unwrap(), "invalid suggestion style") - .help("valid styles are `normal`, `short`, `hidden` and `verbose`") + .help("valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only`") .emit(); SuggestionKind::Normal }); diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 50a6c816578b0..7d9e2576cae3c 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -735,6 +735,13 @@ struct SuggestionStyleVerbose { sub: Span, } +#[derive(Subdiagnostic)] +#[suggestion(parser_add_paren, code = "", style = "tool-only")] +struct SuggestionStyleToolOnly { + #[primary_span] + sub: Span, +} + #[derive(Subdiagnostic)] #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] //~^ ERROR specified multiple times diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 4ae7ed34230df..b76b7fdfceac9 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -446,45 +446,45 @@ LL | #[suggestion_part(code = 3)] | ^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:739:61 + --> $DIR/subdiagnostic-derive.rs:746:61 | LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:739:43 + --> $DIR/subdiagnostic-derive.rs:746:43 | LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:748:50 + --> $DIR/subdiagnostic-derive.rs:755:50 | LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:748:3 + --> $DIR/subdiagnostic-derive.rs:755:3 | LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] | ^^^^^^^^^^^^^^^^^ error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:757:51 + --> $DIR/subdiagnostic-derive.rs:764:51 | LL | #[suggestion(parser_add_paren, code = "", style = "foo")] | ^^^^^ | - = help: valid styles are `normal`, `short`, `hidden` and `verbose` + = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: `#[suggestion(style = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:765:43 + --> $DIR/subdiagnostic-derive.rs:772:43 | LL | #[suggestion(parser_add_paren, code = "", style = 42)] | ^^^^^^^^^^ error: `#[suggestion(style)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:773:43 + --> $DIR/subdiagnostic-derive.rs:780:43 | LL | #[suggestion(parser_add_paren, code = "", style)] | ^^^^^ @@ -492,7 +492,7 @@ LL | #[suggestion(parser_add_paren, code = "", style)] = help: a diagnostic slug must be the first argument to the attribute error: `#[suggestion(style(...))]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:781:43 + --> $DIR/subdiagnostic-derive.rs:788:43 | LL | #[suggestion(parser_add_paren, code = "", style("foo"))] | ^^^^^^^^^^^^ From cd9cadd5a512418cce680bf4f8c4c83faf543482 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sat, 22 Oct 2022 15:48:55 +0200 Subject: [PATCH 036/482] Convert all #[suggestion_*] attributes to #[suggestion(style = "...")] Using the following command: find compiler/ -type f -name '*.rs' -exec perl -i -gpe \ 's/(#\[\w*suggestion)_(short|verbose|hidden)\(\s*(\S+,)?/\1(\3style = "\2",/g' \ '{}' + --- compiler/rustc_ast_lowering/src/errors.rs | 3 +- .../rustc_borrowck/src/session_diagnostics.rs | 2 +- compiler/rustc_hir_analysis/src/errors.rs | 8 ++- compiler/rustc_hir_typeck/src/errors.rs | 3 +- compiler/rustc_infer/src/errors/mod.rs | 15 ++-- compiler/rustc_lint/src/errors.rs | 2 +- .../src/opaque_hidden_inferred_bound.rs | 3 +- compiler/rustc_macros/src/diagnostics/mod.rs | 2 +- compiler/rustc_parse/src/errors.rs | 71 ++++++++++++------- compiler/rustc_passes/src/errors.rs | 2 +- 10 files changed, 73 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 157f46501e145..21c6a2d26f4c2 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> { pub struct SubTupleBinding<'a> { #[primary_span] #[label] - #[suggestion_verbose( + #[suggestion( ast_lowering_sub_tuple_binding_suggestion, + style = "verbose", code = "..", applicability = "maybe-incorrect" )] diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index cff3089c397cb..fe24f85fae10a 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -49,7 +49,7 @@ pub(crate) struct GenericDoesNotLiveLongEnough { #[derive(LintDiagnostic)] #[diag(borrowck_var_does_not_need_mut)] pub(crate) struct VarNeedNotMut { - #[suggestion_short(applicability = "machine-applicable", code = "")] + #[suggestion(style = "short", applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 9442ed9d8053a..afbb27155a2f5 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -120,7 +120,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> { #[primary_span] #[label] pub span: Span, - #[suggestion_verbose(code = "{ty}")] + #[suggestion(style = "verbose", code = "{ty}")] pub opt_sugg: Option<(Span, Applicability)>, } @@ -239,7 +239,11 @@ pub struct UnusedExternCrate { #[derive(LintDiagnostic)] #[diag(hir_analysis_extern_crate_not_idiomatic)] pub struct ExternCrateNotIdiomatic { - #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")] + #[suggestion( + style = "short", + applicability = "machine-applicable", + code = "{suggestion_code}" + )] pub span: Span, pub msg_code: String, pub suggestion_code: String, diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 175037f9b3a14..cfb408396da05 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -113,8 +113,9 @@ pub struct MissingParentheseInRange { } #[derive(Subdiagnostic)] -#[multipart_suggestion_verbose( +#[multipart_suggestion( hir_analysis_add_missing_parentheses_in_range, + style = "verbose", applicability = "maybe-incorrect" )] pub struct AddMissingParenthesesInRange { diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 2131d19068e50..bb04e1c49baea 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -109,8 +109,9 @@ pub struct InferenceBadError<'a> { #[derive(Subdiagnostic)] pub enum SourceKindSubdiag<'a> { - #[suggestion_verbose( + #[suggestion( infer_source_kind_subdiag_let, + style = "verbose", code = ": {type_name}", applicability = "has-placeholders" )] @@ -135,8 +136,9 @@ pub enum SourceKindSubdiag<'a> { parent_prefix: String, parent_name: String, }, - #[suggestion_verbose( + #[suggestion( infer_source_kind_subdiag_generic_suggestion, + style = "verbose", code = "::<{args}>", applicability = "has-placeholders" )] @@ -150,8 +152,9 @@ pub enum SourceKindSubdiag<'a> { #[derive(Subdiagnostic)] pub enum SourceKindMultiSuggestion<'a> { - #[multipart_suggestion_verbose( + #[multipart_suggestion( infer_source_kind_fully_qualified, + style = "verbose", applicability = "has-placeholders" )] FullyQualified { @@ -163,8 +166,9 @@ pub enum SourceKindMultiSuggestion<'a> { adjustment: &'a str, successor_pos: &'a str, }, - #[multipart_suggestion_verbose( + #[multipart_suggestion( infer_source_kind_closure_return, + style = "verbose", applicability = "has-placeholders" )] ClosureReturn { @@ -478,8 +482,9 @@ pub enum ImplicitStaticLifetimeSubdiag { #[primary_span] span: Span, }, - #[suggestion_verbose( + #[suggestion( infer_implicit_static_lifetime_suggestion, + style = "verbose", code = " + '_", applicability = "maybe-incorrect" )] diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index a49d1bdacc25b..1a769893f5520 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -83,7 +83,7 @@ pub struct UnknownToolInScopedLint { pub struct BuiltinEllpisisInclusiveRangePatterns { #[primary_span] pub span: Span, - #[suggestion_short(code = "{replace}", applicability = "machine-applicable")] + #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] pub suggestion: Span, pub replace: String, } diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 00bf287ba6bdd..7443d131c64dc 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -150,8 +150,9 @@ struct OpaqueHiddenInferredBoundLint<'tcx> { } #[derive(Subdiagnostic)] -#[suggestion_verbose( +#[suggestion( lint_opaque_hidden_inferred_bound_sugg, + style = "verbose", applicability = "machine-applicable", code = " + {trait_ref}" )] diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 860340b439061..78df0cd1d341a 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -129,7 +129,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// } /// /// #[derive(Subdiagnostic)] -/// #[suggestion_verbose(parser::raw_identifier)] +/// #[suggestion(style = "verbose",parser::raw_identifier)] /// pub struct RawIdentifierSuggestion<'tcx> { /// #[primary_span] /// span: Span, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 230c42d6d5991..dc20490284293 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -64,7 +64,7 @@ pub(crate) struct BadQPathStage2 { #[diag(parser_incorrect_semicolon)] pub(crate) struct IncorrectSemicolon<'a> { #[primary_span] - #[suggestion_short(code = "", applicability = "machine-applicable")] + #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, #[help] pub opt_help: Option<()>, @@ -136,7 +136,12 @@ pub(crate) struct InvalidComparisonOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidComparisonOperatorSub { - #[suggestion_short(use_instead, applicability = "machine-applicable", code = "{correct}")] + #[suggestion( + use_instead, + style = "short", + applicability = "machine-applicable", + code = "{correct}" + )] Correctable { #[primary_span] span: Span, @@ -160,14 +165,16 @@ pub(crate) struct InvalidLogicalOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidLogicalOperatorSub { - #[suggestion_short( + #[suggestion( use_amp_amp_for_conjunction, + style = "short", applicability = "machine-applicable", code = "&&" )] Conjunction(#[primary_span] Span), - #[suggestion_short( + #[suggestion( use_pipe_pipe_for_disjunction, + style = "short", applicability = "machine-applicable", code = "||" )] @@ -178,7 +185,7 @@ pub(crate) enum InvalidLogicalOperatorSub { #[diag(parser_tilde_is_not_unary_operator)] pub(crate) struct TildeAsUnaryOperator( #[primary_span] - #[suggestion_short(applicability = "machine-applicable", code = "!")] + #[suggestion(style = "short", applicability = "machine-applicable", code = "!")] pub Span, ); @@ -194,22 +201,25 @@ pub(crate) struct NotAsNegationOperator { #[derive(Subdiagnostic)] pub enum NotAsNegationOperatorSub { - #[suggestion_short( + #[suggestion( parser_unexpected_token_after_not_default, + style = "short", applicability = "machine-applicable", code = "!" )] SuggestNotDefault(#[primary_span] Span), - #[suggestion_short( + #[suggestion( parser_unexpected_token_after_not_bitwise, + style = "short", applicability = "machine-applicable", code = "!" )] SuggestNotBitwise(#[primary_span] Span), - #[suggestion_short( + #[suggestion( parser_unexpected_token_after_not_logical, + style = "short", applicability = "machine-applicable", code = "!" )] @@ -249,7 +259,7 @@ pub(crate) struct UnexpectedTokenAfterLabel { #[primary_span] #[label(parser_unexpected_token_after_label)] pub span: Span, - #[suggestion_verbose(suggestion_remove_label, code = "")] + #[suggestion(suggestion_remove_label, style = "verbose", code = "")] pub remove_label: Option, #[subdiagnostic] pub enclose_in_block: Option, @@ -272,7 +282,7 @@ pub(crate) struct RequireColonAfterLabeledExpression { pub span: Span, #[label] pub label: Span, - #[suggestion_short(applicability = "machine-applicable", code = ": ")] + #[suggestion(style = "short", applicability = "machine-applicable", code = ": ")] pub label_end: Span, } @@ -354,7 +364,7 @@ pub(crate) struct IntLiteralTooLarge { pub(crate) struct MissingSemicolonBeforeArray { #[primary_span] pub open_delim: Span, - #[suggestion_verbose(applicability = "maybe-incorrect", code = ";")] + #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = ";")] pub semicolon: Span, } @@ -442,9 +452,9 @@ pub(crate) struct MissingInInForLoop { #[derive(Subdiagnostic)] pub(crate) enum MissingInInForLoopSub { // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect - #[suggestion_short(use_in_not_of, applicability = "maybe-incorrect", code = "in")] + #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")] InNotOf(#[primary_span] Span), - #[suggestion_short(add_in, applicability = "maybe-incorrect", code = " in ")] + #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")] AddIn(#[primary_span] Span), } @@ -470,7 +480,7 @@ pub(crate) struct CatchAfterTry { pub(crate) struct CommaAfterBaseStruct { #[primary_span] pub span: Span, - #[suggestion_short(applicability = "machine-applicable", code = "")] + #[suggestion(style = "short", applicability = "machine-applicable", code = "")] pub comma: Span, } @@ -512,7 +522,7 @@ pub(crate) struct RemoveLet { #[diag(parser_use_eq_instead)] pub(crate) struct UseEqInstead { #[primary_span] - #[suggestion_short(applicability = "machine-applicable", code = "=")] + #[suggestion(style = "short", applicability = "machine-applicable", code = "=")] pub span: Span, } @@ -520,7 +530,7 @@ pub(crate) struct UseEqInstead { #[diag(parser_use_empty_block_not_semi)] pub(crate) struct UseEmptyBlockNotSemi { #[primary_span] - #[suggestion_hidden(applicability = "machine-applicable", code = "{{}}")] + #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")] pub span: Span, } @@ -576,7 +586,12 @@ pub(crate) struct LeadingPlusNotSupported { #[primary_span] #[label] pub span: Span, - #[suggestion_verbose(suggestion_remove_plus, code = "", applicability = "machine-applicable")] + #[suggestion( + suggestion_remove_plus, + style = "verbose", + code = "", + applicability = "machine-applicable" + )] pub remove_plus: Option, #[subdiagnostic] pub add_parentheses: Option, @@ -843,7 +858,7 @@ pub(crate) struct InvalidCurlyInLetElse { #[help] pub(crate) struct CompoundAssignmentExpressionInLet { #[primary_span] - #[suggestion_short(code = "=", applicability = "maybe-incorrect")] + #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")] pub span: Span, } @@ -864,8 +879,9 @@ pub(crate) struct InvalidMetaItem { } #[derive(Subdiagnostic)] -#[suggestion_verbose( +#[suggestion( parser_sugg_escape_to_use_as_identifier, + style = "verbose", applicability = "maybe-incorrect", code = "r#" )] @@ -1005,7 +1021,12 @@ pub(crate) enum ExpectedSemiSugg { applicability = "machine-applicable" )] ChangeToSemi(#[primary_span] Span), - #[suggestion_short(parser_sugg_add_semi, code = ";", applicability = "machine-applicable")] + #[suggestion( + parser_sugg_add_semi, + style = "short", + code = ";", + applicability = "machine-applicable" + )] AddSemi(#[primary_span] Span), } @@ -1059,8 +1080,9 @@ pub(crate) struct GenericParamsWithoutAngleBracketsSugg { pub(crate) struct ComparisonOperatorsCannotBeChained { #[primary_span] pub span: Vec, - #[suggestion_verbose( + #[suggestion( parser_sugg_turbofish_syntax, + style = "verbose", code = "::", applicability = "maybe-incorrect" )] @@ -1074,8 +1096,9 @@ pub(crate) struct ComparisonOperatorsCannotBeChained { #[derive(Subdiagnostic)] pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { - #[suggestion_verbose( + #[suggestion( sugg_split_comparison, + style = "verbose", code = " && {middle_term}", applicability = "maybe-incorrect" )] @@ -1217,7 +1240,7 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg { pub(crate) struct UnexpectedConstInGenericParam { #[primary_span] pub span: Span, - #[suggestion_verbose(code = "", applicability = "maybe-incorrect")] + #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")] pub to_remove: Option, } @@ -1225,7 +1248,7 @@ pub(crate) struct UnexpectedConstInGenericParam { #[diag(parser_async_move_order_incorrect)] pub(crate) struct AsyncMoveOrderIncorrect { #[primary_span] - #[suggestion_verbose(code = "async move", applicability = "maybe-incorrect")] + #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")] pub span: Span, } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 51ae7b9c043c0..fb883ae2ed0a7 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -291,7 +291,7 @@ pub struct DocTestUnknownAny { #[note(no_op_note)] pub struct DocTestUnknownSpotlight { pub path: String, - #[suggestion_short(applicability = "machine-applicable", code = "notable_trait")] + #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] pub span: Span, } From 98de0a2f0d5d095883e9c7d806993290a59cc69b Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sat, 22 Oct 2022 17:21:11 +0200 Subject: [PATCH 037/482] Remove #[suggestion_*] attributes --- .../rustc_macros/src/diagnostics/utils.rs | 52 ++++++--- .../session-diagnostic/diagnostic-derive.rs | 9 +- .../diagnostic-derive.stderr | 106 +++++++++--------- .../subdiagnostic-derive.rs | 13 ++- .../subdiagnostic-derive.stderr | 28 +++-- 5 files changed, 121 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 99ecaaae0e8c8..ba06f61299f37 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -12,7 +12,7 @@ use syn::{spanned::Spanned, Attribute, Field, Meta, Type, TypeTuple}; use syn::{MetaList, MetaNameValue, NestedMeta, Path}; use synstructure::{BindingInfo, VariantInfo}; -use super::error::invalid_nested_attr; +use super::error::{invalid_attr, invalid_nested_attr}; thread_local! { pub static CODE_IDENT_COUNT: RefCell = RefCell::new(0); @@ -496,6 +496,18 @@ impl FromStr for SuggestionKind { } } +impl fmt::Display for SuggestionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SuggestionKind::Normal => write!(f, "normal"), + SuggestionKind::Short => write!(f, "short"), + SuggestionKind::Hidden => write!(f, "hidden"), + SuggestionKind::Verbose => write!(f, "verbose"), + SuggestionKind::ToolOnly => write!(f, "tool-only"), + } + } +} + impl SuggestionKind { pub fn to_suggestion_style(&self) -> TokenStream { match self { @@ -577,21 +589,24 @@ impl SubdiagnosticKind { let meta = attr.parse_meta()?; - let mut opt_suggestion_kind = None; let mut kind = match name { "label" => SubdiagnosticKind::Label, "note" => SubdiagnosticKind::Note, "help" => SubdiagnosticKind::Help, "warning" => SubdiagnosticKind::Warn, _ => { - // FIXME(#100717): remove #[suggestion_{short,verbose,hidden}] attributes, use - // #[suggestion(style = "...")] instead + // Recover old `#[(multipart_)suggestion_*]` syntaxes + // FIXME(#100717): remove if let Some(suggestion_kind) = name.strip_prefix("suggestion").and_then(SuggestionKind::from_suffix) { if suggestion_kind != SuggestionKind::Normal { - // Plain `#[suggestion]` can have a `style = "..."` attribute later, so don't set it here - opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap()); + invalid_attr(attr, &meta) + .help(format!( + r#"Use `#[suggestion(..., style = "{}")]` instead"#, + suggestion_kind + )) + .emit(); } SubdiagnosticKind::Suggestion { @@ -604,8 +619,12 @@ impl SubdiagnosticKind { name.strip_prefix("multipart_suggestion").and_then(SuggestionKind::from_suffix) { if suggestion_kind != SuggestionKind::Normal { - // Plain `#[multipart_suggestion]` can have a `style = "..."` attribute later, so don't set it here - opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap()); + invalid_attr(attr, &meta) + .help(format!( + r#"Use `#[multipart_suggestion(..., style = "{}")]` instead"#, + suggestion_kind + )) + .emit(); } SubdiagnosticKind::MultipartSuggestion { @@ -649,6 +668,7 @@ impl SubdiagnosticKind { }; let mut code = None; + let mut suggestion_kind = None; let mut nested_iter = nested.into_iter().peekable(); @@ -727,7 +747,7 @@ impl SubdiagnosticKind { SuggestionKind::Normal }); - opt_suggestion_kind.set_once(value, span); + suggestion_kind.set_once(value, span); } // Invalid nested attribute @@ -753,11 +773,11 @@ impl SubdiagnosticKind { SubdiagnosticKind::Suggestion { ref code_field, ref mut code_init, - ref mut suggestion_kind, + suggestion_kind: ref mut kind_field, .. } => { - if let Some(kind) = opt_suggestion_kind.value() { - *suggestion_kind = kind; + if let Some(kind) = suggestion_kind.value() { + *kind_field = kind; } *code_init = if let Some(init) = code.value() { @@ -767,9 +787,11 @@ impl SubdiagnosticKind { quote! { let #code_field = std::iter::empty(); } }; } - SubdiagnosticKind::MultipartSuggestion { ref mut suggestion_kind, .. } => { - if let Some(kind) = opt_suggestion_kind.value() { - *suggestion_kind = kind; + SubdiagnosticKind::MultipartSuggestion { + suggestion_kind: ref mut kind_field, .. + } => { + if let Some(kind) = suggestion_kind.value() { + *kind_field = kind; } } SubdiagnosticKind::Label diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index b998f71e3aa5e..411eb3fba483a 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -211,9 +211,10 @@ struct LabelOnNonSpan { #[diag(compiletest_example, code = "E0123")] struct Suggest { #[suggestion(suggestion, code = "This is the suggested code")] - #[suggestion_short(suggestion, code = "This is the suggested code")] - #[suggestion_hidden(suggestion, code = "This is the suggested code")] - #[suggestion_verbose(suggestion, code = "This is the suggested code")] + #[suggestion(suggestion, code = "This is the suggested code", style = "normal")] + #[suggestion(suggestion, code = "This is the suggested code", style = "short")] + #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")] + #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")] suggestion: (Span, Applicability), } @@ -730,7 +731,7 @@ struct SubdiagnosticEagerCorrect { // after the `span_suggestion` call - which breaks eager translation. #[derive(Subdiagnostic)] -#[suggestion_short(use_instead, applicability = "machine-applicable", code = "{correct}")] +#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")] pub(crate) struct SubdiagnosticWithSuggestion { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 5943ffa6bc2bf..b4c211db47cd9 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -261,13 +261,13 @@ LL | #[label(label)] | ^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:223:5 + --> $DIR/diagnostic-derive.rs:224:5 | LL | #[suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:231:18 + --> $DIR/diagnostic-derive.rs:232:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ @@ -275,13 +275,13 @@ LL | #[suggestion(nonsense = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:231:5 + --> $DIR/diagnostic-derive.rs:232:5 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(msg = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:240:18 + --> $DIR/diagnostic-derive.rs:241:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ @@ -289,13 +289,13 @@ LL | #[suggestion(msg = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:240:5 + --> $DIR/diagnostic-derive.rs:241:5 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:263:5 + --> $DIR/diagnostic-derive.rs:264:5 | LL | / #[suggestion(suggestion, code = "This is suggested code")] LL | | @@ -305,55 +305,55 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: specified multiple times - --> $DIR/diagnostic-derive.rs:279:24 + --> $DIR/diagnostic-derive.rs:280:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:279:18 + --> $DIR/diagnostic-derive.rs:280:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:287:33 + --> $DIR/diagnostic-derive.rs:288:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:287:18 + --> $DIR/diagnostic-derive.rs:288:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:294:5 + --> $DIR/diagnostic-derive.rs:295:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:445:44 + --> $DIR/diagnostic-derive.rs:446:44 | LL | #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:447:24 + --> $DIR/diagnostic-derive.rs:448:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:453:44 + --> $DIR/diagnostic-derive.rs:454:44 | LL | #[suggestion(suggestion, code = "...", applicability = "batman")] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(foo)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:516:20 + --> $DIR/diagnostic-derive.rs:517:20 | LL | #[label(label, foo)] | ^^^ @@ -361,19 +361,19 @@ LL | #[label(label, foo)] = help: a diagnostic slug must be the first argument to the attribute error: `#[label(foo = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:524:20 + --> $DIR/diagnostic-derive.rs:525:20 | LL | #[label(label, foo = "...")] | ^^^^^^^^^^^ error: `#[label(foo(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:532:20 + --> $DIR/diagnostic-derive.rs:533:20 | LL | #[label(label, foo("..."))] | ^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:544:5 + --> $DIR/diagnostic-derive.rs:545:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -381,13 +381,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:564:1 + --> $DIR/diagnostic-derive.rs:565:1 | LL | #[error(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:564:1 + --> $DIR/diagnostic-derive.rs:565:1 | LL | / #[error(compiletest_example, code = "E0123")] LL | | @@ -399,13 +399,13 @@ LL | | struct ErrorAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:571:1 + --> $DIR/diagnostic-derive.rs:572:1 | LL | #[warn_(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:571:1 + --> $DIR/diagnostic-derive.rs:572:1 | LL | / #[warn_(compiletest_example, code = "E0123")] LL | | @@ -417,13 +417,13 @@ LL | | struct WarnAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:578:1 + --> $DIR/diagnostic-derive.rs:579:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:578:1 + --> $DIR/diagnostic-derive.rs:579:1 | LL | / #[lint(compiletest_example, code = "E0123")] LL | | @@ -435,19 +435,19 @@ LL | | struct LintAttributeOnSessionDiag {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:585:1 + --> $DIR/diagnostic-derive.rs:586:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:585:1 + --> $DIR/diagnostic-derive.rs:586:1 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:585:1 + --> $DIR/diagnostic-derive.rs:586:1 | LL | / #[lint(compiletest_example, code = "E0123")] LL | | @@ -460,19 +460,19 @@ LL | | struct LintAttributeOnLintDiag {} = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:595:44 + --> $DIR/diagnostic-derive.rs:596:44 | LL | #[suggestion(suggestion, code = "...", code = ",,,")] | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:595:30 + --> $DIR/diagnostic-derive.rs:596:30 | LL | #[suggestion(suggestion, code = "...", code = ",,,")] | ^^^^^^^^^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:604:24 + --> $DIR/diagnostic-derive.rs:605:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -480,7 +480,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:612:17 + --> $DIR/diagnostic-derive.rs:613:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -488,13 +488,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:619:5 + --> $DIR/diagnostic-derive.rs:620:5 | LL | #[suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:626:1 + --> $DIR/diagnostic-derive.rs:627:1 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -502,7 +502,7 @@ LL | #[multipart_suggestion(suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:629:1 + --> $DIR/diagnostic-derive.rs:630:1 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -510,7 +510,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:633:5 + --> $DIR/diagnostic-derive.rs:634:5 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -518,7 +518,7 @@ LL | #[multipart_suggestion(suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:641:1 + --> $DIR/diagnostic-derive.rs:642:1 | LL | #[suggestion(suggestion, code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -526,7 +526,7 @@ LL | #[suggestion(suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:650:1 + --> $DIR/diagnostic-derive.rs:651:1 | LL | #[label] | ^^^^^^^^ @@ -534,7 +534,7 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(bad)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:684:21 + --> $DIR/diagnostic-derive.rs:685:21 | LL | #[subdiagnostic(bad)] | ^^^ @@ -542,7 +542,7 @@ LL | #[subdiagnostic(bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:692:5 + --> $DIR/diagnostic-derive.rs:693:5 | LL | #[subdiagnostic = "bad"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -550,7 +550,7 @@ LL | #[subdiagnostic = "bad"] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:700:5 + --> $DIR/diagnostic-derive.rs:701:5 | LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -558,7 +558,7 @@ LL | #[subdiagnostic(bad, bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic("...")]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:708:21 + --> $DIR/diagnostic-derive.rs:709:21 | LL | #[subdiagnostic("bad")] | ^^^^^ @@ -566,7 +566,7 @@ LL | #[subdiagnostic("bad")] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:716:5 + --> $DIR/diagnostic-derive.rs:717:5 | LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -574,19 +574,19 @@ LL | #[subdiagnostic(eager)] = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:774:18 + --> $DIR/diagnostic-derive.rs:775:18 | LL | #[suggestion(code())] | ^^^^^^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:782:23 + --> $DIR/diagnostic-derive.rs:783:23 | LL | #[suggestion(code(foo))] | ^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:790:18 + --> $DIR/diagnostic-derive.rs:791:18 | LL | #[suggestion(code = 3)] | ^^^^^^^^ @@ -604,43 +604,43 @@ LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:564:3 + --> $DIR/diagnostic-derive.rs:565:3 | LL | #[error(compiletest_example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:571:3 + --> $DIR/diagnostic-derive.rs:572:3 | LL | #[warn_(compiletest_example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:578:3 + --> $DIR/diagnostic-derive.rs:579:3 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:585:3 + --> $DIR/diagnostic-derive.rs:586:3 | LL | #[lint(compiletest_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:626:3 + --> $DIR/diagnostic-derive.rs:627:3 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:629:3 + --> $DIR/diagnostic-derive.rs:630:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:633:7 + --> $DIR/diagnostic-derive.rs:634:7 | LL | #[multipart_suggestion(suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -652,7 +652,7 @@ LL | #[diag(nonsense, code = "E0123")] | ^^^^^^^^ not found in `rustc_errors::fluent` error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:338:10 + --> $DIR/diagnostic-derive.rs:339:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 7d9e2576cae3c..078ec3baac9fc 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -751,11 +751,18 @@ struct SuggestionStyleTwice { sub: Span, } +#[derive(Subdiagnostic)] +#[suggestion_hidden(parser_add_paren, code = "")] +//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +struct SuggestionStyleOldSyntax { + #[primary_span] + sub: Span, +} + #[derive(Subdiagnostic)] #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] -//~^ ERROR specified multiple times -//~| NOTE previously specified here -struct SuggestionStyleTwiceExplicit { +//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +struct SuggestionStyleOldAndNewSyntax { #[primary_span] sub: Span, } diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index b76b7fdfceac9..8e06c43e6d0ad 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -457,20 +457,24 @@ note: previously specified here LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^ -error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:755:50 +error: `#[suggestion_hidden(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:755:1 | -LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] - | ^^^^^^^^^^^^^^^^ +LL | #[suggestion_hidden(parser_add_paren, code = "")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:755:3 + = help: Use `#[suggestion(..., style = "hidden")]` instead + +error: `#[suggestion_hidden(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:763:1 | LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: Use `#[suggestion(..., style = "hidden")]` instead error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:764:51 + --> $DIR/subdiagnostic-derive.rs:771:51 | LL | #[suggestion(parser_add_paren, code = "", style = "foo")] | ^^^^^ @@ -478,13 +482,13 @@ LL | #[suggestion(parser_add_paren, code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: `#[suggestion(style = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:772:43 + --> $DIR/subdiagnostic-derive.rs:779:43 | LL | #[suggestion(parser_add_paren, code = "", style = 42)] | ^^^^^^^^^^ error: `#[suggestion(style)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:780:43 + --> $DIR/subdiagnostic-derive.rs:787:43 | LL | #[suggestion(parser_add_paren, code = "", style)] | ^^^^^ @@ -492,7 +496,7 @@ LL | #[suggestion(parser_add_paren, code = "", style)] = help: a diagnostic slug must be the first argument to the attribute error: `#[suggestion(style(...))]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:788:43 + --> $DIR/subdiagnostic-derive.rs:795:43 | LL | #[suggestion(parser_add_paren, code = "", style("foo"))] | ^^^^^^^^^^^^ @@ -557,6 +561,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent` LL | #[label(slug)] | ^^^^ not found in `rustc_errors::fluent` -error: aborting due to 78 previous errors +error: aborting due to 79 previous errors For more information about this error, try `rustc --explain E0425`. From 77c67f35713af2f487a136b116ed442df39d7902 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 27 Oct 2022 16:49:59 +0100 Subject: [PATCH 038/482] Use stdio in UWP apps This has been supported since Windows 10.0.16299. See https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-console-l1-1-0dll --- library/std/src/sys/windows/c.rs | 57 ++++++++-------- library/std/src/sys/windows/mod.rs | 4 +- library/std/src/sys/windows/stdio_uwp.rs | 87 ------------------------ 3 files changed, 28 insertions(+), 120 deletions(-) delete mode 100644 library/std/src/sys/windows/stdio_uwp.rs diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index be6fc2ebb7a27..fc2dc42833d07 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -56,6 +56,7 @@ pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION; pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES; pub type LPSTARTUPINFO = *mut STARTUPINFO; pub type LPVOID = *mut c_void; +pub type LPCVOID = *const c_void; pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA; @@ -773,6 +774,16 @@ pub struct timeval { pub tv_usec: c_long, } +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CONSOLE_READCONSOLE_CONTROL { + pub nLength: ULONG, + pub nInitialChars: ULONG, + pub dwCtrlWakeupMask: ULONG, + pub dwControlKeyState: ULONG, +} +pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL; + // Desktop specific functions & types cfg_if::cfg_if! { if #[cfg(not(target_vendor = "uwp"))] { @@ -801,17 +812,6 @@ if #[cfg(not(target_vendor = "uwp"))] { pub type PVECTORED_EXCEPTION_HANDLER = extern "system" fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG; - #[repr(C)] - #[derive(Copy, Clone)] - pub struct CONSOLE_READCONSOLE_CONTROL { - pub nLength: ULONG, - pub nInitialChars: ULONG, - pub dwCtrlWakeupMask: ULONG, - pub dwControlKeyState: ULONG, - } - - pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL; - #[repr(C)] pub struct BY_HANDLE_FILE_INFORMATION { pub dwFileAttributes: DWORD, @@ -827,7 +827,6 @@ if #[cfg(not(target_vendor = "uwp"))] { } pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION; - pub type LPCVOID = *const c_void; pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001; @@ -855,24 +854,6 @@ if #[cfg(not(target_vendor = "uwp"))] { #[link(name = "kernel32")] extern "system" { - // Functions forbidden when targeting UWP - pub fn ReadConsoleW( - hConsoleInput: HANDLE, - lpBuffer: LPVOID, - nNumberOfCharsToRead: DWORD, - lpNumberOfCharsRead: LPDWORD, - pInputControl: PCONSOLE_READCONSOLE_CONTROL, - ) -> BOOL; - - pub fn WriteConsoleW( - hConsoleOutput: HANDLE, - lpBuffer: LPCVOID, - nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: LPDWORD, - lpReserved: LPVOID, - ) -> BOOL; - - pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; // Allowed but unused by UWP pub fn GetFileInformationByHandle( hFile: HANDLE, @@ -914,6 +895,22 @@ if #[cfg(target_vendor = "uwp")] { extern "system" { pub fn GetCurrentProcessId() -> DWORD; + pub fn ReadConsoleW( + hConsoleInput: HANDLE, + lpBuffer: LPVOID, + nNumberOfCharsToRead: DWORD, + lpNumberOfCharsRead: LPDWORD, + pInputControl: PCONSOLE_READCONSOLE_CONTROL, + ) -> BOOL; + pub fn WriteConsoleW( + hConsoleOutput: HANDLE, + lpBuffer: LPCVOID, + nNumberOfCharsToWrite: DWORD, + lpNumberOfCharsWritten: LPDWORD, + lpReserved: LPVOID, + ) -> BOOL; + pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; + pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index eab9b961279c9..e67411e16860e 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -29,6 +29,7 @@ pub mod path; pub mod pipe; pub mod process; pub mod rand; +pub mod stdio; pub mod thread; pub mod thread_local_dtor; pub mod thread_local_key; @@ -36,12 +37,9 @@ pub mod thread_parker; pub mod time; cfg_if::cfg_if! { if #[cfg(not(target_vendor = "uwp"))] { - pub mod stdio; pub mod stack_overflow; } else { - pub mod stdio_uwp; pub mod stack_overflow_uwp; - pub use self::stdio_uwp as stdio; pub use self::stack_overflow_uwp as stack_overflow; } } diff --git a/library/std/src/sys/windows/stdio_uwp.rs b/library/std/src/sys/windows/stdio_uwp.rs deleted file mode 100644 index 32550f796ec64..0000000000000 --- a/library/std/src/sys/windows/stdio_uwp.rs +++ /dev/null @@ -1,87 +0,0 @@ -#![unstable(issue = "none", feature = "windows_stdio")] - -use crate::io; -use crate::mem::ManuallyDrop; -use crate::os::windows::io::FromRawHandle; -use crate::sys::c; -use crate::sys::handle::Handle; - -pub struct Stdin {} -pub struct Stdout; -pub struct Stderr; - -const MAX_BUFFER_SIZE: usize = 8192; -pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3; - -pub fn get_handle(handle_id: c::DWORD) -> io::Result { - let handle = unsafe { c::GetStdHandle(handle_id) }; - if handle == c::INVALID_HANDLE_VALUE { - Err(io::Error::last_os_error()) - } else if handle.is_null() { - Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32)) - } else { - Ok(handle) - } -} - -fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result { - let handle = get_handle(handle_id)?; - // SAFETY: The handle returned from `get_handle` must be valid and non-null. - let handle = unsafe { Handle::from_raw_handle(handle) }; - ManuallyDrop::new(handle).write(data) -} - -impl Stdin { - pub const fn new() -> Stdin { - Stdin {} - } -} - -impl io::Read for Stdin { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let handle = get_handle(c::STD_INPUT_HANDLE)?; - // SAFETY: The handle returned from `get_handle` must be valid and non-null. - let handle = unsafe { Handle::from_raw_handle(handle) }; - ManuallyDrop::new(handle).read(buf) - } -} - -impl Stdout { - pub const fn new() -> Stdout { - Stdout - } -} - -impl io::Write for Stdout { - fn write(&mut self, buf: &[u8]) -> io::Result { - write(c::STD_OUTPUT_HANDLE, buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result { - write(c::STD_ERROR_HANDLE, buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32) -} - -pub fn panic_output() -> Option { - Some(Stderr::new()) -} From bfa4e581fb5b77ca4e3eba7119bc2b1e6214582d Mon Sep 17 00:00:00 2001 From: Julien Cretin Date: Thu, 27 Oct 2022 18:08:30 +0200 Subject: [PATCH 039/482] Add `multivalue` target feature to WASM target --- compiler/rustc_codegen_ssa/src/target_features.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 83407ee8f9d32..a4368303de576 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -267,6 +267,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[ // tidy-alphabetical-start ("atomics", Some(sym::wasm_target_feature)), ("bulk-memory", Some(sym::wasm_target_feature)), + ("multivalue", Some(sym::wasm_target_feature)), ("mutable-globals", Some(sym::wasm_target_feature)), ("nontrapping-fptoint", Some(sym::wasm_target_feature)), ("reference-types", Some(sym::wasm_target_feature)), From 521472443ff1bc95a426e51eb9d00ca2de366f9e Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Sun, 30 Oct 2022 17:17:25 -0700 Subject: [PATCH 040/482] Detect unused files in `src/test/mir-opt` and error on them in tidy. --- Cargo.lock | 9 ++ Cargo.toml | 1 + src/bootstrap/builder.rs | 1 + src/bootstrap/check.rs | 1 + ...c.try_identity.DestinationPropagation.diff | 72 ---------- ...y.try_identity.DestinationPropagation.diff | 106 -------------- ..._try.try_identity.SimplifyArmIdentity.diff | 85 ------------ ....try_identity.SimplifyBranchSame.after.mir | 83 ----------- ..._try.try_identity.SimplifyLocals.after.mir | 58 -------- src/tools/compiletest/Cargo.toml | 1 + src/tools/compiletest/src/runtest.rs | 130 +++++------------- src/tools/miropt-test-tools/Cargo.toml | 7 + src/tools/miropt-test-tools/src/lib.rs | 70 ++++++++++ src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 1 + src/tools/tidy/src/mir_opt_tests.rs | 37 +++++ 17 files changed, 168 insertions(+), 496 deletions(-) delete mode 100644 src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff delete mode 100644 src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir create mode 100644 src/tools/miropt-test-tools/Cargo.toml create mode 100644 src/tools/miropt-test-tools/src/lib.rs create mode 100644 src/tools/tidy/src/mir_opt_tests.rs diff --git a/Cargo.lock b/Cargo.lock index dab693419a95d..301167e02cc5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -816,6 +816,7 @@ dependencies = [ "lazycell", "libc", "miow", + "miropt-test-tools", "regex", "rustfix", "serde", @@ -2268,6 +2269,13 @@ dependencies = [ "ui_test", ] +[[package]] +name = "miropt-test-tools" +version = "0.1.0" +dependencies = [ + "regex", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -4920,6 +4928,7 @@ version = "0.1.0" dependencies = [ "cargo_metadata 0.14.0", "lazy_static", + "miropt-test-tools", "regex", "walkdir", ] diff --git a/Cargo.toml b/Cargo.toml index e49fe5e2f6356..13a98eedde867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "src/tools/error_index_generator", "src/tools/linkchecker", "src/tools/lint-docs", + "src/tools/miropt-test-tools", "src/tools/rustbook", "src/tools/unstable-book-gen", "src/tools/tidy", diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c8285c85d0358..6de3746363337 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -622,6 +622,7 @@ impl<'a> Builder<'a> { check::Clippy, check::Miri, check::CargoMiri, + check::MiroptTestTools, check::Rls, check::RustAnalyzer, check::Rustfmt, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 4450dd7e80f95..2e1bd8d6d1f6d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -460,6 +460,7 @@ tool_check_step!(Miri, "src/tools/miri", SourceType::InTree); tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree); tool_check_step!(Rls, "src/tools/rls", SourceType::InTree); tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree); +tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree); tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false); diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff deleted file mode 100644 index c3e503bf2c686..0000000000000 --- a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `try_identity` before DestinationPropagation -+ // MIR for `try_identity` after DestinationPropagation - - fn try_identity(_1: std::result::Result) -> std::result::Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57 - let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10 - let mut _3: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 - let mut _4: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14 - let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 - let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9 - scope 1 { - debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10 - } - scope 2 { - debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15 - scope 3 { - scope 7 { - debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL - } - scope 8 { - debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL - let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15 - } - } - } - scope 4 { - debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15 - scope 5 { - } - } - scope 6 { -- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -+ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10 -- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 -- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -+ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -+ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -+ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -+ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - } - - bb1: { -- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 -- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 -+ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2 - goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 - } - - bb2: { - return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 - } - } - diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff deleted file mode 100644 index 83b91309be308..0000000000000 --- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff +++ /dev/null @@ -1,106 +0,0 @@ -- // MIR for `try_identity` before DestinationPropagation -+ // MIR for `try_identity` after DestinationPropagation - - fn try_identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 - let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 - let mut _3: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - let mut _4: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 - let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 - let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 - let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 - let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 - scope 1 { -- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 -+ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 - } - scope 2 { - debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 - scope 5 (inlined >::from) { // at $DIR/simplify_try.rs:22:37: 22:50 - debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::) { // at $DIR/simplify_try.rs:22:26: 22:51 - debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22 - } - } - scope 3 { -- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 -+ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::) { // at $DIR/simplify_try.rs:21:19: 21:33 -- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23 -+ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23 - } - - bb0: { -- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 -- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 -- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 -- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 -- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6 -- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 -+ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 -+ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 -+ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 -+ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 -+ nop; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6 -+ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 - _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 - } - - bb1: { -- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 -- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 -- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 -- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 -- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 -- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 -- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 -+ nop; // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 -+ ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 -+ nop; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 -+ nop; // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 -+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 -+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 -+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 - Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 -- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 -+ nop; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 -- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 -- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 -+ nop; // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 -+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 - StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 - nop; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10 - Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 -- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 -- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 -+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 -+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - } - diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff deleted file mode 100644 index e025ae7c55111..0000000000000 --- a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff +++ /dev/null @@ -1,85 +0,0 @@ -- // MIR for `try_identity` before SimplifyArmIdentity -+ // MIR for `try_identity` after SimplifyArmIdentity - - fn try_identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 - let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 - let mut _3: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - let mut _4: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 - let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 - let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 - let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 - let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 - scope 1 { - debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 - } - scope 2 { - debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 - scope 5 (inlined >::from) { // at $DIR/simplify_try.rs:22:37: 22:50 - debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::) { // at $DIR/simplify_try.rs:22:26: 22:51 - debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22 - } - } - scope 3 { - debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::) { // at $DIR/simplify_try.rs:21:19: 21:33 - debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6 - StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 - _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 - } - - bb1: { - StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 - StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 - StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 - StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 - _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 - Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 - StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 - ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10 - Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - } - diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir deleted file mode 100644 index eb5af2227ec9b..0000000000000 --- a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir +++ /dev/null @@ -1,83 +0,0 @@ -// MIR for `try_identity` after SimplifyBranchSame - -fn try_identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 - let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 - let mut _3: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - let mut _4: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 - let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 - let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 - let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 - let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 - scope 1 { - debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 - } - scope 2 { - debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 - scope 5 (inlined >::from) { // at $DIR/simplify_try.rs:22:37: 22:50 - debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::) { // at $DIR/simplify_try.rs:22:26: 22:51 - debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22 - } - } - scope 3 { - debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::) { // at $DIR/simplify_try.rs:21:19: 21:33 - debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6 - StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 - _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 - } - - bb1: { - StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 - StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 - StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 - StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 - _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 - Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 - StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 - ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10 - Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } -} diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir deleted file mode 100644 index 1efa8a67e5cd1..0000000000000 --- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir +++ /dev/null @@ -1,58 +0,0 @@ -// MIR for `try_identity` after SimplifyLocals - -fn try_identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 - let mut _2: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - let mut _3: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 - let _4: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - let mut _5: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 - let mut _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 - scope 1 { - debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 - } - scope 2 { - debug e => _4; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 - scope 5 (inlined >::from) { // at $DIR/simplify_try.rs:22:37: 22:50 - debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::) { // at $DIR/simplify_try.rs:22:26: 22:51 - debug e => _5; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22 - } - } - scope 3 { - debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::) { // at $DIR/simplify_try.rs:21:19: 21:33 - debug r => _2; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23 - } - - bb0: { - _2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 - _3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 - } - - bb1: { - ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 - Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 - StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 - StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 - StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 - Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11 - StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 - StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 - return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 - } -} diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 41f97e4326a90..1911f0f9c941c 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -8,6 +8,7 @@ colored = "2" diff = "0.1.10" unified-diff = "0.2.1" getopts = "0.2" +miropt-test-tools = { path = "../miropt-test-tools" } tracing = "0.1" tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } regex = "1.0" diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f8903f754f09f..dee144052874f 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3378,103 +3378,49 @@ impl<'test> TestCx<'test> { } } - for l in test_file_contents.lines() { - if l.starts_with("// EMIT_MIR ") { - let test_name = l.trim_start_matches("// EMIT_MIR ").trim(); - let mut test_names = test_name.split(' '); - // sometimes we specify two files so that we get a diff between the two files - let test_name = test_names.next().unwrap(); - let mut expected_file; - let from_file; - let to_file; - - if test_name.ends_with(".diff") { - let trimmed = test_name.trim_end_matches(".diff"); - let test_against = format!("{}.after.mir", trimmed); - from_file = format!("{}.before.mir", trimmed); - expected_file = format!("{}{}.diff", trimmed, bit_width); - assert!( - test_names.next().is_none(), - "two mir pass names specified for MIR diff" - ); - to_file = Some(test_against); - } else if let Some(first_pass) = test_names.next() { - let second_pass = test_names.next().unwrap(); - assert!( - test_names.next().is_none(), - "three mir pass names specified for MIR diff" - ); - expected_file = - format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); - let second_file = format!("{}.{}.mir", test_name, second_pass); - from_file = format!("{}.{}.mir", test_name, first_pass); - to_file = Some(second_file); - } else { - let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap(); - let cap = ext_re - .captures_iter(test_name) - .next() - .expect("test_name has an invalid extension"); - let extension = cap.get(1).unwrap().as_str(); - expected_file = format!( - "{}{}{}", - test_name.trim_end_matches(extension), - bit_width, - extension, - ); - from_file = test_name.to_string(); - assert!( - test_names.next().is_none(), - "two mir pass names specified for MIR dump" + let files = miropt_test_tools::files_for_miropt_test( + &self.testpaths.file, + self.config.get_pointer_width(), + ); + + for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files { + let dumped_string = if let Some(after) = to_file { + self.diff_mir_files(from_file.into(), after.into()) + } else { + let mut output_file = PathBuf::new(); + output_file.push(self.get_mir_dump_dir()); + output_file.push(&from_file); + debug!( + "comparing the contents of: {} with {}", + output_file.display(), + expected_file.display() + ); + if !output_file.exists() { + panic!( + "Output file `{}` from test does not exist, available files are in `{}`", + output_file.display(), + output_file.parent().unwrap().display() ); - to_file = None; - }; - if !expected_file.starts_with(&test_crate) { - expected_file = format!("{}.{}", test_crate, expected_file); } - let expected_file = test_dir.join(expected_file); + self.check_mir_test_timestamp(&from_file, &output_file); + let dumped_string = fs::read_to_string(&output_file).unwrap(); + self.normalize_output(&dumped_string, &[]) + }; - let dumped_string = if let Some(after) = to_file { - self.diff_mir_files(from_file.into(), after.into()) - } else { - let mut output_file = PathBuf::new(); - output_file.push(self.get_mir_dump_dir()); - output_file.push(&from_file); - debug!( - "comparing the contents of: {} with {}", - output_file.display(), + if self.config.bless { + let _ = std::fs::remove_file(&expected_file); + std::fs::write(expected_file, dumped_string.as_bytes()).unwrap(); + } else { + if !expected_file.exists() { + panic!("Output file `{}` from test does not exist", expected_file.display()); + } + let expected_string = fs::read_to_string(&expected_file).unwrap(); + if dumped_string != expected_string { + print!("{}", write_diff(&expected_string, &dumped_string, 3)); + panic!( + "Actual MIR output differs from expected MIR output {}", expected_file.display() ); - if !output_file.exists() { - panic!( - "Output file `{}` from test does not exist, available files are in `{}`", - output_file.display(), - output_file.parent().unwrap().display() - ); - } - self.check_mir_test_timestamp(&from_file, &output_file); - let dumped_string = fs::read_to_string(&output_file).unwrap(); - self.normalize_output(&dumped_string, &[]) - }; - - if self.config.bless { - let _ = std::fs::remove_file(&expected_file); - std::fs::write(expected_file, dumped_string.as_bytes()).unwrap(); - } else { - if !expected_file.exists() { - panic!( - "Output file `{}` from test does not exist", - expected_file.display() - ); - } - let expected_string = fs::read_to_string(&expected_file).unwrap(); - if dumped_string != expected_string { - print!("{}", write_diff(&expected_string, &dumped_string, 3)); - panic!( - "Actual MIR output differs from expected MIR output {}", - expected_file.display() - ); - } } } } diff --git a/src/tools/miropt-test-tools/Cargo.toml b/src/tools/miropt-test-tools/Cargo.toml new file mode 100644 index 0000000000000..8589a44cf1bab --- /dev/null +++ b/src/tools/miropt-test-tools/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "miropt-test-tools" +version = "0.1.0" +edition = "2021" + +[dependencies] +regex = "1.0" diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs new file mode 100644 index 0000000000000..96819d3547b29 --- /dev/null +++ b/src/tools/miropt-test-tools/src/lib.rs @@ -0,0 +1,70 @@ +use std::fs; + +pub struct MiroptTestFiles { + pub expected_file: std::path::PathBuf, + pub from_file: String, + pub to_file: Option, +} + +pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec { + let mut out = Vec::new(); + let test_file_contents = fs::read_to_string(&testfile).unwrap(); + + let test_dir = testfile.parent().unwrap(); + let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_"); + + let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") { + format!(".{}bit", bit_width) + } else { + String::new() + }; + + for l in test_file_contents.lines() { + if l.starts_with("// EMIT_MIR ") { + let test_name = l.trim_start_matches("// EMIT_MIR ").trim(); + let mut test_names = test_name.split(' '); + // sometimes we specify two files so that we get a diff between the two files + let test_name = test_names.next().unwrap(); + let mut expected_file; + let from_file; + let to_file; + + if test_name.ends_with(".diff") { + let trimmed = test_name.trim_end_matches(".diff"); + let test_against = format!("{}.after.mir", trimmed); + from_file = format!("{}.before.mir", trimmed); + expected_file = format!("{}{}.diff", trimmed, bit_width); + assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff"); + to_file = Some(test_against); + } else if let Some(first_pass) = test_names.next() { + let second_pass = test_names.next().unwrap(); + assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff"); + expected_file = + format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); + let second_file = format!("{}.{}.mir", test_name, second_pass); + from_file = format!("{}.{}.mir", test_name, first_pass); + to_file = Some(second_file); + } else { + let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap(); + let cap = ext_re + .captures_iter(test_name) + .next() + .expect("test_name has an invalid extension"); + let extension = cap.get(1).unwrap().as_str(); + expected_file = + format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,); + from_file = test_name.to_string(); + assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump"); + to_file = None; + }; + if !expected_file.starts_with(&test_crate) { + expected_file = format!("{}.{}", test_crate, expected_file); + } + let expected_file = test_dir.join(expected_file); + + out.push(MiroptTestFiles { expected_file, from_file, to_file }); + } + } + + out +} diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 471d78a2922a0..774c97b7777d2 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -7,6 +7,7 @@ autobins = false [dependencies] cargo_metadata = "0.14" regex = "1" +miropt-test-tools = { path = "../miropt-test-tools" } lazy_static = "1" walkdir = "2" diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index fc0bce5857233..698e4850bea9b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -47,6 +47,7 @@ pub mod error_codes_check; pub mod errors; pub mod extdeps; pub mod features; +pub mod mir_opt_tests; pub mod pal; pub mod primitive_docs; pub mod style; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index ca785042aaa6a..ee883777c31d9 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -64,6 +64,7 @@ fn main() { // Checks over tests. check!(debug_artifacts, &src_path); check!(ui_tests, &src_path); + check!(mir_opt_tests, &src_path); // Checks that only make sense for the compiler. check!(errors, &compiler_path); diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs new file mode 100644 index 0000000000000..f9e8b55497b58 --- /dev/null +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -0,0 +1,37 @@ +//! Tidy check to ensure that mir opt directories do not have stale files. + +use std::collections::HashSet; +use std::path::{Path, PathBuf}; + +pub fn check(path: &Path, bad: &mut bool) { + let mut rs_files = Vec::::new(); + let mut output_files = HashSet::::new(); + let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter(); + + for file in files.filter_map(Result::ok).filter(|e| e.file_type().is_file()) { + let filepath = file.path(); + if filepath.extension() == Some("rs".as_ref()) { + rs_files.push(filepath.to_owned()); + } else { + output_files.insert(filepath.to_owned()); + } + } + + for file in rs_files { + for bw in [32, 64] { + for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) { + output_files.remove(&output_file.expected_file); + } + } + } + + for extra in output_files { + if extra.file_name() != Some("README.md".as_ref()) { + tidy_error!( + bad, + "the following output file is not associated with any mir-opt test, you can remove it: {}", + extra.display() + ); + } + } +} From df6cb501d933719e323e02a81dcdf862ddaf0f14 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Nov 2022 15:48:13 +0100 Subject: [PATCH 041/482] Migrate sidebar-links-color GUI test to functions --- src/test/rustdoc-gui/sidebar-links-color.goml | 386 ++++++++---------- 1 file changed, 162 insertions(+), 224 deletions(-) diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml index 18a1a3fadea55..7ef7ec90cd269 100644 --- a/src/test/rustdoc-gui/sidebar-links-color.goml +++ b/src/test/rustdoc-gui/sidebar-links-color.goml @@ -4,230 +4,168 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // This is needed so that the text color is computed. show-text: true -// Ayu theme -local-storage: { - "rustdoc-theme": "ayu", - "rustdoc-use-system-theme": "false", -} -reload: - -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) - -// Dark theme -local-storage: {"rustdoc-theme": "dark"} -reload: - -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +define-function: ( + "check-colors", + ( + theme, struct, struct_hover, struct_hover_background, enum, enum_hover, + enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover, + trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover, + type_hover_background, keyword, keyword_hover, keyword_hover_background, + ), + [ + ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }), + ("reload"), + // Struct + ("assert-css", ( + ".sidebar .block.struct a:not(.current)", + {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.struct a:not(.current)"), + ("assert-css", ( + ".sidebar .block.struct a:hover", + {"color": |struct_hover|, "background-color": |struct_hover_background|}, + )), + // Enum + ("assert-css", ( + ".sidebar .block.enum a", + {"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.enum a"), + ("assert-css", ( + ".sidebar .block.enum a:hover", + {"color": |enum_hover|, "background-color": |enum_hover_background|}, + )), + // Union + ("assert-css", ( + ".sidebar .block.union a", + {"color": |union|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.union a"), + ("assert-css", ( + ".sidebar .block.union a:hover", + {"color": |union_hover|, "background-color": |union_hover_background|}, + )), + // Trait + ("assert-css", ( + ".sidebar .block.trait a", + {"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.trait a"), + ("assert-css", ( + ".sidebar .block.trait a:hover", + {"color": |trait_hover|, "background-color": |trait_hover_background|}, + )), + // Function + ("assert-css", ( + ".sidebar .block.fn a", + {"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.fn a"), + ("assert-css", ( + ".sidebar .block.fn a:hover", + {"color": |fn_hover|, "background-color": |fn_hover_background|}, + )), + // Type definition + ("assert-css", ( + ".sidebar .block.type a", + {"color": |type|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.type a"), + ("assert-css", ( + ".sidebar .block.type a:hover", + {"color": |type_hover|, "background-color": |type_hover_background|}, + )), + // Keyword + ("assert-css", ( + ".sidebar .block.keyword a", + {"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.keyword a"), + ("assert-css", ( + ".sidebar .block.keyword a:hover", + {"color": |keyword_hover|, "background-color": |keyword_hover_background|}, + )), + ] ) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) - -// Light theme -local-storage: {"rustdoc-theme": "light"} -reload: -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +call-function: ( + "check-colors", + { + "theme": "ayu", + "struct": "rgb(83, 177, 219)", + "struct_hover": "rgb(255, 180, 76)", + "struct_hover_background": "rgba(0, 0, 0, 0)", + "enum": "rgb(83, 177, 219)", + "enum_hover": "rgb(255, 180, 76)", + "enum_hover_background": "rgba(0, 0, 0, 0)", + "union": "rgb(83, 177, 219)", + "union_hover": "rgb(255, 180, 76)", + "union_hover_background": "rgba(0, 0, 0, 0)", + "trait": "rgb(83, 177, 219)", + "trait_hover": "rgb(255, 180, 76)", + "trait_hover_background": "rgba(0, 0, 0, 0)", + "fn": "rgb(83, 177, 219)", + "fn_hover": "rgb(255, 180, 76)", + "fn_hover_background": "rgba(0, 0, 0, 0)", + "type": "rgb(83, 177, 219)", + "type_hover": "rgb(255, 180, 76)", + "type_hover_background": "rgba(0, 0, 0, 0)", + "keyword": "rgb(83, 177, 219)", + "keyword_hover": "rgb(255, 180, 76)", + "keyword_hover_background": "rgba(0, 0, 0, 0)", + } +) +call-function: ( + "check-colors", + { + "theme": "dark", + "struct": "rgb(253, 191, 53)", + "struct_hover": "rgb(253, 191, 53)", + "struct_hover_background": "rgb(68, 68, 68)", + "enum": "rgb(253, 191, 53)", + "enum_hover": "rgb(253, 191, 53)", + "enum_hover_background": "rgb(68, 68, 68)", + "union": "rgb(253, 191, 53)", + "union_hover": "rgb(253, 191, 53)", + "union_hover_background": "rgb(68, 68, 68)", + "trait": "rgb(253, 191, 53)", + "trait_hover": "rgb(253, 191, 53)", + "trait_hover_background": "rgb(68, 68, 68)", + "fn": "rgb(253, 191, 53)", + "fn_hover": "rgb(253, 191, 53)", + "fn_hover_background": "rgb(68, 68, 68)", + "type": "rgb(253, 191, 53)", + "type_hover": "rgb(253, 191, 53)", + "type_hover_background": "rgb(68, 68, 68)", + "keyword": "rgb(253, 191, 53)", + "keyword_hover": "rgb(253, 191, 53)", + "keyword_hover_background": "rgb(68, 68, 68)", + } +) +call-function: ( + "check-colors", + { + "theme": "light", + "struct": "rgb(53, 109, 164)", + "struct_hover": "rgb(53, 109, 164)", + "struct_hover_background": "rgb(255, 255, 255)", + "enum": "rgb(53, 109, 164)", + "enum_hover": "rgb(53, 109, 164)", + "enum_hover_background": "rgb(255, 255, 255)", + "union": "rgb(53, 109, 164)", + "union_hover": "rgb(53, 109, 164)", + "union_hover_background": "rgb(255, 255, 255)", + "trait": "rgb(53, 109, 164)", + "trait_hover": "rgb(53, 109, 164)", + "trait_hover_background": "rgb(255, 255, 255)", + "fn": "rgb(53, 109, 164)", + "fn_hover": "rgb(53, 109, 164)", + "fn_hover_background": "rgb(255, 255, 255)", + "type": "rgb(53, 109, 164)", + "type_hover": "rgb(53, 109, 164)", + "type_hover_background": "rgb(255, 255, 255)", + "keyword": "rgb(53, 109, 164)", + "keyword_hover": "rgb(53, 109, 164)", + "keyword_hover_background": "rgb(255, 255, 255)", + } ) From 6b3dfb08d98d25128ff3c43ccf7cb9e7b52732e3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Nov 2022 19:47:12 +0100 Subject: [PATCH 042/482] Remove unneeded "rustdoc-preferred-dark-theme" setting --- src/test/rustdoc-gui/theme-in-history.goml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml index c29571728a1a2..10508e86a36e1 100644 --- a/src/test/rustdoc-gui/theme-in-history.goml +++ b/src/test/rustdoc-gui/theme-in-history.goml @@ -3,7 +3,6 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" // Set the theme to dark. local-storage: { "rustdoc-theme": "dark", - "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false", } // We reload the page so the local storage settings are being used. From 1ba4796d80fd172f3f1c8b4e3be0312b10309dd9 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 1 Nov 2022 16:24:01 +0100 Subject: [PATCH 043/482] Print valid `--print` requests if request is invalid When someone makes a typo, it can be useful to see the valid options. This is also useful if someone wants to find out about all the options. --- compiler/rustc_session/src/config.rs | 61 ++++++++++++------- .../run-make/valid-print-requests/Makefile | 4 ++ .../valid-print-requests.stderr | 2 + 3 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 src/test/run-make/valid-print-requests/Makefile create mode 100644 src/test/run-make/valid-print-requests/valid-print-requests.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 856ff3d415081..bd1f85a9d0693 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1789,34 +1789,49 @@ fn collect_print_requests( cg.target_feature = String::new(); } - prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s { - "crate-name" => PrintRequest::CrateName, - "file-names" => PrintRequest::FileNames, - "sysroot" => PrintRequest::Sysroot, - "target-libdir" => PrintRequest::TargetLibdir, - "cfg" => PrintRequest::Cfg, - "calling-conventions" => PrintRequest::CallingConventions, - "target-list" => PrintRequest::TargetList, - "target-cpus" => PrintRequest::TargetCPUs, - "target-features" => PrintRequest::TargetFeatures, - "relocation-models" => PrintRequest::RelocationModels, - "code-models" => PrintRequest::CodeModels, - "tls-models" => PrintRequest::TlsModels, - "native-static-libs" => PrintRequest::NativeStaticLibs, - "stack-protector-strategies" => PrintRequest::StackProtectorStrategies, - "target-spec-json" => { - if unstable_opts.unstable_options { - PrintRequest::TargetSpec - } else { + const PRINT_REQUESTS: &[(&str, PrintRequest)] = &[ + ("crate-name", PrintRequest::CrateName), + ("file-names", PrintRequest::FileNames), + ("sysroot", PrintRequest::Sysroot), + ("target-libdir", PrintRequest::TargetLibdir), + ("cfg", PrintRequest::Cfg), + ("calling-conventions", PrintRequest::CallingConventions), + ("target-list", PrintRequest::TargetList), + ("target-cpus", PrintRequest::TargetCPUs), + ("target-features", PrintRequest::TargetFeatures), + ("relocation-models", PrintRequest::RelocationModels), + ("code-models", PrintRequest::CodeModels), + ("tls-models", PrintRequest::TlsModels), + ("native-static-libs", PrintRequest::NativeStaticLibs), + ("stack-protector-strategies", PrintRequest::StackProtectorStrategies), + ("target-spec-json", PrintRequest::TargetSpec), + ("link-args", PrintRequest::LinkArgs), + ]; + + prints.extend(matches.opt_strs("print").into_iter().map(|req| { + match PRINT_REQUESTS.iter().find(|&&(name, _)| name == req) { + Some((_, PrintRequest::TargetSpec)) => { + if unstable_opts.unstable_options { + PrintRequest::TargetSpec + } else { + early_error( + error_format, + "the `-Z unstable-options` flag must also be passed to \ + enable the target-spec-json print option", + ); + } + } + Some(&(_, print_request)) => print_request, + None => { + let prints = + PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::>(); + let prints = prints.join(", "); early_error( error_format, - "the `-Z unstable-options` flag must also be passed to \ - enable the target-spec-json print option", + &format!("unknown print request `{req}`. Valid print requests are: {prints}"), ); } } - "link-args" => PrintRequest::LinkArgs, - req => early_error(error_format, &format!("unknown print request `{req}`")), })); prints diff --git a/src/test/run-make/valid-print-requests/Makefile b/src/test/run-make/valid-print-requests/Makefile new file mode 100644 index 0000000000000..c325e536e7c5d --- /dev/null +++ b/src/test/run-make/valid-print-requests/Makefile @@ -0,0 +1,4 @@ +include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) --print uwu 2>&1 | diff - valid-print-requests.stderr diff --git a/src/test/run-make/valid-print-requests/valid-print-requests.stderr b/src/test/run-make/valid-print-requests/valid-print-requests.stderr new file mode 100644 index 0000000000000..85782866d125a --- /dev/null +++ b/src/test/run-make/valid-print-requests/valid-print-requests.stderr @@ -0,0 +1,2 @@ +error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args` + From 70e051dc744495b9dd7e617031ef43efe48f7270 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 27 Oct 2022 21:41:54 +0400 Subject: [PATCH 044/482] rustdoc: Do not add external traits to the crate in `register_res` It's not clear why it was done, and apparently it's no longer necessary now. Such additions are unpredictable for early doc link resolution and would force us to collect all doc links from all external traits. --- src/librustdoc/clean/utils.rs | 4 ---- src/test/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs | 4 ++++ src/test/rustdoc/intra-doc/issue-103463.rs | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs create mode 100644 src/test/rustdoc/intra-doc/issue-103463.rs diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8f3e29a31a072..518e320235ff1 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -7,7 +7,6 @@ use crate::clean::{ PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility, }; use crate::core::DocContext; -use crate::formats::item_type::ItemType; use rustc_ast as ast; use rustc_ast::tokenstream::TokenTree; @@ -503,9 +502,6 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { return did; } inline::record_extern_fqn(cx, did, kind); - if let ItemType::Trait = kind { - inline::record_extern_trait(cx, did); - } did } diff --git a/src/test/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs b/src/test/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs new file mode 100644 index 0000000000000..2b8fdec1f128f --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs @@ -0,0 +1,4 @@ +pub trait Trait { + /// [`u8::clone`] + fn method(); +} diff --git a/src/test/rustdoc/intra-doc/issue-103463.rs b/src/test/rustdoc/intra-doc/issue-103463.rs new file mode 100644 index 0000000000000..4adf8a9a8a4a3 --- /dev/null +++ b/src/test/rustdoc/intra-doc/issue-103463.rs @@ -0,0 +1,8 @@ +// The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved. + +// aux-build:issue-103463-aux.rs + +extern crate issue_103463_aux; +use issue_103463_aux::Trait; + +fn main() {} From 26114e0c5581415942e39f7726a3c332ca44147c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Oct 2022 16:15:37 +0200 Subject: [PATCH 045/482] Make rustdoc Item::visibility computed on-demand --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 29 ++----- src/librustdoc/clean/mod.rs | 64 +++------------- src/librustdoc/clean/types.rs | 84 ++++++++++++++++----- src/librustdoc/html/render/mod.rs | 12 +-- src/librustdoc/html/render/print_item.rs | 66 ++++++++-------- src/librustdoc/json/conversions.rs | 3 +- src/librustdoc/passes/strip_priv_imports.rs | 4 +- src/librustdoc/passes/strip_private.rs | 4 +- src/librustdoc/passes/stripper.rs | 19 +++-- 11 files changed, 144 insertions(+), 145 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 764a6d3aa48cf..00bdbe41ee419 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -118,7 +118,6 @@ where Some(Item { name: None, attrs: Default::default(), - visibility: Inherited, item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, kind: Box::new(ImplItem(Box::new(Impl { unsafety: hir::Unsafety::Normal, @@ -130,6 +129,7 @@ where kind: ImplKind::Auto, }))), cfg: None, + inline_stmt_id: None, }) } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f82fb498131eb..d80637055829d 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -97,7 +97,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { impls.push(Item { name: None, attrs: Default::default(), - visibility: Inherited, item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, kind: Box::new(ImplItem(Box::new(Impl { unsafety: hir::Unsafety::Normal, @@ -128,6 +127,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { ))), }))), cfg: None, + inline_stmt_id: None, }); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d93f0bd4e5657..ec93eefb7d1ee 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -20,7 +20,7 @@ use crate::clean::{ self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt, - ImplKind, ItemId, Type, Visibility, + ImplKind, ItemId, Type, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -152,18 +152,10 @@ pub(crate) fn try_inline( let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs); cx.inlined.insert(did.into()); - let mut item = clean::Item::from_def_id_and_attrs_and_parts( - did, - Some(name), - kind, - Box::new(attrs), - cx, - cfg, - ); - if let Some(import_def_id) = import_def_id { - // The visibility needs to reflect the one from the reexport and not from the "source" DefId. - item.visibility = clean_visibility(cx.tcx.visibility(import_def_id)); - } + let mut item = + clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg); + // The visibility needs to reflect the one from the reexport and not from the "source" DefId. + item.inline_stmt_id = import_def_id; ret.push(item); Some(ret) } @@ -239,13 +231,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean .tcx .associated_items(did) .in_definition_order() - .map(|item| { - // When building an external trait, the cleaned trait will have all items public, - // which causes methods to have a `pub` prefix, which is invalid since items in traits - // can not have a visibility prefix. Thus we override the visibility here manually. - // See https://github.com/rust-lang/rust/issues/81274 - clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) } - }) + .map(|item| clean_middle_assoc_item(item, cx)) .collect(); let predicates = cx.tcx.predicates_of(did); @@ -559,7 +545,6 @@ pub(crate) fn build_impl( }, })), Box::new(merged_attrs), - cx, cfg, )); } @@ -607,7 +592,6 @@ fn build_module_items( name: None, attrs: Box::new(clean::Attributes::default()), item_id: ItemId::Primitive(prim_ty, did.krate), - visibility: clean::Public, kind: Box::new(clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { @@ -626,6 +610,7 @@ fn build_module_items( true, ))), cfg: None, + inline_stmt_id: None, }); } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) { items.extend(i) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8a0e6a82126bc..1ce0d1e4ffd02 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1083,10 +1083,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext TyAssocTypeItem(Box::new(generics), bounds) } }; - let what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx); - // Trait items always inherit the trait's visibility -- we don't want to show `pub`. - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) }) } @@ -1117,18 +1114,7 @@ pub(crate) fn clean_impl_item<'tcx>( } }; - let mut what_rustc_thinks = - Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx); - - let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.owner_id.def_id)); - - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - if impl_ref.is_some() { - what_rustc_thinks.visibility = Inherited; - } - - what_rustc_thinks + Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx) }) } @@ -1340,18 +1326,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } }; - let mut what_rustc_thinks = - Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx); - - let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)); - - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - if impl_ref.is_some() { - what_rustc_thinks.visibility = Visibility::Inherited; - } - - what_rustc_thinks + Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx) } fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { @@ -1821,23 +1796,7 @@ pub(crate) fn clean_field_with_def_id( ty: Type, cx: &mut DocContext<'_>, ) -> Item { - let what_rustc_thinks = - Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx); - if is_field_vis_inherited(cx.tcx, def_id) { - // Variant fields inherit their enum's visibility. - Item { visibility: Visibility::Inherited, ..what_rustc_thinks } - } else { - what_rustc_thinks - } -} - -fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let parent = tcx.parent(def_id); - match tcx.def_kind(parent) { - DefKind::Struct | DefKind::Union => false, - DefKind::Variant => true, - parent_kind => panic!("unexpected parent kind: {:?}", parent_kind), - } + Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx) } pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { @@ -1861,10 +1820,7 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; - let what_rustc_thinks = - Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx); - // don't show `pub` for variants, which always inherit visibility - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx) } fn clean_variant_data<'tcx>( @@ -2038,10 +1994,7 @@ fn clean_maybe_renamed_item<'tcx>( fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item { let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx)); - let what_rustc_thinks = - Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx); - // don't show `pub` for variants, which are always public - Item { visibility: Inherited, ..what_rustc_thinks } + Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx) } fn clean_impl<'tcx>( @@ -2114,6 +2067,7 @@ fn clean_extern_crate<'tcx>( } }); + let krate_owner_def_id = krate.owner_id.to_def_id(); if please_inline { let mut visited = FxHashSet::default(); @@ -2122,7 +2076,7 @@ fn clean_extern_crate<'tcx>( if let Some(items) = inline::try_inline( cx, cx.tcx.parent_module(krate.hir_id()).to_def_id(), - Some(krate.owner_id.to_def_id()), + Some(krate_owner_def_id), res, name, Some(attrs), @@ -2137,9 +2091,9 @@ fn clean_extern_crate<'tcx>( name: Some(name), attrs: Box::new(Attributes::from_ast(attrs)), item_id: crate_def_id.into(), - visibility: clean_visibility(ty_vis), kind: Box::new(ExternCrateItem { src: orig_name }), cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), + inline_stmt_id: Some(krate_owner_def_id), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cd1f972dce844..439311f064029 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability}; use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety; use rustc_index::vec::IndexVec; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; @@ -348,12 +348,12 @@ pub(crate) struct Item { /// Optional because not every item has a name, e.g. impls. pub(crate) name: Option, pub(crate) attrs: Box, - pub(crate) visibility: Visibility, /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. pub(crate) kind: Box, pub(crate) item_id: ItemId, - + /// This is the `DefId` of the `use` statement if the item was inlined. + pub(crate) inline_stmt_id: Option, pub(crate) cfg: Option>, } @@ -364,9 +364,7 @@ impl fmt::Debug for Item { let alternate = f.alternate(); // hand-picked fields that don't bloat the logs too much let mut fmt = f.debug_struct("Item"); - fmt.field("name", &self.name) - .field("visibility", &self.visibility) - .field("item_id", &self.item_id); + fmt.field("name", &self.name).field("item_id", &self.item_id); // allow printing the full item if someone really wants to if alternate { fmt.field("attrs", &self.attrs).field("kind", &self.kind).field("cfg", &self.cfg); @@ -388,6 +386,15 @@ pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { )) } +fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + let parent = tcx.parent(def_id); + match tcx.def_kind(parent) { + DefKind::Struct | DefKind::Union => false, + DefKind::Variant => true, + parent_kind => panic!("unexpected parent kind: {:?}", parent_kind), + } +} + impl Item { pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) @@ -462,7 +469,6 @@ impl Item { name, kind, Box::new(Attributes::from_ast(ast_attrs)), - cx, ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } @@ -472,21 +478,18 @@ impl Item { name: Option, kind: ItemKind, attrs: Box, - cx: &mut DocContext<'_>, cfg: Option>, ) -> Item { trace!("name={:?}, def_id={:?} cfg={:?}", name, def_id, cfg); - // Primitives and Keywords are written in the source code as private modules. - // The modules need to be private so that nobody actually uses them, but the - // keywords and primitives that they are documenting are public. - let visibility = if matches!(&kind, ItemKind::KeywordItem | ItemKind::PrimitiveItem(..)) { - Visibility::Public - } else { - clean_visibility(cx.tcx.visibility(def_id)) - }; - - Item { item_id: def_id.into(), kind: Box::new(kind), name, attrs, visibility, cfg } + Item { + item_id: def_id.into(), + kind: Box::new(kind), + name, + attrs, + cfg, + inline_stmt_id: None, + } } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -702,6 +705,51 @@ impl Item { }; Some(header) } + + pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + let def_id = match self.item_id { + // Anything but DefId *shouldn't* matter, but return a reasonable value anyway. + ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited, + // Primitives and Keywords are written in the source code as private modules. + // The modules need to be private so that nobody actually uses them, but the + // keywords and primitives that they are documenting are public. + ItemId::Primitive(..) => return Visibility::Public, + ItemId::DefId(def_id) => def_id, + }; + + match *self.kind { + // Explication on `ItemId::Primitive` just above. + ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Visibility::Public, + // Variant fields inherit their enum's visibility. + StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => { + return Visibility::Inherited; + } + // Variants always inherit visibility + VariantItem(..) => return Visibility::Inherited, + // Trait items inherit the trait's visibility + AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) + | TyMethodItem(..) | MethodItem(..) => { + let assoc_item = tcx.associated_item(def_id); + let is_trait_item = match assoc_item.container { + ty::TraitContainer => true, + ty::ImplContainer => { + // Trait impl items always inherit the impl's visibility -- + // we don't want to show `pub`. + tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some() + } + }; + if is_trait_item { + return Visibility::Inherited; + } + } + _ => {} + } + let def_id = match self.inline_stmt_id { + Some(inlined) => inlined, + None => def_id, + }; + clean_visibility(tcx.visibility(def_id)) + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 27dea8ec0b312..adf501a024031 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -747,11 +747,12 @@ fn assoc_const( extra: &str, cx: &Context<'_>, ) { + let tcx = cx.tcx(); write!( w, "{extra}{vis}const {name}: {ty}", extra = extra, - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(tcx).print_with_space(it.item_id, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), ty = ty.print(cx), @@ -764,7 +765,7 @@ fn assoc_const( // This hurts readability in this context especially when more complex expressions // are involved and it doesn't add much of value. // Find a way to print constants here without all that jazz. - write!(w, "{}", Escape(&default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx())))); + write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx)))); } } @@ -805,14 +806,15 @@ fn assoc_method( cx: &Context<'_>, render_mode: RenderMode, ) { - let header = meth.fn_header(cx.tcx()).expect("Trying to get header from a non-function item"); + let tcx = cx.tcx(); + let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let vis = meth.visibility.print_with_space(meth.item_id, cx).to_string(); + let vis = meth.visibility(tcx).print_with_space(meth.item_id, cx).to_string(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. let constness = match render_mode { RenderMode::Normal => { - print_constness_with_space(&header.constness, meth.const_stability(cx.tcx())) + print_constness_with_space(&header.constness, meth.const_stability(tcx)) } RenderMode::ForDeref { .. } => "", }; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6327817364a55..13df08280b5a8 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -318,6 +318,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: ); } + let tcx = cx.tcx(); match *myitem.kind { clean::ExternCrateItem { ref src } => { use crate::html::format::anchor; @@ -327,14 +328,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: Some(src) => write!( w, "

{}extern crate {} as {};", - myitem.visibility.print_with_space(myitem.item_id, cx), + myitem.visibility(tcx).print_with_space(myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), src, cx), myitem.name.unwrap(), ), None => write!( w, "
{}extern crate {};", - myitem.visibility.print_with_space(myitem.item_id, cx), + myitem.visibility(tcx).print_with_space(myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), ), } @@ -384,7 +385,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
\ {stab_tags_before}{stab_tags}{stab_tags_after}", stab = stab.unwrap_or_default(), - vis = myitem.visibility.print_with_space(myitem.item_id, cx), + vis = myitem.visibility(tcx).print_with_space(myitem.item_id, cx), imp = import.print(cx), ); w.write_str(ITEM_TABLE_ROW_CLOSE); @@ -408,7 +409,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: let stab = myitem.stability_class(cx.tcx()); let add = if stab.is_some() { " " } else { "" }; - let visibility_emoji = match myitem.visibility { + let visibility_emoji = match myitem.visibility(tcx) { clean::Visibility::Restricted(_) => { " 🔒 " } @@ -496,12 +497,13 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> } fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &clean::Function) { - let header = it.fn_header(cx.tcx()).expect("printing a function which isn't a function"); - let constness = print_constness_with_space(&header.constness, it.const_stability(cx.tcx())); + let tcx = cx.tcx(); + let header = it.fn_header(tcx).expect("printing a function which isn't a function"); + let constness = print_constness_with_space(&header.constness, it.const_stability(tcx)); let unsafety = header.unsafety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); - let visibility = it.visibility.print_with_space(it.item_id, cx).to_string(); + let visibility = it.visibility(tcx).print_with_space(it.item_id, cx).to_string(); let name = it.name.unwrap(); let generics_len = format!("{:#}", f.generics.print(cx)).len(); @@ -539,6 +541,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle } fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) { + let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::>(); let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); @@ -549,8 +552,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let count_types = required_types.len() + provided_types.len(); let count_consts = required_consts.len() + provided_consts.len(); let count_methods = required_methods.len() + provided_methods.len(); - let must_implement_one_of_functions = - cx.tcx().trait_def(t.def_id).must_implement_one_of.clone(); + let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone(); // Output the trait definition wrap_into_item_decl(w, |w| { @@ -559,9 +561,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: write!( w, "{}{}{}trait {}{}{}", - it.visibility.print_with_space(it.item_id, cx), - t.unsafety(cx.tcx()).print_with_space(), - if t.is_auto(cx.tcx()) { "auto " } else { "" }, + it.visibility(tcx).print_with_space(it.item_id, cx), + t.unsafety(tcx).print_with_space(), + if t.is_auto(tcx) { "auto " } else { "" }, it.name.unwrap(), t.generics.print(cx), bounds @@ -1020,7 +1022,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } let extern_crates = extern_crates .into_iter() - .map(|cnum| cx.shared.tcx.crate_name(cnum).to_string()) + .map(|cnum| tcx.crate_name(cnum).to_string()) .collect::>() .join(","); let (extern_before, extern_after) = @@ -1084,7 +1086,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); - write!(w, "{}", it.visibility.print_with_space(it.item_id, cx)); + write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.item_id, cx)); write!( w, "type {}{}{where_clause} = {type_};", @@ -1173,6 +1175,7 @@ fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item] } fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) { + let tcx = cx.tcx(); let count_variants = e.variants().count(); wrap_into_item_decl(w, |w| { wrap_item(w, "enum", |w| { @@ -1180,7 +1183,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!( w, "{}enum {}{}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(), e.generics.print(cx), ); @@ -1268,10 +1271,10 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(""); render_stability_since_raw( w, - variant.stable_since(cx.tcx()), - variant.const_stability(cx.tcx()), - it.stable_since(cx.tcx()), - it.const_stable_since(cx.tcx()), + variant.stable_since(tcx), + variant.const_stability(tcx), + it.stable_since(tcx), + it.const_stable_since(tcx), ); w.write_str(""); @@ -1389,12 +1392,13 @@ fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) { wrap_into_item_decl(w, |w| { wrap_item(w, "const", |w| { + let tcx = cx.tcx(); render_attributes_in_code(w, it); write!( w, "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(tcx).print_with_space(it.item_id, cx), name = it.name.unwrap(), typ = c.type_.print(cx), ); @@ -1408,9 +1412,9 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle // ` = 100i32;` // instead? - let value = c.value(cx.tcx()); - let is_literal = c.is_literal(cx.tcx()); - let expr = c.expr(cx.tcx()); + let value = c.value(tcx); + let is_literal = c.is_literal(tcx); + let expr = c.expr(tcx); if value.is_some() || is_literal { write!(w, " = {expr};", expr = Escape(&expr)); } else { @@ -1495,7 +1499,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean write!( w, "{vis}static {mutability}{name}: {typ}", - vis = it.visibility.print_with_space(it.item_id, cx), + vis = it.visibility(cx.tcx()).print_with_space(it.item_id, cx), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) @@ -1513,7 +1517,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { write!( w, " {}type {};\n}}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(cx.tcx()).print_with_space(it.item_id, cx), it.name.unwrap(), ); }); @@ -1666,7 +1670,8 @@ fn render_union( tab: &str, cx: &Context<'_>, ) { - write!(w, "{}union {}", it.visibility.print_with_space(it.item_id, cx), it.name.unwrap(),); + let tcx = cx.tcx(); + write!(w, "{}union {}", it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(),); let where_displayed = g .map(|g| { @@ -1693,7 +1698,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), tab @@ -1720,10 +1725,11 @@ fn render_struct( structhead: bool, cx: &Context<'_>, ) { + let tcx = cx.tcx(); write!( w, "{}{}{}", - it.visibility.print_with_space(it.item_id, cx), + it.visibility(tcx).print_with_space(it.item_id, cx), if structhead { "struct " } else { "" }, it.name.unwrap() ); @@ -1753,7 +1759,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), ); @@ -1785,7 +1791,7 @@ fn render_struct( write!( w, "{}{}", - field.visibility.print_with_space(field.item_id, cx), + field.visibility(tcx).print_with_space(field.item_id, cx), ty.print(cx), ) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index cdf59cdd32845..4962eb8f8e176 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -48,7 +48,8 @@ impl JsonRenderer<'_> { .map(rustc_ast_pretty::pprust::attribute_to_string) .collect(); let span = item.span(self.tcx); - let clean::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ } = item; + let visibility = item.visibility(self.tcx); + let clean::Item { name, attrs: _, kind: _, item_id, cfg: _, .. } = item; let inner = match *item.kind { clean::KeywordItem => return None, clean::StrippedItem(ref inner) => { diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 85be8fa109a7e..3bac5a8e5d749 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -11,6 +11,6 @@ pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass { description: "strips all private import statements (`use`, `extern crate`) from a crate", }; -pub(crate) fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { - ImportStripper.fold_crate(krate) +pub(crate) fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + ImportStripper { tcx: cx.tcx }.fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index e3b958b2036e3..8fc42462de969 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -22,13 +22,13 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> // strip all private items { let mut stripper = Stripper { - tcx: cx.tcx, retained: &mut retained, effective_visibilities: &cx.cache.effective_visibilities, update_retained: true, is_json_output, + tcx: cx.tcx, }; - krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); + krate = ImportStripper { tcx: cx.tcx }.fold_crate(stripper.fold_crate(krate)); } // strip all impls referencing private items diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 4fa5c04ddf61d..b2047360ccd9a 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -2,7 +2,6 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; - use std::mem; use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt}; @@ -11,11 +10,11 @@ use crate::formats::cache::Cache; use crate::visit_lib::RustdocEffectiveVisibilities; pub(crate) struct Stripper<'a, 'tcx> { - pub(crate) tcx: TyCtxt<'tcx>, pub(crate) retained: &'a mut ItemIdSet, pub(crate) effective_visibilities: &'a RustdocEffectiveVisibilities, pub(crate) update_retained: bool, pub(crate) is_json_output: bool, + pub(crate) tcx: TyCtxt<'tcx>, } // We need to handle this differently for the JSON output because some non exported items could @@ -35,7 +34,7 @@ fn is_item_reachable( } } -impl<'a> DocFolder for Stripper<'a, '_> { +impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { clean::StrippedItem(..) => { @@ -82,13 +81,13 @@ impl<'a> DocFolder for Stripper<'a, '_> { } clean::StructFieldItem(..) => { - if !i.visibility.is_public() { + if !i.visibility(self.tcx).is_public() { return Some(strip_item(i)); } } clean::ModuleItem(..) => { - if i.item_id.is_local() && !i.visibility.is_public() { + if i.item_id.is_local() && !i.visibility(self.tcx).is_public() { debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = strip_item(self.fold_item_recur(i)); @@ -239,12 +238,16 @@ impl<'a> DocFolder for ImplStripper<'a, '_> { } /// This stripper discards all private import statements (`use`, `extern crate`) -pub(crate) struct ImportStripper; +pub(crate) struct ImportStripper<'tcx> { + pub(crate) tcx: TyCtxt<'tcx>, +} -impl DocFolder for ImportStripper { +impl<'tcx> DocFolder for ImportStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { - clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => { + clean::ExternCrateItem { .. } | clean::ImportItem(..) + if !i.visibility(self.tcx).is_public() => + { None } _ => Some(self.fold_item_recur(i)), From a6aaed24cbd137abcf73d7cd9d7023c3dc4ec8c1 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Oct 2022 16:24:42 -0700 Subject: [PATCH 046/482] Update tinystr --- Cargo.lock | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 301167e02cc5d..33b1299976f3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1154,6 +1154,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dlmalloc" version = "0.2.3" @@ -1834,11 +1845,10 @@ dependencies = [ [[package]] name = "intl_pluralrules" -version = "7.0.1" +version = "7.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18f988384267d7066cc2be425e6faf352900652c046b6971d2e228d3b1c5ecf" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" dependencies = [ - "tinystr", "unic-langid", ] @@ -4949,9 +4959,12 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.3.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" +checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2" +dependencies = [ + "displaydoc", +] [[package]] name = "tinyvec" @@ -5187,9 +5200,9 @@ dependencies = [ [[package]] name = "unic-langid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" +checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" dependencies = [ "unic-langid-impl", "unic-langid-macros", @@ -5197,18 +5210,18 @@ dependencies = [ [[package]] name = "unic-langid-impl" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" +checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" dependencies = [ "tinystr", ] [[package]] name = "unic-langid-macros" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f980d6d87e8805f2836d64b4138cc95aa7986fa63b1f51f67d5fbff64dd6e5" +checksum = "055e618bf694161ffff0466d95cef3e1a5edc59f6ba1888e97801f2b4ebdc4fe" dependencies = [ "proc-macro-hack", "tinystr", @@ -5218,9 +5231,9 @@ dependencies = [ [[package]] name = "unic-langid-macros-impl" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29396ffd97e27574c3e01368b1a64267d3064969e4848e2e130ff668be9daa9f" +checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8" dependencies = [ "proc-macro-hack", "quote", From 23d7fc965513f6ddb783b1c0a0195cc1f2e0be25 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Oct 2022 16:43:02 -0700 Subject: [PATCH 047/482] Update license --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 8a0239eceff13..56b8171959aed 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -23,6 +23,7 @@ const LICENSES: &[&str] = &[ "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros "MIT OR Zlib OR Apache-2.0", // miniz_oxide "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident + "Unicode-DFS-2016", // tinystr and icu4x ]; /// These are exceptions to Rust's permissive licensing policy, and From 44b1441c9eb4846b67b5370014efee63ebaef96e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Oct 2022 16:43:48 -0700 Subject: [PATCH 048/482] allowlist displaydoc --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 56b8171959aed..35fa968f977ab 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -110,6 +110,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "datafrog", "difference", "digest", + "displaydoc", "dlmalloc", "either", "ena", From f0c743ad0be7698f36706410002017eef0ddf6cd Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 30 Oct 2022 10:23:14 -0400 Subject: [PATCH 049/482] Update COPYRIGHT file --- COPYRIGHT | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/COPYRIGHT b/COPYRIGHT index 11335879bd4a7..05993830a0fb4 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -339,3 +339,53 @@ their own copyright notices and license terms: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +* Portions of internationalization code use code or data from Unicode, which + carry the following license: + + UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + + See Terms of Use + for definitions of Unicode Inc.’s Data Files and Software. + + NOTICE TO USER: Carefully read the following legal agreement. + BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S + DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), + YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. + IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE + THE DATA FILES OR SOFTWARE. + + COPYRIGHT AND PERMISSION NOTICE + + Copyright © 1991-2022 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that either + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, or + (b) this copyright and permission notice appear in associated + Documentation. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. From b266ce0374aacb3b6df11b4364f427bf385ba433 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Fri, 28 Oct 2022 20:44:26 +0200 Subject: [PATCH 050/482] Gate some recovery behind a flag Mainly in `expr.rs` --- .../rustc_parse/src/parser/diagnostics.rs | 12 +++++++++ compiler/rustc_parse/src/parser/expr.rs | 25 ++++++++++++++----- compiler/rustc_parse/src/parser/mod.rs | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 887a4a6de33b1..7dc4fd0044f1f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -769,6 +769,10 @@ impl<'a> Parser<'a> { segment: &PathSegment, end: &[&TokenKind], ) -> bool { + if !self.may_recover() { + return false; + } + // This function is intended to be invoked after parsing a path segment where there are two // cases: // @@ -863,6 +867,10 @@ impl<'a> Parser<'a> { /// Check if a method call with an intended turbofish has been written without surrounding /// angle brackets. pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) { + if !self.may_recover() { + return; + } + if token::ModSep == self.token.kind && segment.args.is_none() { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); @@ -1396,6 +1404,10 @@ impl<'a> Parser<'a> { &mut self, base: P, ) -> PResult<'a, P> { + if !self.may_recover() { + return Ok(base); + } + // Do not add `::` to expected tokens. if self.token == token::ModSep { if let Some(ty) = base.to_ty() { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a781748efc52a..0eb633f641687 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -132,7 +132,7 @@ impl<'a> Parser<'a> { Ok(expr) => Ok(expr), Err(mut err) => match self.token.ident() { Some((Ident { name: kw::Underscore, .. }, false)) - if self.look_ahead(1, |t| t == &token::Comma) => + if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) => { // Special-case handling of `foo(_, _, _)` err.emit(); @@ -456,7 +456,7 @@ impl<'a> Parser<'a> { return None; } (Some(op), _) => (op, self.token.span), - (None, Some((Ident { name: sym::and, span }, false))) => { + (None, Some((Ident { name: sym::and, span }, false))) if self.may_recover() => { self.sess.emit_err(InvalidLogicalOperator { span: self.token.span, incorrect: "and".into(), @@ -464,7 +464,7 @@ impl<'a> Parser<'a> { }); (AssocOp::LAnd, span) } - (None, Some((Ident { name: sym::or, span }, false))) => { + (None, Some((Ident { name: sym::or, span }, false))) if self.may_recover() => { self.sess.emit_err(InvalidLogicalOperator { span: self.token.span, incorrect: "or".into(), @@ -615,7 +615,7 @@ impl<'a> Parser<'a> { token::Ident(..) if this.token.is_keyword(kw::Box) => { make_it!(this, attrs, |this, _| this.parse_box_expr(lo)) } - token::Ident(..) if this.is_mistaken_not_ident_negation() => { + token::Ident(..) if this.may_recover() && this.is_mistaken_not_ident_negation() => { make_it!(this, attrs, |this, _| this.recover_not_expr(lo)) } _ => return this.parse_dot_or_call_expr(Some(attrs)), @@ -718,6 +718,10 @@ impl<'a> Parser<'a> { let cast_expr = match self.parse_as_cast_ty() { Ok(rhs) => mk_expr(self, lhs, rhs), Err(type_err) => { + if !self.may_recover() { + return Err(type_err); + } + // Rewind to before attempting to parse the type with generics, to recover // from situations like `x as usize < y` in which we first tried to parse // `usize < y` as a type with generic arguments. @@ -1197,6 +1201,10 @@ impl<'a> Parser<'a> { seq: &mut PResult<'a, P>, snapshot: Option<(SnapshotParser<'a>, ExprKind)>, ) -> Option> { + if !self.may_recover() { + return None; + } + match (seq.as_mut(), snapshot) { (Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => { snapshot.bump(); // `(` @@ -1360,7 +1368,7 @@ impl<'a> Parser<'a> { ) } else if self.check_inline_const(0) { self.parse_const_block(lo.to(self.token.span), false) - } else if self.is_do_catch_block() { + } else if self.may_recover() && self.is_do_catch_block() { self.recover_do_catch() } else if self.is_try_block() { self.expect_keyword(kw::Try)?; @@ -1532,6 +1540,7 @@ impl<'a> Parser<'a> { { self.parse_block_expr(label, lo, BlockCheckMode::Default) } else if !ate_colon + && self.may_recover() && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma) || self.token.is_op()) { @@ -1999,6 +2008,10 @@ impl<'a> Parser<'a> { prev_span: Span, open_delim_span: Span, ) -> PResult<'a, ()> { + if !self.may_recover() { + return Ok(()); + } + if self.token.kind == token::Comma { if !self.sess.source_map().is_multiline(prev_span.until(self.token.span)) { return Ok(()); @@ -2039,7 +2052,7 @@ impl<'a> Parser<'a> { lo: Span, blk_mode: BlockCheckMode, ) -> PResult<'a, P> { - if self.is_array_like_block() { + if self.may_recover() && self.is_array_like_block() { if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) { return Ok(arr); } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 5fe29062b85b9..2e59c005e315a 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -104,6 +104,7 @@ macro_rules! maybe_whole { macro_rules! maybe_recover_from_interpolated_ty_qpath { ($self: expr, $allow_qpath_recovery: expr) => { if $allow_qpath_recovery + && $self.may_recover() && $self.look_ahead(1, |t| t == &token::ModSep) && let token::Interpolated(nt) = &$self.token.kind && let token::NtTy(ty) = &**nt From b7ed417c30117534877c301bacaf243b9728caf8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 30 Oct 2022 19:39:07 +0000 Subject: [PATCH 051/482] Format dyn Trait better in type_name intrinsic --- .../rustc_const_eval/src/util/type_name.rs | 12 ++---------- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- library/core/tests/any.rs | 18 ++++++++++++++++++ .../ui/type/issue-94187-verbose-type-name.rs | 5 +---- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 221efc6f98140..08a6d69b8e40c 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -73,18 +73,10 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { } fn print_dyn_existential( - mut self, + self, predicates: &'tcx ty::List>>, ) -> Result { - let mut first = true; - for p in predicates { - if !first { - write!(self, "+")?; - } - first = false; - self = p.print(self)?; - } - Ok(self) + self.pretty_print_dyn_existential(predicates) } fn path_crate(mut self, cnum: CrateNum) -> Result { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f07c60af24829..fab85c39d2535 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1137,7 +1137,7 @@ pub trait PrettyPrinter<'tcx>: // // To avoid causing instabilities in compiletest // output, sort the auto-traits alphabetically. - auto_traits.sort_by_cached_key(|did| self.tcx().def_path_str(*did)); + auto_traits.sort_by_cached_key(|did| with_no_trimmed_paths!(self.tcx().def_path_str(*did))); for def_id in auto_traits { if !first { diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs index 9538b81394957..e98dac8d12ef4 100644 --- a/library/core/tests/any.rs +++ b/library/core/tests/any.rs @@ -131,6 +131,24 @@ fn distinct_type_names() { assert_ne!(type_name_of_val(Velocity), type_name_of_val(Velocity(0.0, -9.8)),); } +#[cfg(not(bootstrap))] +#[test] +fn dyn_type_name() { + trait Foo { + type Bar; + } + + assert_eq!( + "dyn core::ops::function::Fn(i32, i32) -> i32", + std::any::type_name:: i32>() + ); + assert_eq!( + "dyn coretests::any::dyn_type_name::Foo \ + + core::marker::Send + core::marker::Sync", + std::any::type_name:: + Send + Sync>() + ); +} + // Test the `Provider` API. struct SomeConcreteType { diff --git a/src/test/ui/type/issue-94187-verbose-type-name.rs b/src/test/ui/type/issue-94187-verbose-type-name.rs index 64f0c09e89bca..3713a32eb1183 100644 --- a/src/test/ui/type/issue-94187-verbose-type-name.rs +++ b/src/test/ui/type/issue-94187-verbose-type-name.rs @@ -12,8 +12,5 @@ fn main() { struct Wrapper; assert_eq!(type_name::>(), "issue_94187_verbose_type_name::main::Wrapper<0>"); - assert_eq!( - type_name:: u32>(), - "dyn core::ops::function::Fn<(u32,)>+Output = u32" - ); + assert_eq!(type_name:: u32>(), "dyn core::ops::function::Fn(u32) -> u32"); } From 7a93a5ac210c7d3271abfaab8373a4479db0ca2f Mon Sep 17 00:00:00 2001 From: Sky Date: Mon, 31 Oct 2022 12:01:20 -0400 Subject: [PATCH 052/482] Add tracking issue for `string_extend_from_within` --- library/alloc/src/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c436adf70067a..c9ba8921f6ecc 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -949,7 +949,7 @@ impl String { /// assert_eq!(string, "abcdecdeabecde"); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "string_extend_from_within", issue = "none")] + #[unstable(feature = "string_extend_from_within", issue = "103806")] pub fn extend_from_within(&mut self, src: R) where R: RangeBounds, From 46374531b0a9e691c0acc54c3b86cf547c5aaae3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 1 Nov 2022 16:27:00 -0700 Subject: [PATCH 053/482] rustdoc: simplify mobile item-table CSS Using flexbox in column direction is needlessly complicated, since no special flex powers are being used here. Just use regular block layout. This should result in no visible changes. --- src/librustdoc/html/static/css/rustdoc.css | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 219d1b4ed53ff..360b6b9832a55 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1870,16 +1870,9 @@ in storage.js } /* Display an alternating layout on tablets and phones */ - .item-table { + .item-table, .item-row, .item-left, .item-right { display: block; } - .item-row { - display: flex; - flex-flow: column wrap; - } - .item-left, .item-right { - width: 100%; - } /* Display an alternating layout on tablets and phones */ .search-results > a { From a251e6bcd4177cd8e733ea8a15230c35481c2f72 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 00:48:44 +0000 Subject: [PATCH 054/482] Use ObligationCtxt in fully_normalize --- .../rustc_trait_selection/src/traits/mod.rs | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0bf54c096cd40..9ee6e0a2bf3a2 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -390,6 +390,7 @@ pub fn normalize_param_env_or_error<'tcx>( } /// Normalize a type and process all resulting obligations, returning any errors +#[instrument(skip_all)] pub fn fully_normalize<'tcx, T>( infcx: &InferCtxt<'tcx>, cause: ObligationCause<'tcx>, @@ -399,28 +400,18 @@ pub fn fully_normalize<'tcx, T>( where T: TypeFoldable<'tcx>, { - debug!("fully_normalize_with_fulfillcx(value={:?})", value); - let selcx = &mut SelectionContext::new(infcx); - let Normalized { value: normalized_value, obligations } = - project::normalize(selcx, param_env, cause, value); - debug!( - "fully_normalize: normalized_value={:?} obligations={:?}", - normalized_value, obligations - ); - - let mut fulfill_cx = FulfillmentContext::new(); - for obligation in obligations { - fulfill_cx.register_predicate_obligation(infcx, obligation); - } - - debug!("fully_normalize: select_all_or_error start"); - let errors = fulfill_cx.select_all_or_error(infcx); + let ocx = ObligationCtxt::new(infcx); + debug!(?value); + let normalized_value = ocx.normalize(cause, param_env, value); + debug!(?normalized_value); + debug!("select_all_or_error start"); + let errors = ocx.select_all_or_error(); if !errors.is_empty() { return Err(errors); } - debug!("fully_normalize: select_all_or_error complete"); + debug!("select_all_or_error complete"); let resolved_value = infcx.resolve_vars_if_possible(normalized_value); - debug!("fully_normalize: resolved_value={:?}", resolved_value); + debug!(?resolved_value); Ok(resolved_value) } From 9dc248128817ad8c069b972aa378d5b0831d22d9 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Tue, 1 Nov 2022 19:02:45 -0400 Subject: [PATCH 055/482] Reorder `walk_` functions in intravisit.rs --- compiler/rustc_hir/src/intravisit.rs | 726 +++++++++++++-------------- 1 file changed, 363 insertions(+), 363 deletions(-) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9ee5e25c9bf64..d852893ad5dc6 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -443,72 +443,6 @@ pub trait Visitor<'v>: Sized { } } -pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) { - visitor.visit_id(mod_hir_id); - for &item_id in module.item_ids { - visitor.visit_nested_item(item_id); - } -} - -pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) { - walk_list!(visitor, visit_param, body.params); - visitor.visit_expr(&body.value); -} - -pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) { - // Intentionally visiting the expr first - the initialization expr - // dominates the local's definition. - walk_list!(visitor, visit_expr, &local.init); - visitor.visit_id(local.hir_id); - visitor.visit_pat(&local.pat); - if let Some(els) = local.els { - visitor.visit_block(els); - } - walk_list!(visitor, visit_ty, &local.ty); -} - -pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) { - visitor.visit_name(ident.name); -} - -pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) { - visitor.visit_ident(label.ident); -} - -pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v GenericArg<'v>) { - match generic_arg { - GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt), - GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value), - GenericArg::Infer(inf) => visitor.visit_infer(inf), - } -} - -pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { - visitor.visit_id(lifetime.hir_id); - match lifetime.name { - LifetimeName::Param(_, ParamName::Plain(ident)) => { - visitor.visit_ident(ident); - } - LifetimeName::Param(_, ParamName::Fresh) - | LifetimeName::Param(_, ParamName::Error) - | LifetimeName::Static - | LifetimeName::Error - | LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Infer => {} - } -} - -pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>) { - walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params); - visitor.visit_trait_ref(&trait_ref.trait_ref); -} - -pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef<'v>) { - visitor.visit_id(trait_ref.hir_ref_id); - visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) -} - pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) { visitor.visit_id(param.hir_id); visitor.visit_pat(¶m.pat); @@ -605,142 +539,80 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { } } -pub fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>, id: HirId) { - for (op, op_sp) in asm.operands { - match op { - InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => { - visitor.visit_expr(expr) - } - InlineAsmOperand::Out { expr, .. } => { - if let Some(expr) = expr { - visitor.visit_expr(expr); - } - } - InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { - visitor.visit_expr(in_expr); - if let Some(out_expr) = out_expr { - visitor.visit_expr(out_expr); - } - } - InlineAsmOperand::Const { anon_const, .. } - | InlineAsmOperand::SymFn { anon_const, .. } => visitor.visit_anon_const(anon_const), - InlineAsmOperand::SymStatic { path, .. } => visitor.visit_qpath(path, id, *op_sp), - } - } -} - -pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) { - visitor.visit_id(hir_id); - visitor.visit_path(path, hir_id); +pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) { + walk_list!(visitor, visit_param, body.params); + visitor.visit_expr(&body.value); } -pub fn walk_enum_def<'v, V: Visitor<'v>>( - visitor: &mut V, - enum_definition: &'v EnumDef<'v>, - item_id: HirId, -) { - visitor.visit_id(item_id); - walk_list!(visitor, visit_variant, enum_definition.variants); +pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) { + visitor.visit_name(ident.name); } -pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant<'v>) { - visitor.visit_ident(variant.ident); - visitor.visit_id(variant.id); - visitor.visit_variant_data(&variant.data); - walk_list!(visitor, visit_anon_const, &variant.disr_expr); +pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) { + visitor.visit_id(mod_hir_id); + for &item_id in module.item_ids { + visitor.visit_nested_item(item_id); + } } -pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { - visitor.visit_id(typ.hir_id); +pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) { + visitor.visit_id(foreign_item.hir_id()); + visitor.visit_ident(foreign_item.ident); - match typ.kind { - TyKind::Slice(ref ty) => visitor.visit_ty(ty), - TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), - TyKind::Rptr(ref lifetime, ref mutable_type) => { - visitor.visit_lifetime(lifetime); - visitor.visit_ty(&mutable_type.ty) - } - TyKind::Never => {} - TyKind::Tup(tuple_element_types) => { - walk_list!(visitor, visit_ty, tuple_element_types); - } - TyKind::BareFn(ref function_declaration) => { - walk_list!(visitor, visit_generic_param, function_declaration.generic_params); - visitor.visit_fn_decl(&function_declaration.decl); - } - TyKind::Path(ref qpath) => { - visitor.visit_qpath(qpath, typ.hir_id, typ.span); - } - TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => { - visitor.visit_nested_item(item_id); - walk_list!(visitor, visit_generic_arg, lifetimes); - } - TyKind::Array(ref ty, ref length) => { - visitor.visit_ty(ty); - visitor.visit_array_length(length) - } - TyKind::TraitObject(bounds, ref lifetime, _syntax) => { - for bound in bounds { - visitor.visit_poly_trait_ref(bound); + match foreign_item.kind { + ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => { + visitor.visit_generics(generics); + visitor.visit_fn_decl(function_declaration); + for ¶m_name in param_names { + visitor.visit_ident(param_name); } - visitor.visit_lifetime(lifetime); } - TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), - TyKind::Infer | TyKind::Err => {} + ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), + ForeignItemKind::Type => (), } } -pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) { - visitor.visit_id(inf.hir_id); -} - -pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) { - match *qpath { - QPath::Resolved(ref maybe_qself, ref path) => { - walk_list!(visitor, visit_ty, maybe_qself); - visitor.visit_path(path, id) - } - QPath::TypeRelative(ref qself, ref segment) => { - visitor.visit_ty(qself); - visitor.visit_path_segment(segment); - } - QPath::LangItem(..) => {} +pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) { + // Intentionally visiting the expr first - the initialization expr + // dominates the local's definition. + walk_list!(visitor, visit_expr, &local.init); + visitor.visit_id(local.hir_id); + visitor.visit_pat(&local.pat); + if let Some(els) = local.els { + visitor.visit_block(els); } + walk_list!(visitor, visit_ty, &local.ty); } -pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) { - for segment in path.segments { - visitor.visit_path_segment(segment); - } +pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) { + visitor.visit_id(block.hir_id); + walk_list!(visitor, visit_stmt, block.stmts); + walk_list!(visitor, visit_expr, &block.expr); } -pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) { - visitor.visit_ident(segment.ident); - visitor.visit_id(segment.hir_id); - if let Some(ref args) = segment.args { - visitor.visit_generic_args(args); +pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) { + visitor.visit_id(statement.hir_id); + match statement.kind { + StmtKind::Local(ref local) => visitor.visit_local(local), + StmtKind::Item(item) => visitor.visit_nested_item(item), + StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { + visitor.visit_expr(expression) + } } } -pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, generic_args: &'v GenericArgs<'v>) { - walk_list!(visitor, visit_generic_arg, generic_args.args); - walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings); -} - -pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>( - visitor: &mut V, - type_binding: &'v TypeBinding<'v>, -) { - visitor.visit_id(type_binding.hir_id); - visitor.visit_ident(type_binding.ident); - visitor.visit_generic_args(type_binding.gen_args); - match type_binding.kind { - TypeBindingKind::Equality { ref term } => match term { - Term::Ty(ref ty) => visitor.visit_ty(ty), - Term::Const(ref c) => visitor.visit_anon_const(c), - }, - TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds), +pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) { + visitor.visit_id(arm.hir_id); + visitor.visit_pat(&arm.pat); + if let Some(ref g) = arm.guard { + match g { + Guard::If(ref e) => visitor.visit_expr(e), + Guard::IfLet(ref l) => { + visitor.visit_let_expr(l); + } + } } + visitor.visit_expr(&arm.body); } pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) { @@ -788,33 +660,181 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<' visitor.visit_pat(&field.pat) } -pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) { - visitor.visit_id(foreign_item.hir_id()); - visitor.visit_ident(foreign_item.ident); - - match foreign_item.kind { - ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => { - visitor.visit_generics(generics); - visitor.visit_fn_decl(function_declaration); - for ¶m_name in param_names { - visitor.visit_ident(param_name); - } - } - ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), - ForeignItemKind::Type => (), +pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) { + match len { + &ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id), + ArrayLen::Body(c) => visitor.visit_anon_const(c), } } -pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) { - match *bound { - GenericBound::Trait(ref typ, _modifier) => { - visitor.visit_poly_trait_ref(typ); +pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) { + visitor.visit_id(constant.hir_id); + visitor.visit_nested_body(constant.body); +} + +pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) { + visitor.visit_id(expression.hir_id); + match expression.kind { + ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), + ExprKind::Array(subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); } - GenericBound::LangItemTrait(_, _span, hir_id, args) => { - visitor.visit_id(hir_id); - visitor.visit_generic_args(args); + ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), + ExprKind::Repeat(ref element, ref count) => { + visitor.visit_expr(element); + visitor.visit_array_length(count) } - GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), + ExprKind::Struct(ref qpath, fields, ref optional_base) => { + visitor.visit_qpath(qpath, expression.hir_id, expression.span); + walk_list!(visitor, visit_expr_field, fields); + walk_list!(visitor, visit_expr, optional_base); + } + ExprKind::Tup(subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); + } + ExprKind::Call(ref callee_expression, arguments) => { + visitor.visit_expr(callee_expression); + walk_list!(visitor, visit_expr, arguments); + } + ExprKind::MethodCall(ref segment, receiver, arguments, _) => { + visitor.visit_path_segment(segment); + visitor.visit_expr(receiver); + walk_list!(visitor, visit_expr, arguments); + } + ExprKind::Binary(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(left_expression); + visitor.visit_expr(right_expression) + } + ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { + visitor.visit_expr(subexpression) + } + ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { + visitor.visit_expr(subexpression); + visitor.visit_ty(typ) + } + ExprKind::DropTemps(ref subexpression) => { + visitor.visit_expr(subexpression); + } + ExprKind::Let(ref let_expr) => visitor.visit_let_expr(let_expr), + ExprKind::If(ref cond, ref then, ref else_opt) => { + visitor.visit_expr(cond); + visitor.visit_expr(then); + walk_list!(visitor, visit_expr, else_opt); + } + ExprKind::Loop(ref block, ref opt_label, _, _) => { + walk_list!(visitor, visit_label, opt_label); + visitor.visit_block(block); + } + ExprKind::Match(ref subexpression, arms, _) => { + visitor.visit_expr(subexpression); + walk_list!(visitor, visit_arm, arms); + } + ExprKind::Closure(&Closure { + binder: _, + bound_generic_params, + fn_decl, + body, + capture_clause: _, + fn_decl_span: _, + movability: _, + }) => { + walk_list!(visitor, visit_generic_param, bound_generic_params); + visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id) + } + ExprKind::Block(ref block, ref opt_label) => { + walk_list!(visitor, visit_label, opt_label); + visitor.visit_block(block); + } + ExprKind::Assign(ref lhs, ref rhs, _) => { + visitor.visit_expr(rhs); + visitor.visit_expr(lhs) + } + ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(right_expression); + visitor.visit_expr(left_expression); + } + ExprKind::Field(ref subexpression, ident) => { + visitor.visit_expr(subexpression); + visitor.visit_ident(ident); + } + ExprKind::Index(ref main_expression, ref index_expression) => { + visitor.visit_expr(main_expression); + visitor.visit_expr(index_expression) + } + ExprKind::Path(ref qpath) => { + visitor.visit_qpath(qpath, expression.hir_id, expression.span); + } + ExprKind::Break(ref destination, ref opt_expr) => { + walk_list!(visitor, visit_label, &destination.label); + walk_list!(visitor, visit_expr, opt_expr); + } + ExprKind::Continue(ref destination) => { + walk_list!(visitor, visit_label, &destination.label); + } + ExprKind::Ret(ref optional_expression) => { + walk_list!(visitor, visit_expr, optional_expression); + } + ExprKind::InlineAsm(ref asm) => { + visitor.visit_inline_asm(asm, expression.hir_id); + } + ExprKind::Yield(ref subexpression, _) => { + visitor.visit_expr(subexpression); + } + ExprKind::Lit(_) | ExprKind::Err => {} + } +} + +pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>) { + // match the visit order in walk_local + visitor.visit_expr(let_expr.init); + visitor.visit_id(let_expr.hir_id); + visitor.visit_pat(let_expr.pat); + walk_list!(visitor, visit_ty, let_expr.ty); +} + +pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) { + visitor.visit_id(field.hir_id); + visitor.visit_ident(field.ident); + visitor.visit_expr(&field.expr) +} + +pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { + visitor.visit_id(typ.hir_id); + + match typ.kind { + TyKind::Slice(ref ty) => visitor.visit_ty(ty), + TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), + TyKind::Rptr(ref lifetime, ref mutable_type) => { + visitor.visit_lifetime(lifetime); + visitor.visit_ty(&mutable_type.ty) + } + TyKind::Never => {} + TyKind::Tup(tuple_element_types) => { + walk_list!(visitor, visit_ty, tuple_element_types); + } + TyKind::BareFn(ref function_declaration) => { + walk_list!(visitor, visit_generic_param, function_declaration.generic_params); + visitor.visit_fn_decl(&function_declaration.decl); + } + TyKind::Path(ref qpath) => { + visitor.visit_qpath(qpath, typ.hir_id, typ.span); + } + TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => { + visitor.visit_nested_item(item_id); + walk_list!(visitor, visit_generic_arg, lifetimes); + } + TyKind::Array(ref ty, ref length) => { + visitor.visit_ty(ty); + visitor.visit_array_length(length) + } + TyKind::TraitObject(bounds, ref lifetime, _syntax) => { + for bound in bounds { + visitor.visit_poly_trait_ref(bound); + } + visitor.visit_lifetime(lifetime); + } + TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), + TyKind::Infer | TyKind::Err => {} } } @@ -879,12 +899,6 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( } } -pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) { - if let FnRetTy::Return(ref output_ty) = *ret_ty { - visitor.visit_ty(output_ty) - } -} - pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl<'v>) { for ty in function_declaration.inputs { visitor.visit_ty(ty) @@ -892,12 +906,9 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & walk_fn_ret_ty(visitor, &function_declaration.output) } -pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) { - match function_kind { - FnKind::ItemFn(_, generics, ..) => { - visitor.visit_generics(generics); - } - FnKind::Closure | FnKind::Method(..) => {} +pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) { + if let FnRetTy::Return(ref output_ty) = *ret_ty { + visitor.visit_ty(output_ty) } } @@ -914,6 +925,20 @@ pub fn walk_fn<'v, V: Visitor<'v>>( visitor.visit_nested_body(body_id) } +pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) { + match function_kind { + FnKind::ItemFn(_, generics, ..) => { + visitor.visit_generics(generics); + } + FnKind::Closure | FnKind::Method(..) => {} + } +} + +pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) { + visitor.visit_id(hir_id); + visitor.visit_path(path, hir_id); +} + pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) { // N.B., deliberately force a compilation error if/when new fields are added. let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item; @@ -1008,6 +1033,29 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &' visitor.visit_associated_item_kind(kind); } +pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef<'v>) { + visitor.visit_id(trait_ref.hir_ref_id); + visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) +} + +pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) { + match *bound { + GenericBound::Trait(ref typ, _modifier) => { + visitor.visit_poly_trait_ref(typ); + } + GenericBound::LangItemTrait(_, _span, hir_id, args) => { + visitor.visit_id(hir_id); + visitor.visit_generic_args(args); + } + GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), + } +} + +pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>) { + walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params); + visitor.visit_trait_ref(&trait_ref.trait_ref); +} + pub fn walk_struct_def<'v, V: Visitor<'v>>( visitor: &mut V, struct_definition: &'v VariantData<'v>, @@ -1022,173 +1070,101 @@ pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<' visitor.visit_ty(&field.ty); } -pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) { - visitor.visit_id(block.hir_id); - walk_list!(visitor, visit_stmt, block.stmts); - walk_list!(visitor, visit_expr, &block.expr); +pub fn walk_enum_def<'v, V: Visitor<'v>>( + visitor: &mut V, + enum_definition: &'v EnumDef<'v>, + item_id: HirId, +) { + visitor.visit_id(item_id); + walk_list!(visitor, visit_variant, enum_definition.variants); } -pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) { - visitor.visit_id(statement.hir_id); - match statement.kind { - StmtKind::Local(ref local) => visitor.visit_local(local), - StmtKind::Item(item) => visitor.visit_nested_item(item), - StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { - visitor.visit_expr(expression) - } - } +pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant<'v>) { + visitor.visit_ident(variant.ident); + visitor.visit_id(variant.id); + visitor.visit_variant_data(&variant.data); + walk_list!(visitor, visit_anon_const, &variant.disr_expr); } -pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) { - match len { - &ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id), - ArrayLen::Body(c) => visitor.visit_anon_const(c), - } +pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) { + visitor.visit_ident(label.ident); } -pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) { - visitor.visit_id(constant.hir_id); - visitor.visit_nested_body(constant.body); +pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) { + visitor.visit_id(inf.hir_id); } -pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>) { - // match the visit order in walk_local - visitor.visit_expr(let_expr.init); - visitor.visit_id(let_expr.hir_id); - visitor.visit_pat(let_expr.pat); - walk_list!(visitor, visit_ty, let_expr.ty); +pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v GenericArg<'v>) { + match generic_arg { + GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt), + GenericArg::Type(ty) => visitor.visit_ty(ty), + GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value), + GenericArg::Infer(inf) => visitor.visit_infer(inf), + } } -pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) { - visitor.visit_id(field.hir_id); - visitor.visit_ident(field.ident); - visitor.visit_expr(&field.expr) +pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { + visitor.visit_id(lifetime.hir_id); + match lifetime.name { + LifetimeName::Param(_, ParamName::Plain(ident)) => { + visitor.visit_ident(ident); + } + LifetimeName::Param(_, ParamName::Fresh) + | LifetimeName::Param(_, ParamName::Error) + | LifetimeName::Static + | LifetimeName::Error + | LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Infer => {} + } } -pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) { - visitor.visit_id(expression.hir_id); - match expression.kind { - ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::Array(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), - ExprKind::Repeat(ref element, ref count) => { - visitor.visit_expr(element); - visitor.visit_array_length(count) - } - ExprKind::Struct(ref qpath, fields, ref optional_base) => { - visitor.visit_qpath(qpath, expression.hir_id, expression.span); - walk_list!(visitor, visit_expr_field, fields); - walk_list!(visitor, visit_expr, optional_base); - } - ExprKind::Tup(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::Call(ref callee_expression, arguments) => { - visitor.visit_expr(callee_expression); - walk_list!(visitor, visit_expr, arguments); +pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) { + match *qpath { + QPath::Resolved(ref maybe_qself, ref path) => { + walk_list!(visitor, visit_ty, maybe_qself); + visitor.visit_path(path, id) } - ExprKind::MethodCall(ref segment, receiver, arguments, _) => { + QPath::TypeRelative(ref qself, ref segment) => { + visitor.visit_ty(qself); visitor.visit_path_segment(segment); - visitor.visit_expr(receiver); - walk_list!(visitor, visit_expr, arguments); } - ExprKind::Binary(_, ref left_expression, ref right_expression) => { - visitor.visit_expr(left_expression); - visitor.visit_expr(right_expression) - } - ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { - visitor.visit_expr(subexpression) - } - ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { - visitor.visit_expr(subexpression); - visitor.visit_ty(typ) - } - ExprKind::DropTemps(ref subexpression) => { - visitor.visit_expr(subexpression); - } - ExprKind::Let(ref let_expr) => visitor.visit_let_expr(let_expr), - ExprKind::If(ref cond, ref then, ref else_opt) => { - visitor.visit_expr(cond); - visitor.visit_expr(then); - walk_list!(visitor, visit_expr, else_opt); - } - ExprKind::Loop(ref block, ref opt_label, _, _) => { - walk_list!(visitor, visit_label, opt_label); - visitor.visit_block(block); - } - ExprKind::Match(ref subexpression, arms, _) => { - visitor.visit_expr(subexpression); - walk_list!(visitor, visit_arm, arms); - } - ExprKind::Closure(&Closure { - binder: _, - bound_generic_params, - fn_decl, - body, - capture_clause: _, - fn_decl_span: _, - movability: _, - }) => { - walk_list!(visitor, visit_generic_param, bound_generic_params); - visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id) - } - ExprKind::Block(ref block, ref opt_label) => { - walk_list!(visitor, visit_label, opt_label); - visitor.visit_block(block); - } - ExprKind::Assign(ref lhs, ref rhs, _) => { - visitor.visit_expr(rhs); - visitor.visit_expr(lhs) - } - ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { - visitor.visit_expr(right_expression); - visitor.visit_expr(left_expression); - } - ExprKind::Field(ref subexpression, ident) => { - visitor.visit_expr(subexpression); - visitor.visit_ident(ident); - } - ExprKind::Index(ref main_expression, ref index_expression) => { - visitor.visit_expr(main_expression); - visitor.visit_expr(index_expression) - } - ExprKind::Path(ref qpath) => { - visitor.visit_qpath(qpath, expression.hir_id, expression.span); - } - ExprKind::Break(ref destination, ref opt_expr) => { - walk_list!(visitor, visit_label, &destination.label); - walk_list!(visitor, visit_expr, opt_expr); - } - ExprKind::Continue(ref destination) => { - walk_list!(visitor, visit_label, &destination.label); - } - ExprKind::Ret(ref optional_expression) => { - walk_list!(visitor, visit_expr, optional_expression); - } - ExprKind::InlineAsm(ref asm) => { - visitor.visit_inline_asm(asm, expression.hir_id); - } - ExprKind::Yield(ref subexpression, _) => { - visitor.visit_expr(subexpression); - } - ExprKind::Lit(_) | ExprKind::Err => {} + QPath::LangItem(..) => {} } } -pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) { - visitor.visit_id(arm.hir_id); - visitor.visit_pat(&arm.pat); - if let Some(ref g) = arm.guard { - match g { - Guard::If(ref e) => visitor.visit_expr(e), - Guard::IfLet(ref l) => { - visitor.visit_let_expr(l); - } - } +pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) { + for segment in path.segments { + visitor.visit_path_segment(segment); + } +} + +pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) { + visitor.visit_ident(segment.ident); + visitor.visit_id(segment.hir_id); + if let Some(ref args) = segment.args { + visitor.visit_generic_args(args); + } +} + +pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, generic_args: &'v GenericArgs<'v>) { + walk_list!(visitor, visit_generic_arg, generic_args.args); + walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings); +} + +pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>( + visitor: &mut V, + type_binding: &'v TypeBinding<'v>, +) { + visitor.visit_id(type_binding.hir_id); + visitor.visit_ident(type_binding.ident); + visitor.visit_generic_args(type_binding.gen_args); + match type_binding.kind { + TypeBindingKind::Equality { ref term } => match term { + Term::Ty(ref ty) => visitor.visit_ty(ty), + Term::Const(ref c) => visitor.visit_anon_const(c), + }, + TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds), } - visitor.visit_expr(&arm.body); } pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) { @@ -1202,3 +1178,27 @@ pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) { // the right thing to do, should content be added in the future, // would be to walk it. } + +pub fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>, id: HirId) { + for (op, op_sp) in asm.operands { + match op { + InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => { + visitor.visit_expr(expr) + } + InlineAsmOperand::Out { expr, .. } => { + if let Some(expr) = expr { + visitor.visit_expr(expr); + } + } + InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { + visitor.visit_expr(in_expr); + if let Some(out_expr) = out_expr { + visitor.visit_expr(out_expr); + } + } + InlineAsmOperand::Const { anon_const, .. } + | InlineAsmOperand::SymFn { anon_const, .. } => visitor.visit_anon_const(anon_const), + InlineAsmOperand::SymStatic { path, .. } => visitor.visit_qpath(path, id, *op_sp), + } + } +} From c1420974aa02b4b46c46774c9447a5aee4278160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 1 Nov 2022 19:36:25 +0100 Subject: [PATCH 056/482] Revert "ci: Bring back ninja for dist builders" --- src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile | 2 +- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 2 +- src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index bff3f8f21929f..cd86d9fb584fb 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -23,7 +23,6 @@ RUN yum upgrade -y && \ libstdc++-devel.x86_64 \ make \ ncurses-devel \ - ninja-build \ openssl-devel \ patch \ perl \ @@ -65,6 +64,7 @@ ENV RUST_CONFIGURE_ARGS \ --enable-profiler \ --set target.i686-unknown-linux-gnu.linker=clang \ --build=i686-unknown-linux-gnu \ + --set llvm.ninja=false \ --set rust.jemalloc ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 6fdf05aebd6e1..423aba06ccaff 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -23,7 +23,6 @@ RUN yum upgrade -y && \ libstdc++-devel.x86_64 \ make \ ncurses-devel \ - ninja-build \ openssl-devel \ patch \ perl \ @@ -77,6 +76,7 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \ --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \ --set llvm.thin-lto=true \ + --set llvm.ninja=false \ --set rust.jemalloc \ --set rust.use-lld=true \ --set rust.lto=thin diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 15ab3e5bd6e68..9abfd4e973115 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -25,7 +25,6 @@ INC="/rustroot/include:/usr/include" # disable them. BOLT is used for optimizing LLVM. hide_output \ cmake ../llvm \ - -GNinja \ -DCMAKE_C_COMPILER=/rustroot/bin/gcc \ -DCMAKE_CXX_COMPILER=/rustroot/bin/g++ \ -DCMAKE_BUILD_TYPE=Release \ @@ -40,8 +39,8 @@ hide_output \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ -DC_INCLUDE_DIRS="$INC" -hide_output ninja -hide_output ninja install +hide_output make -j$(nproc) +hide_output make install cd ../.. rm -rf llvm-project From e08c697e711566ad7b5e8f54f2e5812b751a738e Mon Sep 17 00:00:00 2001 From: Zhixing Zhang Date: Mon, 31 Oct 2022 17:01:00 -0700 Subject: [PATCH 057/482] fix(generic_const_exprs): Fix predicate inheritance for children of opaque types --- .../src/collect/predicates_of.rs | 31 +++++++++++++++-- .../generic_const_exprs/issue-99705.rs | 33 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-99705.rs diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 2e84e1d016007..5d1ca1cbd2389 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>( } else { if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + let parent_def_id = tcx.hir().get_parent_item(hir_id); + if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() { // In `generics_of` we set the generics' parent to be our parent's parent which means that // we lose out on the predicates of our actual parent if we dont return those predicates here. @@ -439,8 +441,33 @@ pub(super) fn explicit_predicates_of<'tcx>( // parent of generics returned by `generics_of` // // In the above code we want the anon const to have predicates in its param env for `T: Trait` - let item_def_id = tcx.hir().get_parent_item(hir_id); - // In the above code example we would be calling `explicit_predicates_of(Foo)` here + // and we would be calling `explicit_predicates_of(Foo)` here + return tcx.explicit_predicates_of(parent_def_id); + } + + let parent_def_kind = tcx.def_kind(parent_def_id); + if matches!(parent_def_kind, DefKind::OpaqueTy) { + // In `instantiate_identity` we inherit the predicates of our parent. + // However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means + // that we lose out on the predicates of our actual parent if we dont return those predicates here. + // + // + // fn foo() -> impl Iterator::ASSOC }> > { todo!() } + // ^^^^^^^^^^^^^^^^^^^ the def id we are calling + // explicit_predicates_of on + // + // In the above code we want the anon const to have predicates in its param env for `T: Trait`. + // However, the anon const cannot inherit predicates from its parent since it's opaque. + // + // To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent. + + // In the above example this is `foo::{opaque#0}` or `impl Iterator` + let parent_hir_id = tcx.hir().local_def_id_to_hir_id(parent_def_id.def_id); + + // In the above example this is the function `foo` + let item_def_id = tcx.hir().get_parent_item(parent_hir_id); + + // In the above code example we would be calling `explicit_predicates_of(foo)` here return tcx.explicit_predicates_of(item_def_id); } } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs b/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs new file mode 100644 index 0000000000000..75b57b621bb57 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs @@ -0,0 +1,33 @@ +// check-pass +#![crate_type = "lib"] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] +pub trait MyIterator { + type Output; +} + +pub trait Foo { + const ABC: usize; +} + +pub struct IteratorStruct{ + +} + +pub struct Bar { + pub data: [usize; N] +} + +impl MyIterator for IteratorStruct { + type Output = Bar; +} + +pub fn test1() -> impl MyIterator> where [(); T::ABC]: Sized { + IteratorStruct::<{T::ABC}>{} +} + +pub trait Baz{} +impl Baz for Bar {} +pub fn test2() -> impl MyIterator> where [(); T::ABC]: Sized { + IteratorStruct::<{T::ABC}>{} +} From f0af05237eb4996a435b0e4bb32c143a400e3e52 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 26 Oct 2022 20:28:25 -0400 Subject: [PATCH 058/482] Allow use of `-Clto=thin` with `-Ccodegen-units=1` in general The current logic to ignore ThinLTO when `-Ccodegen-units=1` makes sense for local ThinLTO but even in this scenario, a user may still want (non-local) ThinLTO for the purpose of optimizing dependencies into the final crate which is being compiled with 1 CGU. The previous behavior was even more confusing because if you were generating a binary (`--emit=link`), then you would get ThinLTO but if you asked for LLVM IR or bytecode, then it would silently change to using regular LTO. With this change, we only override the defaults for local ThinLTO if you ask for a single output such as LLVM IR or bytecode and in all other cases honor the requested LTO setting. --- compiler/rustc_session/src/config.rs | 14 +++++++------- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_session/src/session.rs | 9 +++------ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index bd1f85a9d0693..b8ad18c64dcf6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -738,7 +738,7 @@ impl Default for Options { actually_rustdoc: false, trimmed_def_paths: TrimmedDefPaths::default(), cli_forced_codegen_units: None, - cli_forced_thinlto_off: false, + cli_forced_local_thinlto_off: false, remap_path_prefix: Vec::new(), real_rust_source_base_dir: None, edition: DEFAULT_EDITION, @@ -1721,7 +1721,7 @@ fn should_override_cgus_and_disable_thinlto( error_format: ErrorOutputType, mut codegen_units: Option, ) -> (bool, Option) { - let mut disable_thinlto = false; + let mut disable_local_thinlto = false; // Issue #30063: if user requests LLVM-related output to one // particular path, disable codegen-units. let incompatible: Vec<_> = output_types @@ -1746,12 +1746,12 @@ fn should_override_cgus_and_disable_thinlto( } early_warn(error_format, "resetting to default -C codegen-units=1"); codegen_units = Some(1); - disable_thinlto = true; + disable_local_thinlto = true; } } _ => { codegen_units = Some(1); - disable_thinlto = true; + disable_local_thinlto = true; } } } @@ -1760,7 +1760,7 @@ fn should_override_cgus_and_disable_thinlto( early_error(error_format, "value for codegen units must be a positive non-zero integer"); } - (disable_thinlto, codegen_units) + (disable_local_thinlto, codegen_units) } fn check_thread_count(unstable_opts: &UnstableOptions, error_format: ErrorOutputType) { @@ -2265,7 +2265,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let output_types = parse_output_types(&unstable_opts, matches, error_format); let mut cg = CodegenOptions::build(matches, error_format); - let (disable_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( + let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( &output_types, matches, error_format, @@ -2508,7 +2508,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { actually_rustdoc: false, trimmed_def_paths: TrimmedDefPaths::default(), cli_forced_codegen_units: codegen_units, - cli_forced_thinlto_off: disable_thinlto, + cli_forced_local_thinlto_off: disable_local_thinlto, remap_path_prefix, real_rust_source_base_dir, edition, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index e93c4138e61b0..f9ee202466f67 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -181,7 +181,7 @@ top_level_options!( #[rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field")] cli_forced_codegen_units: Option [UNTRACKED], #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")] - cli_forced_thinlto_off: bool [UNTRACKED], + cli_forced_local_thinlto_off: bool [UNTRACKED], /// Remap source path prefixes in all output (messages, object files, debug, etc.). remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 6d3cda684a62a..ec0a5b9d0d84f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1018,11 +1018,8 @@ impl Session { return config::Lto::Fat; } config::LtoCli::Thin => { - return if self.opts.cli_forced_thinlto_off { - config::Lto::Fat - } else { - config::Lto::Thin - }; + // The user explicitly asked for ThinLTO + return config::Lto::Thin; } } @@ -1034,7 +1031,7 @@ impl Session { // If processing command line options determined that we're incompatible // with ThinLTO (e.g., `-C lto --emit llvm-ir`) then return that option. - if self.opts.cli_forced_thinlto_off { + if self.opts.cli_forced_local_thinlto_off { return config::Lto::No; } From 0397cef2b9b302c40971b0ea9de2d8c8dbc4fe16 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 2 Nov 2022 14:47:48 +0900 Subject: [PATCH 059/482] return const_error when ty has errors --- .../rustc_hir_analysis/src/astconv/mod.rs | 3 + src/test/ui/consts/issue-103790.rs | 10 +++ src/test/ui/consts/issue-103790.stderr | 65 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/test/ui/consts/issue-103790.rs create mode 100644 src/test/ui/consts/issue-103790.stderr diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 39b178f5976b8..410f294cc1111 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -500,6 +500,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } GenericParamDefKind::Const { has_default } => { let ty = tcx.at(self.span).type_of(param.def_id); + if ty.references_error() { + return tcx.const_error(ty).into(); + } if !infer_args && has_default { tcx.bound_const_param_default(param.def_id) .subst(tcx, substs.unwrap()) diff --git a/src/test/ui/consts/issue-103790.rs b/src/test/ui/consts/issue-103790.rs new file mode 100644 index 0000000000000..ea3cac605b156 --- /dev/null +++ b/src/test/ui/consts/issue-103790.rs @@ -0,0 +1,10 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct S; +//~^ ERROR the name `S` is already used for a generic parameter in this item's generic parameters +//~| ERROR missing generics for struct `S` +//~| ERROR cycle detected when computing type of `S::S` +//~| ERROR cycle detected when computing type of `S` + +fn main() {} diff --git a/src/test/ui/consts/issue-103790.stderr b/src/test/ui/consts/issue-103790.stderr new file mode 100644 index 0000000000000..41b0816dc32af --- /dev/null +++ b/src/test/ui/consts/issue-103790.stderr @@ -0,0 +1,65 @@ +error[E0403]: the name `S` is already used for a generic parameter in this item's generic parameters + --> $DIR/issue-103790.rs:4:29 + | +LL | struct S; + | - ^ already used + | | + | first use of `S` + +error[E0107]: missing generics for struct `S` + --> $DIR/issue-103790.rs:4:32 + | +LL | struct S; + | ^ expected at least 1 generic argument + | +note: struct defined here, with at least 1 generic parameter: `S` + --> $DIR/issue-103790.rs:4:8 + | +LL | struct S; + | ^ ----------- +help: add missing generic argument + | +LL | struct S = { S }>; + | ~~~~ + +error[E0391]: cycle detected when computing type of `S::S` + --> $DIR/issue-103790.rs:4:32 + | +LL | struct S; + | ^ + | + = note: ...which immediately requires computing type of `S::S` again +note: cycle used when computing type of `S` + --> $DIR/issue-103790.rs:4:1 + | +LL | struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0391]: cycle detected when computing type of `S` + --> $DIR/issue-103790.rs:4:1 + | +LL | struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `S::S`... + --> $DIR/issue-103790.rs:4:32 + | +LL | struct S; + | ^ + = note: ...which again requires computing type of `S`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/issue-103790.rs:1:1 + | +LL | / #![feature(generic_const_exprs)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | struct S; +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0391, E0403. +For more information about an error, try `rustc --explain E0107`. From a3824c9c9ddc8cd0affd3ee830a36d172e682c04 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 31 Oct 2022 16:19:36 +0000 Subject: [PATCH 060/482] Simplify astconv item def id handling --- compiler/rustc_hir_analysis/src/astconv/errors.rs | 7 ++----- compiler/rustc_hir_analysis/src/astconv/mod.rs | 9 +++------ compiler/rustc_hir_analysis/src/collect.rs | 4 ++-- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 ++-- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index a9152bdc59787..e6465d641f1e6 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -177,11 +177,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .all_traits() .filter(|trait_def_id| { let viz = self.tcx().visibility(*trait_def_id); - if let Some(def_id) = self.item_def_id() { - viz.is_accessible_from(def_id, self.tcx()) - } else { - viz.is_visible_locally() - } + let def_id = self.item_def_id(); + viz.is_accessible_from(def_id, self.tcx()) }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 410f294cc1111..9dd9bf05540fb 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -54,7 +54,7 @@ pub struct PathSeg(pub DefId, pub usize); pub trait AstConv<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; - fn item_def_id(&self) -> Option; + fn item_def_id(&self) -> DefId; /// Returns predicates in scope of the form `X: Foo`, where `X` /// is a type parameter `X` with the given id `def_id` and T @@ -2082,17 +2082,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("qpath_to_ty: self.item_def_id()={:?}", def_id); - let parent_def_id = def_id - .and_then(|def_id| { - def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) - }) + let parent_def_id = def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) .map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id()); debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id); // If the trait in segment is the same as the trait defining the item, // use the `` syntax in the error. - let is_part_of_self_trait_constraints = def_id == Some(trait_def_id); + let is_part_of_self_trait_constraints = def_id == trait_def_id; let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id); let type_name = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 46db0f74d4d5f..25faacadf3d0c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -379,8 +379,8 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { self.tcx } - fn item_def_id(&self) -> Option { - Some(self.item_def_id) + fn item_def_id(&self) -> DefId { + self.item_def_id } fn get_type_parameter_bounds( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0c600daf4459e..c36c01e1b46d0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -194,8 +194,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { self.tcx } - fn item_def_id(&self) -> Option { - None + fn item_def_id(&self) -> DefId { + self.body_id.owner.to_def_id() } fn get_type_parameter_bounds( From 59311fbabc5c8b5d2f391a99ff47e55b2500fc93 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 2 Nov 2022 16:51:37 +0100 Subject: [PATCH 061/482] Fix merge of attributes for reexports of local items --- src/librustdoc/clean/mod.rs | 26 +++++++++++++++++++++----- src/librustdoc/visit_ast.rs | 29 ++++++++++++++++------------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1ce0d1e4ffd02..ad4ad4104e104 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -74,12 +74,12 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - items.extend(doc.items.iter().flat_map(|(item, renamed)| { + items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| { // First, lower everything other than imports. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); } - let v = clean_maybe_renamed_item(cx, item, *renamed); + let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id); for item in &v { if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) { inserted.insert((item.type_(), name)); @@ -87,7 +87,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); - items.extend(doc.items.iter().flat_map(|(item, renamed)| { + items.extend(doc.items.iter().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); @@ -1911,6 +1911,7 @@ fn clean_maybe_renamed_item<'tcx>( cx: &mut DocContext<'tcx>, item: &hir::Item<'tcx>, renamed: Option, + import_id: Option, ) -> Vec { use hir::ItemKind; @@ -1987,8 +1988,23 @@ fn clean_maybe_renamed_item<'tcx>( } _ => unreachable!("not yet converted"), }; - - vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] + if let Some(import_id) = import_id { + let (attrs, cfg) = inline::merge_attrs( + cx, + Some(cx.tcx.parent_module(import_id).to_def_id()), + inline::load_attrs(cx, def_id), + Some(inline::load_attrs(cx, cx.tcx.hir().local_def_id(import_id).to_def_id())), + ); + vec![Item::from_def_id_and_attrs_and_parts( + def_id, + Some(name), + kind, + Box::new(attrs), + cfg, + )] + } else { + vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] + } }) } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 7ee7eb25e0d90..c788b9f4093fe 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -25,8 +25,8 @@ pub(crate) struct Module<'hir> { pub(crate) where_inner: Span, pub(crate) mods: Vec>, pub(crate) id: hir::HirId, - // (item, renamed) - pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option)>, + // (item, renamed, import_id) + pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option, Option)>, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, } @@ -93,6 +93,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::CRATE_HIR_ID, self.cx.tcx.hir().root_module(), self.cx.tcx.crate_name(LOCAL_CRATE), + None, ); // `#[macro_export] macro_rules!` items are reexported at the top level of the @@ -113,7 +114,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if self.cx.tcx.has_attr(def_id, sym::macro_export) { if inserted.insert(def_id) { let item = self.cx.tcx.hir().expect_item(local_def_id); - top_level_module.items.push((item, None)); + top_level_module.items.push((item, None, None)); } } } @@ -155,6 +156,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { id: hir::HirId, m: &'tcx hir::Mod<'tcx>, name: Symbol, + parent_id: Option, ) -> Module<'tcx> { let mut om = Module::new(name, id, m.spans.inner_span); let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id(); @@ -166,7 +168,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { continue; } - self.visit_item(item, None, &mut om); + self.visit_item(item, None, &mut om, parent_id); } for &i in m.item_ids { let item = self.cx.tcx.hir().item(i); @@ -174,7 +176,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // Later passes in rustdoc will de-duplicate by name and kind, so if glob- // imported items appear last, then they'll be the ones that get discarded. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { - self.visit_item(item, None, &mut om); + self.visit_item(item, None, &mut om, parent_id); } } self.inside_public_path = orig_inside_public_path; @@ -247,14 +249,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let prev = mem::replace(&mut self.inlining, true); for &i in m.item_ids { let i = self.cx.tcx.hir().item(i); - self.visit_item(i, None, om); + self.visit_item(i, None, om, Some(id)); } self.inlining = prev; true } Node::Item(it) if !glob => { let prev = mem::replace(&mut self.inlining, true); - self.visit_item(it, renamed, om); + self.visit_item(it, renamed, om, Some(id)); self.inlining = prev; true } @@ -275,6 +277,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { item: &'tcx hir::Item<'_>, renamed: Option, om: &mut Module<'tcx>, + parent_id: Option, ) { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); @@ -330,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - om.items.push((item, renamed)) + om.items.push((item, renamed, parent_id)) } hir::ItemKind::Macro(ref macro_def, _) => { // `#[macro_export] macro_rules!` items are handled separately in `visit()`, @@ -349,11 +352,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export); if is_macro_2_0 || nonexported || self.inlining { - om.items.push((item, renamed)); + om.items.push((item, renamed, None)); } } hir::ItemKind::Mod(ref m) => { - om.mods.push(self.visit_mod_contents(item.hir_id(), m, name)); + om.mods.push(self.visit_mod_contents(item.hir_id(), m, name, parent_id)); } hir::ItemKind::Fn(..) | hir::ItemKind::ExternCrate(..) @@ -364,19 +367,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Static(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)), + | hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed, parent_id)), hir::ItemKind::Const(..) => { // Underscore constants do not correspond to a nameable item and // so are never useful in documentation. if name != kw::Underscore { - om.items.push((item, renamed)); + om.items.push((item, renamed, parent_id)); } } hir::ItemKind::Impl(impl_) => { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. if !self.inlining && impl_.of_trait.is_none() { - om.items.push((item, None)); + om.items.push((item, None, None)); } } } From 0847c8be677ecc241f32da99691b3c481cc1ec92 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 2 Nov 2022 16:55:55 +0100 Subject: [PATCH 062/482] Add regression test for doc of reexport of local items --- src/test/rustdoc/local-reexport-doc.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/rustdoc/local-reexport-doc.rs diff --git a/src/test/rustdoc/local-reexport-doc.rs b/src/test/rustdoc/local-reexport-doc.rs new file mode 100644 index 0000000000000..1c8468008dd0a --- /dev/null +++ b/src/test/rustdoc/local-reexport-doc.rs @@ -0,0 +1,16 @@ +// This test ensures that the reexports of local items also get the doc from +// the reexport. + +#![crate_name = "foo"] + +// @has 'foo/fn.g.html' +// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' \ +// 'outer module inner module' + +mod inner_mod { + /// inner module + pub fn g() {} +} + +/// outer module +pub use inner_mod::g; From e5cab7f26957cfe6b774d839cac7be96ae3d18fa Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 2 Nov 2022 10:10:44 -0700 Subject: [PATCH 063/482] rustdoc: remove unused mobile CSS `.rustdoc { padding-top: 0 }` When this rule was added in dd437ee6ed81f85c715bf415d261feca484bb39f, as `body { padding-top: 0 }`, the desktop body tag had non-zero top padding. This padding was removed in 135281ed1525db15edd8ebd092aa10aa40df2386. This rule no longer overrides a rule in rustdoc's desktop styles, and also doesn't override the UA stylesheet, since the [HTML standard] has only margin, not padding, on the page body. [HTML standard]: https://html.spec.whatwg.org/multipage/rendering.html#the-page --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 360b6b9832a55..d6f2b02afd8f8 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1677,7 +1677,6 @@ in storage.js } .rustdoc { - padding-top: 0px; /* Sidebar should overlay main content, rather than pushing main content to the right. Turn off `display: flex` on the body element. */ display: block; From 4ed8501c6e09045c329a2f2437c1859c76673dd3 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Sun, 23 Oct 2022 15:23:04 -0500 Subject: [PATCH 064/482] Fix x86_64-apple-ios target to use the correct target_abi --- compiler/rustc_target/src/spec/apple/tests.rs | 15 ++++++++++++++ .../rustc_target/src/spec/apple_sdk_base.rs | 20 +++++++++++++------ .../rustc_target/src/spec/x86_64_apple_ios.rs | 2 +- 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 compiler/rustc_target/src/spec/apple/tests.rs diff --git a/compiler/rustc_target/src/spec/apple/tests.rs b/compiler/rustc_target/src/spec/apple/tests.rs new file mode 100644 index 0000000000000..23bfb95c1985b --- /dev/null +++ b/compiler/rustc_target/src/spec/apple/tests.rs @@ -0,0 +1,15 @@ +use crate::spec::{aarch64_apple_ios_sim, aarch64_apple_watchos_sim, x86_64_apple_ios}; + +#[test] +fn simulator_targets_set_abi() { + let all_sim_targets = [ + x86_64_apple_ios::target(), + aarch64_apple_ios_sim::target(), + aarch64_apple_watchos_sim::target(), + // TODO: x86_64-apple-tvos and x86_64-apple-watchos-sim + ]; + + for target in all_sim_targets { + assert_eq!(target.abi, "sim") + } +} diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index 49e302676a7b1..f920ce8444f72 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -1,6 +1,10 @@ use crate::spec::{cvs, TargetOptions}; use std::borrow::Cow; +#[cfg(test)] +#[path = "apple/tests.rs"] +mod tests; + use Arch::*; #[allow(non_camel_case_types)] #[derive(Copy, Clone)] @@ -12,6 +16,7 @@ pub enum Arch { Arm64_32, I386, X86_64, + X86_64_sim, X86_64_macabi, Arm64_macabi, Arm64_sim, @@ -25,7 +30,7 @@ fn target_arch_name(arch: Arch) -> &'static str { Arm64 | Arm64_macabi | Arm64_sim => "arm64", Arm64_32 => "arm64_32", I386 => "i386", - X86_64 | X86_64_macabi => "x86_64", + X86_64 | X86_64_sim | X86_64_macabi => "x86_64", } } @@ -33,7 +38,9 @@ fn target_abi(arch: Arch) -> &'static str { match arch { Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", X86_64_macabi | Arm64_macabi => "macabi", - Arm64_sim => "sim", + // x86_64-apple-ios is a simulator target, even though it isn't + // declared that way in the target like the other ones... + Arm64_sim | X86_64_sim => "sim", } } @@ -45,7 +52,7 @@ fn target_cpu(arch: Arch) -> &'static str { Arm64 => "apple-a7", Arm64_32 => "apple-s4", I386 => "yonah", - X86_64 => "core2", + X86_64 | X86_64_sim => "core2", X86_64_macabi => "core2", Arm64_macabi => "apple-a12", Arm64_sim => "apple-a12", @@ -54,7 +61,7 @@ fn target_cpu(arch: Arch) -> &'static str { fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> { match arch { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | Arm64_sim => { + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | X86_64_sim | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], @@ -62,11 +69,12 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> { } pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { + let abi = target_abi(arch); TargetOptions { - abi: target_abi(arch).into(), + abi: abi.into(), cpu: target_cpu(arch).into(), link_env_remove: link_env_remove(arch), has_thread_local: false, - ..super::apple_base::opts(os, target_arch_name(arch), target_abi(arch)) + ..super::apple_base::opts(os, target_arch_name(arch), abi) } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index e6143025d6d2c..db23f01c23326 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -2,7 +2,7 @@ use super::apple_sdk_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("ios", Arch::X86_64); + let base = opts("ios", Arch::X86_64_sim); let llvm_target = super::apple_base::ios_sim_llvm_target("x86_64"); Target { From 84b40d1f86ca76776b458406264f14dff9705774 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Sun, 23 Oct 2022 15:33:01 -0500 Subject: [PATCH 065/482] Fix x86_64-apple-tvos target to use the correct target_abi --- compiler/rustc_target/src/spec/apple/tests.rs | 8 ++++++-- compiler/rustc_target/src/spec/x86_64_apple_tvos.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/spec/apple/tests.rs b/compiler/rustc_target/src/spec/apple/tests.rs index 23bfb95c1985b..b45e6e309c119 100644 --- a/compiler/rustc_target/src/spec/apple/tests.rs +++ b/compiler/rustc_target/src/spec/apple/tests.rs @@ -1,12 +1,16 @@ -use crate::spec::{aarch64_apple_ios_sim, aarch64_apple_watchos_sim, x86_64_apple_ios}; +use crate::spec::{ + aarch64_apple_ios_sim, aarch64_apple_watchos_sim, x86_64_apple_ios, x86_64_apple_tvos, +}; #[test] fn simulator_targets_set_abi() { let all_sim_targets = [ x86_64_apple_ios::target(), + x86_64_apple_tvos::target(), aarch64_apple_ios_sim::target(), + // Note: There is currently no ARM64 tvOS simulator target aarch64_apple_watchos_sim::target(), - // TODO: x86_64-apple-tvos and x86_64-apple-watchos-sim + // TODO: x86_64-apple-watchos-sim ]; for target in all_sim_targets { diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index 3d54da0867cf7..c1fd8e1c8b90a 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -2,7 +2,7 @@ use super::apple_sdk_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("tvos", Arch::X86_64); + let base = opts("tvos", Arch::X86_64_sim); Target { llvm_target: "x86_64-apple-tvos".into(), pointer_width: 64, From d309784e60e32262b976ccd747aa44b0b3b71146 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Sun, 23 Oct 2022 15:41:07 -0500 Subject: [PATCH 066/482] Fix x86_64-apple-watchos-sim target to use the correct target_abi --- compiler/rustc_target/src/spec/apple/tests.rs | 3 ++- compiler/rustc_target/src/spec/apple_sdk_base.rs | 1 + compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/apple/tests.rs b/compiler/rustc_target/src/spec/apple/tests.rs index b45e6e309c119..d062b36742d60 100644 --- a/compiler/rustc_target/src/spec/apple/tests.rs +++ b/compiler/rustc_target/src/spec/apple/tests.rs @@ -1,5 +1,6 @@ use crate::spec::{ aarch64_apple_ios_sim, aarch64_apple_watchos_sim, x86_64_apple_ios, x86_64_apple_tvos, + x86_64_apple_watchos_sim, }; #[test] @@ -7,10 +8,10 @@ fn simulator_targets_set_abi() { let all_sim_targets = [ x86_64_apple_ios::target(), x86_64_apple_tvos::target(), + x86_64_apple_watchos_sim::target(), aarch64_apple_ios_sim::target(), // Note: There is currently no ARM64 tvOS simulator target aarch64_apple_watchos_sim::target(), - // TODO: x86_64-apple-watchos-sim ]; for target in all_sim_targets { diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index f920ce8444f72..148031b156976 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -15,6 +15,7 @@ pub enum Arch { Arm64, Arm64_32, I386, + #[allow(dead_code)] // Some targets don't use this enum... X86_64, X86_64_sim, X86_64_macabi, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs index e499b1985e761..550566b2aa754 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -2,7 +2,7 @@ use super::apple_sdk_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::X86_64); + let base = opts("watchos", Arch::X86_64_sim); let arch = "x86_64"; let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); From f5766aa25eaceae59c3bf654c31b63587f42d54c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 2 Nov 2022 23:17:12 +0000 Subject: [PATCH 067/482] Update cargo 14 commits in 7e484fc1a766f56dbc95380f45719698e0c82749..810cbad9a123ad4ee0a55a96171b8f8478ff1c03 2022-10-27 15:20:57 +0000 to 2022-11-02 21:04:31 +0000 - Update curl-sys (rust-lang/cargo#11326) - Mention fix on build script deadlock (rust-lang/cargo#11325) - Make cargo forward pre-existing CARGO if set (rust-lang/cargo#11285) - Clean up workspace dependencies after cargo remove (rust-lang/cargo#11242) - Update the outdated link for rust-semverver (rust-lang/cargo#11322) - Fix broken link to compilation entry point (rust-lang/cargo#11317) - Only remove fingerprints and build script artifacts of the requested package (rust-lang/cargo#10621) - Newer anyhow features are required (rust-lang/cargo#11316) - Clean stale git temp files (rust-lang/cargo#11308) - Report crate size on package and publish (rust-lang/cargo#11270) - add a note that some warnings (and/or errors) can be auto-fixed (rust-lang/cargo#10989) - Update libcurl (rust-lang/cargo#11307) - artifact deps shoud works when target field specified coexists with `optional = true` (rust-lang/cargo#11183) - Fix singular verb in tests page (rust-lang/cargo#11300) --- Cargo.lock | 8 ++++---- src/tools/cargo | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33b1299976f3e..c2b460d9a857e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" dependencies = [ "curl-sys", "libc", @@ -1051,9 +1051,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.55+curl-7.83.1" +version = "0.4.59+curl-7.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" +checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407" dependencies = [ "cc", "libc", diff --git a/src/tools/cargo b/src/tools/cargo index 7e484fc1a766f..810cbad9a123a 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 7e484fc1a766f56dbc95380f45719698e0c82749 +Subproject commit 810cbad9a123ad4ee0a55a96171b8f8478ff1c03 From 4612e93658bea1e76c41461f97df6d0897f97f0c Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Wed, 2 Nov 2022 14:54:49 -0700 Subject: [PATCH 068/482] Ban dashes in miropt test file names --- src/bootstrap/test.rs | 3 + ..._of_reborrow.SimplifyCfg-initial.after.mir | 542 +++++++++--------- ...row_and_cast.SimplifyCfg-initial.after.mir | 68 +-- .../mir-opt/{address-of.rs => address_of.rs} | 0 ...main.SimplifyCfg-elaborate-drops.after.mir | 82 +-- ...mporary.rs => array_index_is_temporary.rs} | 0 .../issue_101867.main.built.after.mir | 58 +- .../{issue-101867.rs => issue_101867.rs} | 0 .../building/issue_49232.main.built.after.mir | 76 +-- .../{issue-49232.rs => issue_49232.rs} | 0 ...ceiver_ptr_mutability.main.built.after.mir | 130 ++--- ...tability.rs => receiver_ptr_mutability.rs} | 0 .../simple_match.match_bool.built.after.mir | 20 +- .../{simple-match.rs => simple_match.rs} | 0 ...d[0].SimplifyCfg-elaborate-drops.after.mir | 20 +- ...motion_extern_static.BAR.PromoteTemps.diff | 60 +- ...romotion_extern_static.BOP.built.after.mir | 20 +- ...d[0].SimplifyCfg-elaborate-drops.after.mir | 20 +- ...motion_extern_static.FOO.PromoteTemps.diff | 60 +- ...ic.rs => const_promotion_extern_static.rs} | 0 ...l_flow_simplification.hello.ConstProp.diff | 18 +- ...simplification.hello.PreCodegen.before.mir | 4 +- ...tion.rs => control_flow_simplification.rs} | 0 .../issue_66971.main.ConstProp.diff | 38 +- .../{issue-66971.rs => issue_66971.rs} | 0 .../issue_67019.main.ConstProp.diff | 40 +- .../{issue-67019.rs => issue_67019.rs} | 0 ....match_tuple.SimplifyCfg-initial.after.mir | 88 +-- .../{exponential-or.rs => exponential_or.rs} | 0 .../{fn-ptr-shim.rs => fn_ptr_shim.rs} | 0 ...anup.main-{closure#0}.generator_drop.0.mir | 58 +- ...p-cleanup.rs => generator_drop_cleanup.rs} | 0 ...main-{closure#0}.StateTransform.before.mir | 122 ++-- ...nd.rs => generator_storage_dead_unwind.rs} | 0 ...ny.main-{closure#0}.generator_resume.0.mir | 84 +-- .../{generator-tiny.rs => generator_tiny.rs} | 0 ...t_opt_bool.SimplifyComparisonIntegral.diff | 24 +- ...opt_floats.SimplifyComparisonIntegral.diff | 32 +- ...comparison.SimplifyComparisonIntegral.diff | 76 +-- ...t.opt_char.SimplifyComparisonIntegral.diff | 42 +- ...int.opt_i8.SimplifyComparisonIntegral.diff | 42 +- ...ltiple_ifs.SimplifyComparisonIntegral.diff | 76 +-- ...t_negative.SimplifyComparisonIntegral.diff | 42 +- ...nt.opt_u32.SimplifyComparisonIntegral.diff | 42 +- ...f-condition-int.rs => if_condition_int.rs} | 0 .../inline/asm_unwind.main.Inline.diff | 34 +- .../inline/{asm-unwind.rs => asm_unwind.rs} | 0 .../caller_with_trivial_bound.foo.Inline.diff | 22 +- ...-bound.rs => caller_with_trivial_bound.rs} | 0 .../inline/dyn_trait.get_query.Inline.diff | 74 +-- .../inline/dyn_trait.mk_cycle.Inline.diff | 18 +- .../inline/{dyn-trait.rs => dyn_trait.rs} | 0 .../dyn_trait.try_execute_query.Inline.diff | 42 +- .../inline_any_operand.bar.Inline.after.mir | 64 +-- ...e-any-operand.rs => inline_any_operand.rs} | 0 .../{inline-async.rs => inline_async.rs} | 0 .../inline_closure.foo.Inline.after.mir | 78 +-- .../{inline-closure.rs => inline_closure.rs} | 0 ...e_closure_borrows_arg.foo.Inline.after.mir | 88 +-- ...s-arg.rs => inline_closure_borrows_arg.rs} | 0 ...line_closure_captures.foo.Inline.after.mir | 110 ++-- ...captures.rs => inline_closure_captures.rs} | 0 ...patibility.inlined_no_sanitize.Inline.diff | 18 +- ...ibility.inlined_target_feature.Inline.diff | 18 +- ...ibility.not_inlined_c_variadic.Inline.diff | 18 +- ...bility.not_inlined_no_sanitize.Inline.diff | 16 +- ...ity.not_inlined_target_feature.Inline.diff | 16 +- ...mpatibility.rs => inline_compatibility.rs} | 0 .../inline/inline_cycle.one.Inline.diff | 26 +- .../{inline-cycle.rs => inline_cycle.rs} | 0 .../inline/inline_cycle.two.Inline.diff | 66 +-- .../inline_cycle_generic.main.Inline.diff | 28 +- ...cle-generic.rs => inline_cycle_generic.rs} | 0 .../inline/inline_diverging.f.Inline.diff | 18 +- .../inline/inline_diverging.g.Inline.diff | 46 +- .../inline/inline_diverging.h.Inline.diff | 58 +- ...nline-diverging.rs => inline_diverging.rs} | 0 .../inline/inline_generator.main.Inline.diff | 164 +++--- ...nline-generator.rs => inline_generator.rs} | 0 ...inline_instruction_set.default.Inline.diff | 38 +- ...ction-set.rs => inline_instruction_set.rs} | 0 .../inline_instruction_set.t32.Inline.diff | 40 +- .../inline_into_box_place.main.Inline.diff | 68 +-- ...-box-place.rs => inline_into_box_place.rs} | 0 .../inline_options.main.Inline.after.mir | 54 +- .../{inline-options.rs => inline_options.rs} | 0 .../inline/inline_retag.bar.Inline.after.mir | 112 ++-- .../{inline-retag.rs => inline_retag.rs} | 0 .../inline/inline_shims.clone.Inline.diff | 20 +- .../inline/inline_shims.drop.Inline.diff | 48 +- .../{inline-shims.rs => inline_shims.rs} | 0 .../inline_specialization.main.Inline.diff | 22 +- ...ialization.rs => inline_specialization.rs} | 0 ...trait-method.rs => inline_trait_method.rs} | 0 .../inline_trait_method.test.Inline.after.mir | 18 +- ...t-method_2.rs => inline_trait_method_2.rs} | 0 ...line_trait_method_2.test2.Inline.after.mir | 38 +- ...67_inline_as_ref_as_mut.a.Inline.after.mir | 32 +- ...67_inline_as_ref_as_mut.b.Inline.after.mir | 32 +- ...67_inline_as_ref_as_mut.c.Inline.after.mir | 24 +- ...67_inline_as_ref_as_mut.d.Inline.after.mir | 24 +- ...rs => issue_58867_inline_as_ref_as_mut.rs} | 0 ...ine_scopes_parenting.main.Inline.after.mir | 60 +- ...=> issue_76997_inline_scopes_parenting.rs} | 0 .../inline/issue_78442.bar.Inline.diff | 72 +-- .../inline/issue_78442.bar.RevealAll.diff | 56 +- .../inline/{issue-78442.rs => issue_78442.rs} | 0 ...-recursion.rs => polymorphic_recursion.rs} | 0 .../mir-opt/issue_101973.inner.ConstProp.diff | 122 ++-- .../{issue-101973.rs => issue_101973.rs} | 0 ...e_38669.main.SimplifyCfg-initial.after.mir | 56 +- .../{issue-38669.rs => issue_38669.rs} | 0 .../issue_41110.main.ElaborateDrops.after.mir | 66 +-- .../{issue-41110.rs => issue_41110.rs} | 0 .../issue_41110.test.ElaborateDrops.after.mir | 92 +-- .../{issue-41697.rs => issue_41697.rs} | 0 ...nt#0}.SimplifyCfg-promote-consts.after.mir | 18 +- .../issue_41888.main.ElaborateDrops.after.mir | 146 ++--- .../{issue-41888.rs => issue_41888.rs} | 0 .../{issue-62289.rs => issue_62289.rs} | 0 ...issue_62289.test.ElaborateDrops.before.mir | 120 ++-- .../mir-opt/issue_72181.bar.built.after.mir | 16 +- .../mir-opt/issue_72181.foo.built.after.mir | 28 +- .../mir-opt/issue_72181.main.built.after.mir | 72 +-- .../{issue-72181.rs => issue_72181.rs} | 0 .../mir-opt/issue_72181_1.f.built.after.mir | 26 +- .../issue_72181_1.main.built.after.mir | 56 +- .../{issue-72181-1.rs => issue_72181_1.rs} | 0 .../issue_73223.main.SimplifyArmIdentity.diff | 80 +-- .../{issue-73223.rs => issue_73223.rs} | 0 .../mir-opt/issue_78192.f.InstCombine.diff | 36 +- .../{issue-78192.rs => issue_78192.rs} | 0 .../mir-opt/issue_91633.bar.built.after.mir | 32 +- .../mir-opt/issue_91633.foo.built.after.mir | 56 +- .../mir-opt/issue_91633.fun.built.after.mir | 40 +- .../mir-opt/issue_91633.hey.built.after.mir | 36 +- .../{issue-91633.rs => issue_91633.rs} | 0 .../mir-opt/issue_99325.main.built.after.mir | 48 +- .../{issue-99325.rs => issue_99325.rs} | 0 ...ue_59352.num_to_digit.PreCodegen.after.mir | 54 +- .../issues/{issue-59352.rs => issue_59352.rs} | 0 ...e_75439.foo.MatchBranchSimplification.diff | 82 +-- .../issues/{issue-75439.rs => issue_75439.rs} | 0 ...fg-initial.after-ElaborateDrops.after.diff | 290 +++++----- ...atch-arm-scopes.rs => match_arm_scopes.rs} | 0 ...imes-basic.rs => named_lifetimes_basic.rs} | 0 .../nll/named_lifetimes_basic.use_x.nll.0.mir | 30 +- ...egion_subtyping_basic.main.nll.0.32bit.mir | 110 ++-- ...egion_subtyping_basic.main.nll.0.64bit.mir | 110 ++-- ...ing-basic.rs => region_subtyping_basic.rs} | 0 ...ant.rs => no_drop_for_inactive_variant.rs} | 0 ...wrap.SimplifyCfg-elaborate-drops.after.mir | 38 +- ..._after_call.main.ElaborateDrops.before.mir | 48 +- ...call.rs => no_spurious_drop_after_call.rs} | 0 .../nrvo_simple.nrvo.RenameReturnPlace.diff | 58 +- .../{nrvo-simple.rs => nrvo_simple.rs} | 0 ...main.SimplifyCfg-elaborate-drops.after.mir | 78 +-- ...igned.rs => packed_struct_drop_aligned.rs} | 0 ...ever_const.no_codegen.PreCodegen.after.mir | 4 +- ...e-never-const.rs => remove_never_const.rs} | 0 .../{simplify-arm.rs => simplify_arm.rs} | 0 ...m-identity.rs => simplify_arm_identity.rs} | 0 .../simplify_locals.c.SimplifyLocals.diff | 40 +- .../simplify_locals.d1.SimplifyLocals.diff | 16 +- .../simplify_locals.d2.SimplifyLocals.diff | 40 +- ...ify_locals.expose_addr.SimplifyLocals.diff | 24 +- .../simplify_locals.r.SimplifyLocals.diff | 32 +- ...{simplify-locals.rs => simplify_locals.rs} | 0 .../simplify_locals.t1.SimplifyLocals.diff | 22 +- .../simplify_locals.t2.SimplifyLocals.diff | 22 +- .../simplify_locals.t3.SimplifyLocals.diff | 30 +- .../simplify_locals.t4.SimplifyLocals.diff | 22 +- ..._locals_fixedpoint.foo.SimplifyLocals.diff | 78 +-- ...point.rs => simplify_locals_fixedpoint.rs} | 0 ...ves_unused_consts.main.SimplifyLocals.diff | 176 +++--- ... simplify_locals_removes_unused_consts.rs} | 0 ...discriminant_reads.map.SimplifyLocals.diff | 58 +- ...cals_removes_unused_discriminant_reads.rs} | 0 ...{slice-drop-shim.rs => slice_drop_shim.rs} | 0 .../spanview_block.main.built.after.html | 2 +- .../{spanview-block.rs => spanview_block.rs} | 0 .../spanview_statement.main.built.after.html | 4 +- ...iew-statement.rs => spanview_statement.rs} | 0 .../spanview_terminator.main.built.after.html | 2 +- ...w-terminator.rs => spanview_terminator.rs} | 0 .../tls_access.main.PreCodegen.after.mir | 34 +- .../mir-opt/{tls-access.rs => tls_access.rs} | 0 ...num.process_never.SimplifyLocals.after.mir | 10 +- ...enum.process_void.SimplifyLocals.after.mir | 14 +- ...ninhabited-enum.rs => uninhabited_enum.rs} | 0 ...tem_types.E-V-{constant#0}.built.after.mir | 6 +- ...pes.Test-X-{constructor#0}.built.after.mir | 10 +- ...al-item-types.rs => unusual_item_types.rs} | 0 ...mpl#0}-ASSOCIATED_CONSTANT.built.after.mir | 10 +- .../{while-storage.rs => while_storage.rs} | 0 ...le_storage.while_loop.PreCodegen.after.mir | 54 +- src/tools/tidy/src/main.rs | 3 +- src/tools/tidy/src/mir_opt_tests.rs | 37 +- 198 files changed, 3299 insertions(+), 3262 deletions(-) rename src/test/mir-opt/{address-of.rs => address_of.rs} (100%) rename src/test/mir-opt/{array-index-is-temporary.rs => array_index_is_temporary.rs} (100%) rename src/test/mir-opt/building/{issue-101867.rs => issue_101867.rs} (100%) rename src/test/mir-opt/building/{issue-49232.rs => issue_49232.rs} (100%) rename src/test/mir-opt/building/{receiver-ptr-mutability.rs => receiver_ptr_mutability.rs} (100%) rename src/test/mir-opt/building/{simple-match.rs => simple_match.rs} (100%) rename src/test/mir-opt/{const-promotion-extern-static.rs => const_promotion_extern_static.rs} (100%) rename src/test/mir-opt/const_prop/{control-flow-simplification.rs => control_flow_simplification.rs} (100%) rename src/test/mir-opt/const_prop/{issue-66971.rs => issue_66971.rs} (100%) rename src/test/mir-opt/const_prop/{issue-67019.rs => issue_67019.rs} (100%) rename src/test/mir-opt/{exponential-or.rs => exponential_or.rs} (100%) rename src/test/mir-opt/{fn-ptr-shim.rs => fn_ptr_shim.rs} (100%) rename src/test/mir-opt/{generator-drop-cleanup.rs => generator_drop_cleanup.rs} (100%) rename src/test/mir-opt/{generator-storage-dead-unwind.rs => generator_storage_dead_unwind.rs} (100%) rename src/test/mir-opt/{generator-tiny.rs => generator_tiny.rs} (100%) rename src/test/mir-opt/{if-condition-int.rs => if_condition_int.rs} (100%) rename src/test/mir-opt/inline/{asm-unwind.rs => asm_unwind.rs} (100%) rename src/test/mir-opt/inline/{caller-with-trivial-bound.rs => caller_with_trivial_bound.rs} (100%) rename src/test/mir-opt/inline/{dyn-trait.rs => dyn_trait.rs} (100%) rename src/test/mir-opt/inline/{inline-any-operand.rs => inline_any_operand.rs} (100%) rename src/test/mir-opt/inline/{inline-async.rs => inline_async.rs} (100%) rename src/test/mir-opt/inline/{inline-closure.rs => inline_closure.rs} (100%) rename src/test/mir-opt/inline/{inline-closure-borrows-arg.rs => inline_closure_borrows_arg.rs} (100%) rename src/test/mir-opt/inline/{inline-closure-captures.rs => inline_closure_captures.rs} (100%) rename src/test/mir-opt/inline/{inline-compatibility.rs => inline_compatibility.rs} (100%) rename src/test/mir-opt/inline/{inline-cycle.rs => inline_cycle.rs} (100%) rename src/test/mir-opt/inline/{inline-cycle-generic.rs => inline_cycle_generic.rs} (100%) rename src/test/mir-opt/inline/{inline-diverging.rs => inline_diverging.rs} (100%) rename src/test/mir-opt/inline/{inline-generator.rs => inline_generator.rs} (100%) rename src/test/mir-opt/inline/{inline-instruction-set.rs => inline_instruction_set.rs} (100%) rename src/test/mir-opt/inline/{inline-into-box-place.rs => inline_into_box_place.rs} (100%) rename src/test/mir-opt/inline/{inline-options.rs => inline_options.rs} (100%) rename src/test/mir-opt/inline/{inline-retag.rs => inline_retag.rs} (100%) rename src/test/mir-opt/inline/{inline-shims.rs => inline_shims.rs} (100%) rename src/test/mir-opt/inline/{inline-specialization.rs => inline_specialization.rs} (100%) rename src/test/mir-opt/inline/{inline-trait-method.rs => inline_trait_method.rs} (100%) rename src/test/mir-opt/inline/{inline-trait-method_2.rs => inline_trait_method_2.rs} (100%) rename src/test/mir-opt/inline/{issue-58867-inline-as-ref-as-mut.rs => issue_58867_inline_as_ref_as_mut.rs} (100%) rename src/test/mir-opt/inline/{issue-76997-inline-scopes-parenting.rs => issue_76997_inline_scopes_parenting.rs} (100%) rename src/test/mir-opt/inline/{issue-78442.rs => issue_78442.rs} (100%) rename src/test/mir-opt/inline/{polymorphic-recursion.rs => polymorphic_recursion.rs} (100%) rename src/test/mir-opt/{issue-101973.rs => issue_101973.rs} (100%) rename src/test/mir-opt/{issue-38669.rs => issue_38669.rs} (100%) rename src/test/mir-opt/{issue-41110.rs => issue_41110.rs} (100%) rename src/test/mir-opt/{issue-41697.rs => issue_41697.rs} (100%) rename src/test/mir-opt/{issue-41888.rs => issue_41888.rs} (100%) rename src/test/mir-opt/{issue-62289.rs => issue_62289.rs} (100%) rename src/test/mir-opt/{issue-72181.rs => issue_72181.rs} (100%) rename src/test/mir-opt/{issue-72181-1.rs => issue_72181_1.rs} (100%) rename src/test/mir-opt/{issue-73223.rs => issue_73223.rs} (100%) rename src/test/mir-opt/{issue-78192.rs => issue_78192.rs} (100%) rename src/test/mir-opt/{issue-91633.rs => issue_91633.rs} (100%) rename src/test/mir-opt/{issue-99325.rs => issue_99325.rs} (100%) rename src/test/mir-opt/issues/{issue-59352.rs => issue_59352.rs} (100%) rename src/test/mir-opt/issues/{issue-75439.rs => issue_75439.rs} (100%) rename src/test/mir-opt/{match-arm-scopes.rs => match_arm_scopes.rs} (100%) rename src/test/mir-opt/nll/{named-lifetimes-basic.rs => named_lifetimes_basic.rs} (100%) rename src/test/mir-opt/nll/{region-subtyping-basic.rs => region_subtyping_basic.rs} (100%) rename src/test/mir-opt/{no-drop-for-inactive-variant.rs => no_drop_for_inactive_variant.rs} (100%) rename src/test/mir-opt/{no-spurious-drop-after-call.rs => no_spurious_drop_after_call.rs} (100%) rename src/test/mir-opt/{nrvo-simple.rs => nrvo_simple.rs} (100%) rename src/test/mir-opt/{packed-struct-drop-aligned.rs => packed_struct_drop_aligned.rs} (100%) rename src/test/mir-opt/{remove-never-const.rs => remove_never_const.rs} (100%) rename src/test/mir-opt/{simplify-arm.rs => simplify_arm.rs} (100%) rename src/test/mir-opt/{simplify-arm-identity.rs => simplify_arm_identity.rs} (100%) rename src/test/mir-opt/{simplify-locals.rs => simplify_locals.rs} (100%) rename src/test/mir-opt/{simplify-locals-fixedpoint.rs => simplify_locals_fixedpoint.rs} (100%) rename src/test/mir-opt/{simplify-locals-removes-unused-consts.rs => simplify_locals_removes_unused_consts.rs} (100%) rename src/test/mir-opt/{simplify-locals-removes-unused-discriminant-reads.rs => simplify_locals_removes_unused_discriminant_reads.rs} (100%) rename src/test/mir-opt/{slice-drop-shim.rs => slice_drop_shim.rs} (100%) rename src/test/mir-opt/{spanview-block.rs => spanview_block.rs} (100%) rename src/test/mir-opt/{spanview-statement.rs => spanview_statement.rs} (100%) rename src/test/mir-opt/{spanview-terminator.rs => spanview_terminator.rs} (100%) rename src/test/mir-opt/{tls-access.rs => tls_access.rs} (100%) rename src/test/mir-opt/{uninhabited-enum.rs => uninhabited_enum.rs} (100%) rename src/test/mir-opt/{unusual-item-types.rs => unusual_item_types.rs} (100%) rename src/test/mir-opt/{while-storage.rs => while_storage.rs} (100%) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index e168dd571f6d2..935ce5e7f84b3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1052,6 +1052,9 @@ impl Step for Tidy { if builder.is_verbose() { cmd.arg("--verbose"); } + if builder.config.cmd.bless() { + cmd.arg("--bless"); + } builder.info("tidy check"); try_run(builder, &mut cmd); diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index d41a66871cc43..5f8b2f9312b75 100644 --- a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -1,115 +1,115 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:7:5: 7:18, inferred_ty: *const [i32; 10] -| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send -| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] -| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] -| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] -| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] -| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send -| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send -| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] -| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] -| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:18:5: 18:18, inferred_ty: *const [i32; 10] -| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send -| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] -| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] -| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] -| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] -| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send -| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send -| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] -| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] -| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10] -| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send -| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] -| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] -| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] -| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] -| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send -| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send -| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] -| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] +| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:7:5: 7:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:18:5: 18:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send +| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send +| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32] +| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32] | fn address_of_reborrow() -> () { - let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:26: +0:26 - let _1: &[i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10 - let _2: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:14: +1:21 - let mut _4: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+2:22: +2:29 - let _5: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18 - let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18 - let _7: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+5:5: +5:26 - let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25 - let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25 - let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+6:5: +6:6 - let _11: *const [i32]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:22 - let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:6 - let _13: *const i32; // in scope 0 at $DIR/address-of.rs:+8:5: +8:20 - let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+8:5: +8:6 - let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+12:30: +12:31 - let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+13:27: +13:28 - let _21: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18 - let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18 - let _23: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+16:5: +16:26 - let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25 - let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25 - let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+17:5: +17:6 - let _27: *const [i32]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:22 - let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:6 - let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+22:30: +22:31 - let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+23:27: +23:28 - let _35: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16 - let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16 - let _37: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+26:5: +26:24 - let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23 - let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23 - let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+27:5: +27:6 - let _41: *mut [i32]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:20 - let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:6 - let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+32:28: +32:29 - let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+33:25: +33:26 + let mut _0: (); // return place in scope 0 at $DIR/address_of.rs:+0:26: +0:26 + let _1: &[i32; 10]; // in scope 0 at $DIR/address_of.rs:+1:9: +1:10 + let _2: [i32; 10]; // in scope 0 at $DIR/address_of.rs:+1:14: +1:21 + let mut _4: [i32; 10]; // in scope 0 at $DIR/address_of.rs:+2:22: +2:29 + let _5: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+4:5: +4:18 + let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+4:5: +4:18 + let _7: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+5:5: +5:26 + let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+6:5: +6:25 + let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+6:5: +6:25 + let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+6:5: +6:6 + let _11: *const [i32]; // in scope 0 at $DIR/address_of.rs:+7:5: +7:22 + let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+7:5: +7:6 + let _13: *const i32; // in scope 0 at $DIR/address_of.rs:+8:5: +8:20 + let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+8:5: +8:6 + let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+12:30: +12:31 + let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+13:27: +13:28 + let _21: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+15:5: +15:18 + let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+15:5: +15:18 + let _23: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+16:5: +16:26 + let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+17:5: +17:25 + let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+17:5: +17:25 + let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+17:5: +17:6 + let _27: *const [i32]; // in scope 0 at $DIR/address_of.rs:+18:5: +18:22 + let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+18:5: +18:6 + let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+22:30: +22:31 + let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+23:27: +23:28 + let _35: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+25:5: +25:16 + let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+25:5: +25:16 + let _37: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+26:5: +26:24 + let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+27:5: +27:23 + let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+27:5: +27:23 + let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+27:5: +27:6 + let _41: *mut [i32]; // in scope 0 at $DIR/address_of.rs:+28:5: +28:20 + let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+28:5: +28:6 + let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+32:28: +32:29 + let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+33:25: +33:26 scope 1 { - debug y => _1; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10 - let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address-of.rs:+2:9: +2:14 + debug y => _1; // in scope 1 at $DIR/address_of.rs:+1:9: +1:10 + let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address_of.rs:+2:9: +2:14 scope 2 { - debug z => _3; // in scope 2 at $DIR/address-of.rs:+2:9: +2:14 - let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address-of.rs:+10:9: +10:10 + debug z => _3; // in scope 2 at $DIR/address_of.rs:+2:9: +2:14 + let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address_of.rs:+10:9: +10:10 scope 3 { - debug p => _15; // in scope 3 at $DIR/address-of.rs:+10:9: +10:10 - let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address-of.rs:+11:9: +11:10 + debug p => _15; // in scope 3 at $DIR/address_of.rs:+10:9: +10:10 + let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address_of.rs:+11:9: +11:10 scope 4 { - debug p => _16; // in scope 4 at $DIR/address-of.rs:+11:9: +11:10 - let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address-of.rs:+12:9: +12:10 + debug p => _16; // in scope 4 at $DIR/address_of.rs:+11:9: +11:10 + let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address_of.rs:+12:9: +12:10 scope 5 { - debug p => _17; // in scope 5 at $DIR/address-of.rs:+12:9: +12:10 - let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address-of.rs:+13:9: +13:10 + debug p => _17; // in scope 5 at $DIR/address_of.rs:+12:9: +12:10 + let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address_of.rs:+13:9: +13:10 scope 6 { - debug p => _19; // in scope 6 at $DIR/address-of.rs:+13:9: +13:10 - let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address-of.rs:+20:9: +20:10 + debug p => _19; // in scope 6 at $DIR/address_of.rs:+13:9: +13:10 + let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address_of.rs:+20:9: +20:10 scope 7 { - debug p => _29; // in scope 7 at $DIR/address-of.rs:+20:9: +20:10 - let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address-of.rs:+21:9: +21:10 + debug p => _29; // in scope 7 at $DIR/address_of.rs:+20:9: +20:10 + let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address_of.rs:+21:9: +21:10 scope 8 { - debug p => _30; // in scope 8 at $DIR/address-of.rs:+21:9: +21:10 - let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address-of.rs:+22:9: +22:10 + debug p => _30; // in scope 8 at $DIR/address_of.rs:+21:9: +21:10 + let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address_of.rs:+22:9: +22:10 scope 9 { - debug p => _31; // in scope 9 at $DIR/address-of.rs:+22:9: +22:10 - let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address-of.rs:+23:9: +23:10 + debug p => _31; // in scope 9 at $DIR/address_of.rs:+22:9: +22:10 + let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address_of.rs:+23:9: +23:10 scope 10 { - debug p => _33; // in scope 10 at $DIR/address-of.rs:+23:9: +23:10 - let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address-of.rs:+30:9: +30:10 + debug p => _33; // in scope 10 at $DIR/address_of.rs:+23:9: +23:10 + let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address_of.rs:+30:9: +30:10 scope 11 { - debug p => _43; // in scope 11 at $DIR/address-of.rs:+30:9: +30:10 - let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address-of.rs:+31:9: +31:10 + debug p => _43; // in scope 11 at $DIR/address_of.rs:+30:9: +30:10 + let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address_of.rs:+31:9: +31:10 scope 12 { - debug p => _44; // in scope 12 at $DIR/address-of.rs:+31:9: +31:10 - let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address-of.rs:+32:9: +32:10 + debug p => _44; // in scope 12 at $DIR/address_of.rs:+31:9: +31:10 + let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address_of.rs:+32:9: +32:10 scope 13 { - debug p => _45; // in scope 13 at $DIR/address-of.rs:+32:9: +32:10 - let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address-of.rs:+33:9: +33:10 + debug p => _45; // in scope 13 at $DIR/address_of.rs:+32:9: +32:10 + let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address_of.rs:+33:9: +33:10 scope 14 { - debug p => _47; // in scope 14 at $DIR/address-of.rs:+33:9: +33:10 + debug p => _47; // in scope 14 at $DIR/address_of.rs:+33:9: +33:10 } } } @@ -126,183 +126,183 @@ fn address_of_reborrow() -> () { } bb0: { - StorageLive(_1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 - StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:14: +1:21 - _2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:+1:14: +1:21 - _1 = &_2; // scope 0 at $DIR/address-of.rs:+1:13: +1:21 - FakeRead(ForLet(None), _1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 - StorageLive(_3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14 - StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:22: +2:29 - _4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:+2:22: +2:29 - _3 = &mut _4; // scope 1 at $DIR/address-of.rs:+2:17: +2:29 - FakeRead(ForLet(None), _3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14 - StorageLive(_5); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 - StorageLive(_6); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 - _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+4:5: +4:6 - AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 - _5 = _6; // scope 2 at $DIR/address-of.rs:+4:5: +4:18 - StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:18: +4:19 - StorageDead(_5); // scope 2 at $DIR/address-of.rs:+4:18: +4:19 - StorageLive(_7); // scope 2 at $DIR/address-of.rs:+5:5: +5:26 - _7 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+5:5: +5:6 - StorageDead(_7); // scope 2 at $DIR/address-of.rs:+5:26: +5:27 - StorageLive(_8); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 - StorageLive(_9); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 - StorageLive(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 - _10 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 - _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 - StorageDead(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 - AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 - _8 = _9; // scope 2 at $DIR/address-of.rs:+6:5: +6:25 - StorageDead(_9); // scope 2 at $DIR/address-of.rs:+6:25: +6:26 - StorageDead(_8); // scope 2 at $DIR/address-of.rs:+6:25: +6:26 - StorageLive(_11); // scope 2 at $DIR/address-of.rs:+7:5: +7:22 - StorageLive(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 - _12 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 - _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 - StorageDead(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 - StorageDead(_11); // scope 2 at $DIR/address-of.rs:+7:22: +7:23 - StorageLive(_13); // scope 2 at $DIR/address-of.rs:+8:5: +8:20 - StorageLive(_14); // scope 2 at $DIR/address-of.rs:+8:5: +8:6 - _14 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+8:5: +8:6 - _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address-of.rs:+8:5: +8:20 - StorageDead(_14); // scope 2 at $DIR/address-of.rs:+8:19: +8:20 - StorageDead(_13); // scope 2 at $DIR/address-of.rs:+8:20: +8:21 - StorageLive(_15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10 - _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+10:23: +10:24 - FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10 - AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:+10:12: +10:20 - StorageLive(_16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10 - _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:+11:31: +11:32 - FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10 - AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:+11:12: +11:28 - StorageLive(_17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10 - StorageLive(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 - _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 - _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 - StorageDead(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 - FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10 - AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:+12:12: +12:27 - StorageLive(_19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10 - StorageLive(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 - _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 - _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 - StorageDead(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 - FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10 - AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:+13:12: +13:24 - StorageLive(_21); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 - StorageLive(_22); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 - _22 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+15:5: +15:6 - AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 - _21 = _22; // scope 6 at $DIR/address-of.rs:+15:5: +15:18 - StorageDead(_22); // scope 6 at $DIR/address-of.rs:+15:18: +15:19 - StorageDead(_21); // scope 6 at $DIR/address-of.rs:+15:18: +15:19 - StorageLive(_23); // scope 6 at $DIR/address-of.rs:+16:5: +16:26 - _23 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+16:5: +16:6 - StorageDead(_23); // scope 6 at $DIR/address-of.rs:+16:26: +16:27 - StorageLive(_24); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 - StorageLive(_25); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 - StorageLive(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 - _26 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 - _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 - StorageDead(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 - AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 - _24 = _25; // scope 6 at $DIR/address-of.rs:+17:5: +17:25 - StorageDead(_25); // scope 6 at $DIR/address-of.rs:+17:25: +17:26 - StorageDead(_24); // scope 6 at $DIR/address-of.rs:+17:25: +17:26 - StorageLive(_27); // scope 6 at $DIR/address-of.rs:+18:5: +18:22 - StorageLive(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 - _28 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 - _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 - StorageDead(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 - StorageDead(_27); // scope 6 at $DIR/address-of.rs:+18:22: +18:23 - StorageLive(_29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10 - _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+20:23: +20:24 - FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10 - AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:+20:12: +20:20 - StorageLive(_30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10 - _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:+21:31: +21:32 - FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10 - AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:+21:12: +21:28 - StorageLive(_31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10 - StorageLive(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 - _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 - _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 - StorageDead(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 - FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10 - AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:+22:12: +22:27 - StorageLive(_33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10 - StorageLive(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 - _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 - _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 - StorageDead(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 - FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10 - AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:+23:12: +23:24 - StorageLive(_35); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 - StorageLive(_36); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 - _36 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+25:5: +25:6 - AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 - _35 = _36; // scope 10 at $DIR/address-of.rs:+25:5: +25:16 - StorageDead(_36); // scope 10 at $DIR/address-of.rs:+25:16: +25:17 - StorageDead(_35); // scope 10 at $DIR/address-of.rs:+25:16: +25:17 - StorageLive(_37); // scope 10 at $DIR/address-of.rs:+26:5: +26:24 - _37 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+26:5: +26:6 - StorageDead(_37); // scope 10 at $DIR/address-of.rs:+26:24: +26:25 - StorageLive(_38); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 - StorageLive(_39); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 - StorageLive(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 - _40 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 - _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 - StorageDead(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 - AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 - _38 = _39; // scope 10 at $DIR/address-of.rs:+27:5: +27:23 - StorageDead(_39); // scope 10 at $DIR/address-of.rs:+27:23: +27:24 - StorageDead(_38); // scope 10 at $DIR/address-of.rs:+27:23: +27:24 - StorageLive(_41); // scope 10 at $DIR/address-of.rs:+28:5: +28:20 - StorageLive(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 - _42 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 - _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 - StorageDead(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 - StorageDead(_41); // scope 10 at $DIR/address-of.rs:+28:20: +28:21 - StorageLive(_43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10 - _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+30:21: +30:22 - FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10 - AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:+30:12: +30:18 - StorageLive(_44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10 - _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:+31:29: +31:30 - FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10 - AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:+31:12: +31:26 - StorageLive(_45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10 - StorageLive(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 - _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 - _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 - StorageDead(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 - FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10 - AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:+32:12: +32:25 - StorageLive(_47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10 - StorageLive(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 - _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 - _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 - StorageDead(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 - FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10 - AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:+33:12: +33:22 - _0 = const (); // scope 0 at $DIR/address-of.rs:+0:26: +34:2 - StorageDead(_47); // scope 13 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_45); // scope 12 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_44); // scope 11 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_43); // scope 10 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_33); // scope 9 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_31); // scope 8 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_30); // scope 7 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_29); // scope 6 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_19); // scope 5 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_17); // scope 4 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_16); // scope 3 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_15); // scope 2 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_4); // scope 1 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_3); // scope 1 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_2); // scope 0 at $DIR/address-of.rs:+34:1: +34:2 - StorageDead(_1); // scope 0 at $DIR/address-of.rs:+34:1: +34:2 - return; // scope 0 at $DIR/address-of.rs:+34:2: +34:2 + StorageLive(_1); // scope 0 at $DIR/address_of.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/address_of.rs:+1:14: +1:21 + _2 = [const 0_i32; 10]; // scope 0 at $DIR/address_of.rs:+1:14: +1:21 + _1 = &_2; // scope 0 at $DIR/address_of.rs:+1:13: +1:21 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/address_of.rs:+1:9: +1:10 + StorageLive(_3); // scope 1 at $DIR/address_of.rs:+2:9: +2:14 + StorageLive(_4); // scope 1 at $DIR/address_of.rs:+2:22: +2:29 + _4 = [const 0_i32; 10]; // scope 1 at $DIR/address_of.rs:+2:22: +2:29 + _3 = &mut _4; // scope 1 at $DIR/address_of.rs:+2:17: +2:29 + FakeRead(ForLet(None), _3); // scope 1 at $DIR/address_of.rs:+2:9: +2:14 + StorageLive(_5); // scope 2 at $DIR/address_of.rs:+4:5: +4:18 + StorageLive(_6); // scope 2 at $DIR/address_of.rs:+4:5: +4:18 + _6 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+4:5: +4:6 + AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address_of.rs:+4:5: +4:18 + _5 = _6; // scope 2 at $DIR/address_of.rs:+4:5: +4:18 + StorageDead(_6); // scope 2 at $DIR/address_of.rs:+4:18: +4:19 + StorageDead(_5); // scope 2 at $DIR/address_of.rs:+4:18: +4:19 + StorageLive(_7); // scope 2 at $DIR/address_of.rs:+5:5: +5:26 + _7 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+5:5: +5:6 + StorageDead(_7); // scope 2 at $DIR/address_of.rs:+5:26: +5:27 + StorageLive(_8); // scope 2 at $DIR/address_of.rs:+6:5: +6:25 + StorageLive(_9); // scope 2 at $DIR/address_of.rs:+6:5: +6:25 + StorageLive(_10); // scope 2 at $DIR/address_of.rs:+6:5: +6:6 + _10 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+6:5: +6:6 + _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address_of.rs:+6:5: +6:6 + StorageDead(_10); // scope 2 at $DIR/address_of.rs:+6:5: +6:6 + AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address_of.rs:+6:5: +6:25 + _8 = _9; // scope 2 at $DIR/address_of.rs:+6:5: +6:25 + StorageDead(_9); // scope 2 at $DIR/address_of.rs:+6:25: +6:26 + StorageDead(_8); // scope 2 at $DIR/address_of.rs:+6:25: +6:26 + StorageLive(_11); // scope 2 at $DIR/address_of.rs:+7:5: +7:22 + StorageLive(_12); // scope 2 at $DIR/address_of.rs:+7:5: +7:6 + _12 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+7:5: +7:6 + _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address_of.rs:+7:5: +7:6 + StorageDead(_12); // scope 2 at $DIR/address_of.rs:+7:5: +7:6 + StorageDead(_11); // scope 2 at $DIR/address_of.rs:+7:22: +7:23 + StorageLive(_13); // scope 2 at $DIR/address_of.rs:+8:5: +8:20 + StorageLive(_14); // scope 2 at $DIR/address_of.rs:+8:5: +8:6 + _14 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+8:5: +8:6 + _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address_of.rs:+8:5: +8:20 + StorageDead(_14); // scope 2 at $DIR/address_of.rs:+8:19: +8:20 + StorageDead(_13); // scope 2 at $DIR/address_of.rs:+8:20: +8:21 + StorageLive(_15); // scope 2 at $DIR/address_of.rs:+10:9: +10:10 + _15 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+10:23: +10:24 + FakeRead(ForLet(None), _15); // scope 2 at $DIR/address_of.rs:+10:9: +10:10 + AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address_of.rs:+10:12: +10:20 + StorageLive(_16); // scope 3 at $DIR/address_of.rs:+11:9: +11:10 + _16 = &raw const (*_1); // scope 3 at $DIR/address_of.rs:+11:31: +11:32 + FakeRead(ForLet(None), _16); // scope 3 at $DIR/address_of.rs:+11:9: +11:10 + AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address_of.rs:+11:12: +11:28 + StorageLive(_17); // scope 4 at $DIR/address_of.rs:+12:9: +12:10 + StorageLive(_18); // scope 4 at $DIR/address_of.rs:+12:30: +12:31 + _18 = &raw const (*_1); // scope 4 at $DIR/address_of.rs:+12:30: +12:31 + _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address_of.rs:+12:30: +12:31 + StorageDead(_18); // scope 4 at $DIR/address_of.rs:+12:30: +12:31 + FakeRead(ForLet(None), _17); // scope 4 at $DIR/address_of.rs:+12:9: +12:10 + AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address_of.rs:+12:12: +12:27 + StorageLive(_19); // scope 5 at $DIR/address_of.rs:+13:9: +13:10 + StorageLive(_20); // scope 5 at $DIR/address_of.rs:+13:27: +13:28 + _20 = &raw const (*_1); // scope 5 at $DIR/address_of.rs:+13:27: +13:28 + _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address_of.rs:+13:27: +13:28 + StorageDead(_20); // scope 5 at $DIR/address_of.rs:+13:27: +13:28 + FakeRead(ForLet(None), _19); // scope 5 at $DIR/address_of.rs:+13:9: +13:10 + AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address_of.rs:+13:12: +13:24 + StorageLive(_21); // scope 6 at $DIR/address_of.rs:+15:5: +15:18 + StorageLive(_22); // scope 6 at $DIR/address_of.rs:+15:5: +15:18 + _22 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+15:5: +15:6 + AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address_of.rs:+15:5: +15:18 + _21 = _22; // scope 6 at $DIR/address_of.rs:+15:5: +15:18 + StorageDead(_22); // scope 6 at $DIR/address_of.rs:+15:18: +15:19 + StorageDead(_21); // scope 6 at $DIR/address_of.rs:+15:18: +15:19 + StorageLive(_23); // scope 6 at $DIR/address_of.rs:+16:5: +16:26 + _23 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+16:5: +16:6 + StorageDead(_23); // scope 6 at $DIR/address_of.rs:+16:26: +16:27 + StorageLive(_24); // scope 6 at $DIR/address_of.rs:+17:5: +17:25 + StorageLive(_25); // scope 6 at $DIR/address_of.rs:+17:5: +17:25 + StorageLive(_26); // scope 6 at $DIR/address_of.rs:+17:5: +17:6 + _26 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+17:5: +17:6 + _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address_of.rs:+17:5: +17:6 + StorageDead(_26); // scope 6 at $DIR/address_of.rs:+17:5: +17:6 + AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address_of.rs:+17:5: +17:25 + _24 = _25; // scope 6 at $DIR/address_of.rs:+17:5: +17:25 + StorageDead(_25); // scope 6 at $DIR/address_of.rs:+17:25: +17:26 + StorageDead(_24); // scope 6 at $DIR/address_of.rs:+17:25: +17:26 + StorageLive(_27); // scope 6 at $DIR/address_of.rs:+18:5: +18:22 + StorageLive(_28); // scope 6 at $DIR/address_of.rs:+18:5: +18:6 + _28 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+18:5: +18:6 + _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address_of.rs:+18:5: +18:6 + StorageDead(_28); // scope 6 at $DIR/address_of.rs:+18:5: +18:6 + StorageDead(_27); // scope 6 at $DIR/address_of.rs:+18:22: +18:23 + StorageLive(_29); // scope 6 at $DIR/address_of.rs:+20:9: +20:10 + _29 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+20:23: +20:24 + FakeRead(ForLet(None), _29); // scope 6 at $DIR/address_of.rs:+20:9: +20:10 + AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address_of.rs:+20:12: +20:20 + StorageLive(_30); // scope 7 at $DIR/address_of.rs:+21:9: +21:10 + _30 = &raw const (*_3); // scope 7 at $DIR/address_of.rs:+21:31: +21:32 + FakeRead(ForLet(None), _30); // scope 7 at $DIR/address_of.rs:+21:9: +21:10 + AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address_of.rs:+21:12: +21:28 + StorageLive(_31); // scope 8 at $DIR/address_of.rs:+22:9: +22:10 + StorageLive(_32); // scope 8 at $DIR/address_of.rs:+22:30: +22:31 + _32 = &raw const (*_3); // scope 8 at $DIR/address_of.rs:+22:30: +22:31 + _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address_of.rs:+22:30: +22:31 + StorageDead(_32); // scope 8 at $DIR/address_of.rs:+22:30: +22:31 + FakeRead(ForLet(None), _31); // scope 8 at $DIR/address_of.rs:+22:9: +22:10 + AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address_of.rs:+22:12: +22:27 + StorageLive(_33); // scope 9 at $DIR/address_of.rs:+23:9: +23:10 + StorageLive(_34); // scope 9 at $DIR/address_of.rs:+23:27: +23:28 + _34 = &raw const (*_3); // scope 9 at $DIR/address_of.rs:+23:27: +23:28 + _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address_of.rs:+23:27: +23:28 + StorageDead(_34); // scope 9 at $DIR/address_of.rs:+23:27: +23:28 + FakeRead(ForLet(None), _33); // scope 9 at $DIR/address_of.rs:+23:9: +23:10 + AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address_of.rs:+23:12: +23:24 + StorageLive(_35); // scope 10 at $DIR/address_of.rs:+25:5: +25:16 + StorageLive(_36); // scope 10 at $DIR/address_of.rs:+25:5: +25:16 + _36 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+25:5: +25:6 + AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address_of.rs:+25:5: +25:16 + _35 = _36; // scope 10 at $DIR/address_of.rs:+25:5: +25:16 + StorageDead(_36); // scope 10 at $DIR/address_of.rs:+25:16: +25:17 + StorageDead(_35); // scope 10 at $DIR/address_of.rs:+25:16: +25:17 + StorageLive(_37); // scope 10 at $DIR/address_of.rs:+26:5: +26:24 + _37 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+26:5: +26:6 + StorageDead(_37); // scope 10 at $DIR/address_of.rs:+26:24: +26:25 + StorageLive(_38); // scope 10 at $DIR/address_of.rs:+27:5: +27:23 + StorageLive(_39); // scope 10 at $DIR/address_of.rs:+27:5: +27:23 + StorageLive(_40); // scope 10 at $DIR/address_of.rs:+27:5: +27:6 + _40 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+27:5: +27:6 + _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address_of.rs:+27:5: +27:6 + StorageDead(_40); // scope 10 at $DIR/address_of.rs:+27:5: +27:6 + AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address_of.rs:+27:5: +27:23 + _38 = _39; // scope 10 at $DIR/address_of.rs:+27:5: +27:23 + StorageDead(_39); // scope 10 at $DIR/address_of.rs:+27:23: +27:24 + StorageDead(_38); // scope 10 at $DIR/address_of.rs:+27:23: +27:24 + StorageLive(_41); // scope 10 at $DIR/address_of.rs:+28:5: +28:20 + StorageLive(_42); // scope 10 at $DIR/address_of.rs:+28:5: +28:6 + _42 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+28:5: +28:6 + _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address_of.rs:+28:5: +28:6 + StorageDead(_42); // scope 10 at $DIR/address_of.rs:+28:5: +28:6 + StorageDead(_41); // scope 10 at $DIR/address_of.rs:+28:20: +28:21 + StorageLive(_43); // scope 10 at $DIR/address_of.rs:+30:9: +30:10 + _43 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+30:21: +30:22 + FakeRead(ForLet(None), _43); // scope 10 at $DIR/address_of.rs:+30:9: +30:10 + AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address_of.rs:+30:12: +30:18 + StorageLive(_44); // scope 11 at $DIR/address_of.rs:+31:9: +31:10 + _44 = &raw mut (*_3); // scope 11 at $DIR/address_of.rs:+31:29: +31:30 + FakeRead(ForLet(None), _44); // scope 11 at $DIR/address_of.rs:+31:9: +31:10 + AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address_of.rs:+31:12: +31:26 + StorageLive(_45); // scope 12 at $DIR/address_of.rs:+32:9: +32:10 + StorageLive(_46); // scope 12 at $DIR/address_of.rs:+32:28: +32:29 + _46 = &raw mut (*_3); // scope 12 at $DIR/address_of.rs:+32:28: +32:29 + _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address_of.rs:+32:28: +32:29 + StorageDead(_46); // scope 12 at $DIR/address_of.rs:+32:28: +32:29 + FakeRead(ForLet(None), _45); // scope 12 at $DIR/address_of.rs:+32:9: +32:10 + AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address_of.rs:+32:12: +32:25 + StorageLive(_47); // scope 13 at $DIR/address_of.rs:+33:9: +33:10 + StorageLive(_48); // scope 13 at $DIR/address_of.rs:+33:25: +33:26 + _48 = &raw mut (*_3); // scope 13 at $DIR/address_of.rs:+33:25: +33:26 + _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address_of.rs:+33:25: +33:26 + StorageDead(_48); // scope 13 at $DIR/address_of.rs:+33:25: +33:26 + FakeRead(ForLet(None), _47); // scope 13 at $DIR/address_of.rs:+33:9: +33:10 + AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address_of.rs:+33:12: +33:22 + _0 = const (); // scope 0 at $DIR/address_of.rs:+0:26: +34:2 + StorageDead(_47); // scope 13 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_45); // scope 12 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_44); // scope 11 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_43); // scope 10 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_33); // scope 9 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_31); // scope 8 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_30); // scope 7 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_29); // scope 6 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_19); // scope 5 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_17); // scope 4 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_16); // scope 3 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_15); // scope 2 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_4); // scope 1 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_3); // scope 1 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_2); // scope 0 at $DIR/address_of.rs:+34:1: +34:2 + StorageDead(_1); // scope 0 at $DIR/address_of.rs:+34:1: +34:2 + return; // scope 0 at $DIR/address_of.rs:+34:2: +34:2 } } diff --git a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir index 060077b8adb9e..4c67376b56a68 100644 --- a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir @@ -1,47 +1,47 @@ // MIR for `borrow_and_cast` after SimplifyCfg-initial fn borrow_and_cast(_1: i32) -> () { - debug x => _1; // in scope 0 at $DIR/address-of.rs:+0:20: +0:25 - let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:32: +0:32 - let _2: *const i32; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10 - let _3: &i32; // in scope 0 at $DIR/address-of.rs:+1:13: +1:15 - let _5: &mut i32; // in scope 0 at $DIR/address-of.rs:+2:13: +2:19 - let mut _7: &mut i32; // in scope 0 at $DIR/address-of.rs:+3:13: +3:19 + debug x => _1; // in scope 0 at $DIR/address_of.rs:+0:20: +0:25 + let mut _0: (); // return place in scope 0 at $DIR/address_of.rs:+0:32: +0:32 + let _2: *const i32; // in scope 0 at $DIR/address_of.rs:+1:9: +1:10 + let _3: &i32; // in scope 0 at $DIR/address_of.rs:+1:13: +1:15 + let _5: &mut i32; // in scope 0 at $DIR/address_of.rs:+2:13: +2:19 + let mut _7: &mut i32; // in scope 0 at $DIR/address_of.rs:+3:13: +3:19 scope 1 { - debug p => _2; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10 - let _4: *const i32; // in scope 1 at $DIR/address-of.rs:+2:9: +2:10 + debug p => _2; // in scope 1 at $DIR/address_of.rs:+1:9: +1:10 + let _4: *const i32; // in scope 1 at $DIR/address_of.rs:+2:9: +2:10 scope 2 { - debug q => _4; // in scope 2 at $DIR/address-of.rs:+2:9: +2:10 - let _6: *mut i32; // in scope 2 at $DIR/address-of.rs:+3:9: +3:10 + debug q => _4; // in scope 2 at $DIR/address_of.rs:+2:9: +2:10 + let _6: *mut i32; // in scope 2 at $DIR/address_of.rs:+3:9: +3:10 scope 3 { - debug r => _6; // in scope 3 at $DIR/address-of.rs:+3:9: +3:10 + debug r => _6; // in scope 3 at $DIR/address_of.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15 - _3 = &_1; // scope 0 at $DIR/address-of.rs:+1:13: +1:15 - _2 = &raw const (*_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15 - FakeRead(ForLet(None), _2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 - StorageDead(_3); // scope 0 at $DIR/address-of.rs:+1:29: +1:30 - StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10 - StorageLive(_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19 - _5 = &mut _1; // scope 1 at $DIR/address-of.rs:+2:13: +2:19 - _4 = &raw const (*_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19 - FakeRead(ForLet(None), _4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10 - StorageDead(_5); // scope 1 at $DIR/address-of.rs:+2:33: +2:34 - StorageLive(_6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10 - StorageLive(_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19 - _7 = &mut _1; // scope 2 at $DIR/address-of.rs:+3:13: +3:19 - _6 = &raw mut (*_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19 - FakeRead(ForLet(None), _6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10 - StorageDead(_7); // scope 2 at $DIR/address-of.rs:+3:31: +3:32 - _0 = const (); // scope 0 at $DIR/address-of.rs:+0:32: +4:2 - StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:1: +4:2 - StorageDead(_4); // scope 1 at $DIR/address-of.rs:+4:1: +4:2 - StorageDead(_2); // scope 0 at $DIR/address-of.rs:+4:1: +4:2 - return; // scope 0 at $DIR/address-of.rs:+4:2: +4:2 + StorageLive(_2); // scope 0 at $DIR/address_of.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/address_of.rs:+1:13: +1:15 + _3 = &_1; // scope 0 at $DIR/address_of.rs:+1:13: +1:15 + _2 = &raw const (*_3); // scope 0 at $DIR/address_of.rs:+1:13: +1:15 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/address_of.rs:+1:9: +1:10 + StorageDead(_3); // scope 0 at $DIR/address_of.rs:+1:29: +1:30 + StorageLive(_4); // scope 1 at $DIR/address_of.rs:+2:9: +2:10 + StorageLive(_5); // scope 1 at $DIR/address_of.rs:+2:13: +2:19 + _5 = &mut _1; // scope 1 at $DIR/address_of.rs:+2:13: +2:19 + _4 = &raw const (*_5); // scope 1 at $DIR/address_of.rs:+2:13: +2:19 + FakeRead(ForLet(None), _4); // scope 1 at $DIR/address_of.rs:+2:9: +2:10 + StorageDead(_5); // scope 1 at $DIR/address_of.rs:+2:33: +2:34 + StorageLive(_6); // scope 2 at $DIR/address_of.rs:+3:9: +3:10 + StorageLive(_7); // scope 2 at $DIR/address_of.rs:+3:13: +3:19 + _7 = &mut _1; // scope 2 at $DIR/address_of.rs:+3:13: +3:19 + _6 = &raw mut (*_7); // scope 2 at $DIR/address_of.rs:+3:13: +3:19 + FakeRead(ForLet(None), _6); // scope 2 at $DIR/address_of.rs:+3:9: +3:10 + StorageDead(_7); // scope 2 at $DIR/address_of.rs:+3:31: +3:32 + _0 = const (); // scope 0 at $DIR/address_of.rs:+0:32: +4:2 + StorageDead(_6); // scope 2 at $DIR/address_of.rs:+4:1: +4:2 + StorageDead(_4); // scope 1 at $DIR/address_of.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/address_of.rs:+4:1: +4:2 + return; // scope 0 at $DIR/address_of.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/address-of.rs b/src/test/mir-opt/address_of.rs similarity index 100% rename from src/test/mir-opt/address-of.rs rename to src/test/mir-opt/address_of.rs diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir index 27f883ed321ae..af5178d4079d0 100644 --- a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir @@ -1,22 +1,22 @@ // MIR for `main` after SimplifyCfg-elaborate-drops fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11 - let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 - let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 - let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 - let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 - let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 - let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 - let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + let mut _0: (); // return place in scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +0:11 + let mut _1: [u32; 3]; // in scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + let mut _4: &mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + let mut _5: u32; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:12: +4:29 + let mut _6: *mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + let _7: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + let mut _8: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + let mut _9: bool; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 scope 1 { - debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 - let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + debug x => _1; // in scope 1 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + let mut _2: usize; // in scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 scope 2 { - debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 - let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + debug y => _2; // in scope 2 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 + let _3: *mut usize; // in scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + debug z => _3; // in scope 3 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 scope 4 { } } @@ -24,41 +24,41 @@ fn main() -> () { } bb0: { - StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 - _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29 - StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 - _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18 - StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 - StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 - _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 - _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 - StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32 - StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 - StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 - _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 - _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27 + StorageLive(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14 + _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array_index_is_temporary.rs:+1:17: +1:29 + StorageLive(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14 + _2 = const 1_usize; // scope 1 at $DIR/array_index_is_temporary.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + _4 = &mut _2; // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + _3 = &raw mut (*_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31 + StorageDead(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:31: +3:32 + StorageLive(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:12: +4:29 + StorageLive(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + _6 = _3; // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26 + _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array_index_is_temporary.rs:+4:21: +4:27 // mir::Constant - // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24 + // + span: $DIR/array_index_is_temporary.rs:16:21: 16:24 // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value() } } bb1: { - StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27 - StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 - _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 - _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 - _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 - assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + StorageDead(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:26: +4:27 + StorageLive(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + _7 = _2; // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8 + _8 = Len(_1); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + _9 = Lt(_7, _8); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9 } bb2: { - _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29 - StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29 - StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30 - _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2 - StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 - StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 - StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 - return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2 + _1[_7] = move _5; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:29 + StorageDead(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:28: +4:29 + StorageDead(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:29: +4:30 + _0 = const (); // scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +5:2 + StorageDead(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+5:1: +5:2 + return; // scope 0 at $DIR/array_index_is_temporary.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array_index_is_temporary.rs similarity index 100% rename from src/test/mir-opt/array-index-is-temporary.rs rename to src/test/mir-opt/array_index_is_temporary.rs diff --git a/src/test/mir-opt/building/issue_101867.main.built.after.mir b/src/test/mir-opt/building/issue_101867.main.built.after.mir index 6834205b649b2..0ebd840cf2d5c 100644 --- a/src/test/mir-opt/building/issue_101867.main.built.after.mir +++ b/src/test/mir-opt/building/issue_101867.main.built.after.mir @@ -1,33 +1,33 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option) }, span: $DIR/issue-101867.rs:3:12: 3:22, inferred_ty: std::option::Option -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option) }, span: $DIR/issue-101867.rs:3:12: 3:22, inferred_ty: std::option::Option +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-101867.rs:+0:11: +0:11 - let _1: std::option::Option as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-101867.rs:+1:9: +1:10 - let mut _2: !; // in scope 0 at $DIR/issue-101867.rs:+2:26: +4:6 + let mut _0: (); // return place in scope 0 at $DIR/issue_101867.rs:+0:11: +0:11 + let _1: std::option::Option as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + let mut _2: !; // in scope 0 at $DIR/issue_101867.rs:+2:26: +4:6 let _3: (); // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL - let mut _6: isize; // in scope 0 at $DIR/issue-101867.rs:+2:9: +2:16 + let mut _6: isize; // in scope 0 at $DIR/issue_101867.rs:+2:9: +2:16 scope 1 { - debug x => _1; // in scope 1 at $DIR/issue-101867.rs:+1:9: +1:10 - let _5: u8; // in scope 1 at $DIR/issue-101867.rs:+2:14: +2:15 + debug x => _1; // in scope 1 at $DIR/issue_101867.rs:+1:9: +1:10 + let _5: u8; // in scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 scope 2 { - debug y => _5; // in scope 2 at $DIR/issue-101867.rs:+2:14: +2:15 + debug y => _5; // in scope 2 at $DIR/issue_101867.rs:+2:14: +2:15 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10 - _1 = Option::::Some(const 1_u8); // scope 0 at $DIR/issue-101867.rs:+1:25: +1:32 - FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10 - AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-101867.rs:+1:12: +1:22 - StorageLive(_5); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15 - FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20 - _6 = discriminant(_1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20 - switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16 + StorageLive(_1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + _1 = Option::::Some(const 1_u8); // scope 0 at $DIR/issue_101867.rs:+1:25: +1:32 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_101867.rs:+1:12: +1:22 + StorageLive(_5); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 + FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 + _6 = discriminant(_1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 + switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 } bb1: { @@ -44,32 +44,32 @@ fn main() -> () { bb2: { StorageDead(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL - StorageDead(_3); // scope 1 at $DIR/issue-101867.rs:+3:16: +3:17 - unreachable; // scope 1 at $DIR/issue-101867.rs:+2:26: +4:6 + StorageDead(_3); // scope 1 at $DIR/issue_101867.rs:+3:16: +3:17 + unreachable; // scope 1 at $DIR/issue_101867.rs:+2:26: +4:6 } bb3: { - goto -> bb6; // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20 + goto -> bb6; // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 } bb4: { - falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16 + falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 } bb5: { - _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15 - _0 = const (); // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2 - StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2 - StorageDead(_1); // scope 0 at $DIR/issue-101867.rs:+5:1: +5:2 - return; // scope 0 at $DIR/issue-101867.rs:+5:2: +5:2 + _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 + _0 = const (); // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2 + StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue_101867.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_101867.rs:+5:2: +5:2 } bb6: { - StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2 - goto -> bb1; // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2 + StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2 + goto -> bb1; // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2 } bb7 (cleanup): { - resume; // scope 0 at $DIR/issue-101867.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/issue_101867.rs:+0:1: +5:2 } } diff --git a/src/test/mir-opt/building/issue-101867.rs b/src/test/mir-opt/building/issue_101867.rs similarity index 100% rename from src/test/mir-opt/building/issue-101867.rs rename to src/test/mir-opt/building/issue_101867.rs diff --git a/src/test/mir-opt/building/issue_49232.main.built.after.mir b/src/test/mir-opt/building/issue_49232.main.built.after.mir index b90f8c13589fa..9182bcaa21fa6 100644 --- a/src/test/mir-opt/building/issue_49232.main.built.after.mir +++ b/src/test/mir-opt/building/issue_49232.main.built.after.mir @@ -1,82 +1,82 @@ // MIR for `main` after built fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-49232.rs:+0:11: +0:11 - let mut _1: (); // in scope 0 at $DIR/issue-49232.rs:+0:1: +10:2 - let _2: i32; // in scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 - let mut _3: bool; // in scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 - let mut _4: !; // in scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 - let _5: (); // in scope 0 at $DIR/issue-49232.rs:+8:9: +8:22 - let mut _6: &i32; // in scope 0 at $DIR/issue-49232.rs:+8:14: +8:21 + let mut _0: (); // return place in scope 0 at $DIR/issue_49232.rs:+0:11: +0:11 + let mut _1: (); // in scope 0 at $DIR/issue_49232.rs:+0:1: +10:2 + let _2: i32; // in scope 0 at $DIR/issue_49232.rs:+2:13: +2:19 + let mut _3: bool; // in scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 + let mut _4: !; // in scope 0 at $DIR/issue_49232.rs:+5:25: +5:30 + let _5: (); // in scope 0 at $DIR/issue_49232.rs:+8:9: +8:22 + let mut _6: &i32; // in scope 0 at $DIR/issue_49232.rs:+8:14: +8:21 scope 1 { - debug beacon => _2; // in scope 1 at $DIR/issue-49232.rs:+2:13: +2:19 + debug beacon => _2; // in scope 1 at $DIR/issue_49232.rs:+2:13: +2:19 } bb0: { - goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + goto -> bb1; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6 } bb1: { - falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6 } bb2: { - StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 - StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 - _3 = const true; // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 - FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 - switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue-49232.rs:+3:13: +3:23 + StorageLive(_2); // scope 0 at $DIR/issue_49232.rs:+2:13: +2:19 + StorageLive(_3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 + _3 = const true; // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 + FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 + switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue_49232.rs:+3:13: +3:23 } bb3: { - falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue-49232.rs:+4:17: +4:22 + falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue_49232.rs:+4:17: +4:22 } bb4: { - _0 = const (); // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 - goto -> bb10; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + _0 = const (); // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30 + goto -> bb10; // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30 } bb5: { - _2 = const 4_i32; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27 - goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27 + _2 = const 4_i32; // scope 0 at $DIR/issue_49232.rs:+4:26: +4:27 + goto -> bb8; // scope 0 at $DIR/issue_49232.rs:+4:26: +4:27 } bb6: { - unreachable; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + unreachable; // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30 } bb7: { - goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+6:13: +6:14 + goto -> bb8; // scope 0 at $DIR/issue_49232.rs:+6:13: +6:14 } bb8: { - FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 - StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11 - StorageLive(_5); // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22 - StorageLive(_6); // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21 - _6 = &_2; // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21 - _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_49232.rs:+2:13: +2:19 + StorageDead(_3); // scope 0 at $DIR/issue_49232.rs:+7:10: +7:11 + StorageLive(_5); // scope 1 at $DIR/issue_49232.rs:+8:9: +8:22 + StorageLive(_6); // scope 1 at $DIR/issue_49232.rs:+8:14: +8:21 + _6 = &_2; // scope 1 at $DIR/issue_49232.rs:+8:14: +8:21 + _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue_49232.rs:+8:9: +8:22 // mir::Constant - // + span: $DIR/issue-49232.rs:13:9: 13:13 + // + span: $DIR/issue_49232.rs:13:9: 13:13 // + literal: Const { ty: fn(&i32) {std::mem::drop::<&i32>}, val: Value() } } bb9: { - StorageDead(_6); // scope 1 at $DIR/issue-49232.rs:+8:21: +8:22 - StorageDead(_5); // scope 1 at $DIR/issue-49232.rs:+8:22: +8:23 - _1 = const (); // scope 0 at $DIR/issue-49232.rs:+1:10: +9:6 - StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6 - goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + StorageDead(_6); // scope 1 at $DIR/issue_49232.rs:+8:21: +8:22 + StorageDead(_5); // scope 1 at $DIR/issue_49232.rs:+8:22: +8:23 + _1 = const (); // scope 0 at $DIR/issue_49232.rs:+1:10: +9:6 + StorageDead(_2); // scope 0 at $DIR/issue_49232.rs:+9:5: +9:6 + goto -> bb1; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6 } bb10: { - StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11 - StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6 - return; // scope 0 at $DIR/issue-49232.rs:+10:2: +10:2 + StorageDead(_3); // scope 0 at $DIR/issue_49232.rs:+7:10: +7:11 + StorageDead(_2); // scope 0 at $DIR/issue_49232.rs:+9:5: +9:6 + return; // scope 0 at $DIR/issue_49232.rs:+10:2: +10:2 } bb11 (cleanup): { - resume; // scope 0 at $DIR/issue-49232.rs:+0:1: +10:2 + resume; // scope 0 at $DIR/issue_49232.rs:+0:1: +10:2 } } diff --git a/src/test/mir-opt/building/issue-49232.rs b/src/test/mir-opt/building/issue_49232.rs similarity index 100% rename from src/test/mir-opt/building/issue-49232.rs rename to src/test/mir-opt/building/issue_49232.rs diff --git a/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index 0192bdc2d5e3e..41eb00363bd90 100644 --- a/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -1,96 +1,96 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test -| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test -| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +0:11 - let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 - let _2: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 - let mut _3: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 - let mut _4: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 - let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 - let _7: &&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 - let _8: &&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 - let _9: &*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 - let _10: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - let mut _11: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - let mut _12: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + let mut _0: (); // return place in scope 0 at $DIR/receiver_ptr_mutability.rs:+0:11: +0:11 + let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12 + let _2: (); // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 + let mut _3: *const Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 + let mut _4: *mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8 + let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41 + let _7: &&&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41 + let _8: &&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41 + let _9: &*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41 + let _10: (); // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + let mut _11: *const Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + let mut _12: *mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 scope 1 { - debug ptr => _1; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 - let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + debug ptr => _1; // in scope 1 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12 + let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16 scope 2 { - debug ptr_ref => _5; // in scope 2 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + debug ptr_ref => _5; // in scope 2 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 - _1 = null_mut::() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:26: +1:46 + StorageLive(_1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12 + _1 = null_mut::() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:26: +1:46 // mir::Constant - // + span: $DIR/receiver-ptr-mutability.rs:14:26: 14:44 + // + span: $DIR/receiver_ptr_mutability.rs:14:26: 14:44 // + literal: Const { ty: fn() -> *mut Test {null_mut::}, val: Value() } } bb1: { - FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 - AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:14: +1:23 - StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 - StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 - StorageLive(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 - _4 = _1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 - _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 - StorageDead(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:7: +2:8 - _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12 + AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:14: +1:23 + StorageLive(_2); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 + StorageLive(_3); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 + StorageLive(_4); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8 + _4 = _1; // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8 + _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 + StorageDead(_4); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:7: +2:8 + _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12 // mir::Constant - // + span: $DIR/receiver-ptr-mutability.rs:15:9: 15:10 + // + span: $DIR/receiver_ptr_mutability.rs:15:9: 15:10 // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value() } } bb2: { - StorageDead(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:11: +2:12 - StorageDead(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:12: +2:13 - StorageLive(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 - StorageLive(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 - StorageLive(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 - StorageLive(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 - StorageLive(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 - _9 = &_1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 - _8 = &_9; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 - _7 = &_8; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 - _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 - _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 - FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 - AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:18: +5:31 - StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:41: +5:42 - StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - StorageLive(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - StorageLive(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 - StorageDead(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:11: +6:12 - _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + StorageDead(_3); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:11: +2:12 + StorageDead(_2); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:12: +2:13 + StorageLive(_5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16 + StorageLive(_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41 + StorageLive(_7); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41 + StorageLive(_8); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41 + StorageLive(_9); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41 + _9 = &_1; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41 + _8 = &_9; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41 + _7 = &_8; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41 + _6 = &_7; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41 + _5 = &(*_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41 + FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16 + AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:18: +5:31 + StorageDead(_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:41: +5:42 + StorageLive(_10); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + StorageLive(_11); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + StorageLive(_12); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 + StorageDead(_12); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:11: +6:12 + _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16 // mir::Constant - // + span: $DIR/receiver-ptr-mutability.rs:19:13: 19:14 + // + span: $DIR/receiver_ptr_mutability.rs:19:13: 19:14 // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value() } } bb3: { - StorageDead(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:15: +6:16 - StorageDead(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:16: +6:17 - _0 = const (); // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +7:2 - StorageDead(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 - StorageDead(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 - StorageDead(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 - StorageDead(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 - StorageDead(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 - return; // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:2: +7:2 + StorageDead(_11); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:15: +6:16 + StorageDead(_10); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:16: +6:17 + _0 = const (); // scope 0 at $DIR/receiver_ptr_mutability.rs:+0:11: +7:2 + StorageDead(_9); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2 + StorageDead(_8); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2 + StorageDead(_7); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2 + StorageDead(_5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2 + return; // scope 0 at $DIR/receiver_ptr_mutability.rs:+7:2: +7:2 } bb4 (cleanup): { - resume; // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:1: +7:2 + resume; // scope 0 at $DIR/receiver_ptr_mutability.rs:+0:1: +7:2 } } diff --git a/src/test/mir-opt/building/receiver-ptr-mutability.rs b/src/test/mir-opt/building/receiver_ptr_mutability.rs similarity index 100% rename from src/test/mir-opt/building/receiver-ptr-mutability.rs rename to src/test/mir-opt/building/receiver_ptr_mutability.rs diff --git a/src/test/mir-opt/building/simple_match.match_bool.built.after.mir b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir index 5b101cbdee775..a4516026c3b47 100644 --- a/src/test/mir-opt/building/simple_match.match_bool.built.after.mir +++ b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir @@ -1,29 +1,29 @@ // MIR for `match_bool` after built fn match_bool(_1: bool) -> usize { - debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16 - let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32 + debug x => _1; // in scope 0 at $DIR/simple_match.rs:+0:15: +0:16 + let mut _0: usize; // return place in scope 0 at $DIR/simple_match.rs:+0:27: +0:32 bb0: { - FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12 - switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple_match.rs:+1:11: +1:12 + switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple_match.rs:+1:5: +1:12 } bb1: { - falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13 + falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple_match.rs:+2:9: +2:13 } bb2: { - _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 - goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 + _0 = const 20_usize; // scope 0 at $DIR/simple_match.rs:+3:14: +3:16 + goto -> bb4; // scope 0 at $DIR/simple_match.rs:+3:14: +3:16 } bb3: { - _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 - goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 + _0 = const 10_usize; // scope 0 at $DIR/simple_match.rs:+2:17: +2:19 + goto -> bb4; // scope 0 at $DIR/simple_match.rs:+2:17: +2:19 } bb4: { - return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2 + return; // scope 0 at $DIR/simple_match.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/building/simple-match.rs b/src/test/mir-opt/building/simple_match.rs similarity index 100% rename from src/test/mir-opt/building/simple-match.rs rename to src/test/mir-opt/building/simple_match.rs diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 7650769de3b59..028480bdc88b4 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -1,20 +1,20 @@ // MIR for `BAR::promoted[0]` after SimplifyCfg-elaborate-drops promoted[0] in BAR: &[&i32; 1] = { - let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 - let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 - let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 + let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + let mut _1: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35 + let mut _2: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34 + let mut _3: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34 bb0: { - _3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 + _3 = const {alloc1: &i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 + // + span: $DIR/const_promotion_extern_static.rs:9:33: 9:34 // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } - _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 - _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 - _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34 + _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35 + _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 } } diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index f8a7c687e124a..2ef4378115fbe 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -2,49 +2,49 @@ + // MIR for `BAR` after PromoteTemps static mut BAR: *const &i32 = { - let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28 - let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 - let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 - let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 -+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + let mut _0: *const &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:17: +0:28 + let mut _1: &[&i32]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + let _3: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35 + let mut _4: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34 + let _5: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34 ++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 bb0: { - StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 -- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 -- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 -- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 -- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 -+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 +- StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35 +- StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34 +- StorageLive(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34 +- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34 ++ _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 // mir::Constant -- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 +- // + span: $DIR/const_promotion_extern_static.rs:9:33: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } -- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 -- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 -- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 -+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44 +- _4 = &(*_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34 +- _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35 +- _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 ++ // + span: $DIR/const_promotion_extern_static.rs:9:31: 9:44 + // + literal: Const { ty: &[&i32; 1], val: Unevaluated(BAR, [], Some(promoted[0])) } -+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 - _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 -- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35 - StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35 - _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 ++ _2 = &(*_6); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 + _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 +- StorageDead(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:34: +0:35 + StorageDead(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:34: +0:35 + _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42 + // + span: $DIR/const_promotion_extern_static.rs:9:36: 9:42 // + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::::as_ptr}, val: Value() } } bb1: { -- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 -- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 - StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 - return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45 +- StorageDead(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44 +- StorageDead(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44 + StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44 + return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45 } bb2 (cleanup): { - resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45 + resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45 } - } - diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir index 5bda86bbd4f50..476fc49a1fe1b 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir @@ -1,17 +1,17 @@ // MIR for `BOP` after built static BOP: &i32 = { - let mut _0: &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:13: +0:17 - let _1: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 - let _2: i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 + let mut _0: &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:13: +0:17 + let _1: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23 + let _2: i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23 bb0: { - StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 - StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 - _2 = const 13_i32; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 - _1 = &_2; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 - _0 = &(*_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 - StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:22: +0:23 - return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:24 + StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23 + StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23 + _2 = const 13_i32; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23 + _1 = &_2; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23 + _0 = &(*_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23 + StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:22: +0:23 + return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:24 } } diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 71827eab1c28b..41657b53fc12c 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -1,20 +1,20 @@ // MIR for `FOO::promoted[0]` after SimplifyCfg-elaborate-drops promoted[0] in FOO: &[&i32; 1] = { - let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 - let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 - let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 + let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + let mut _1: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 + let mut _2: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 + let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 bb0: { - _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 + _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 + // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } - _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43 - _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 - _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 + _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 + _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 } } diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index e938ca28af5d6..25ba0face6bd8 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -2,51 +2,51 @@ + // MIR for `FOO` after PromoteTemps static mut FOO: *const &i32 = { - let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28 - let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 - let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 - let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 -+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + let mut _0: *const &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:17: +0:28 + let mut _1: &[&i32]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + let _3: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 + let mut _4: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 + let _5: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 ++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 scope 1 { } bb0: { - StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 -- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 -- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 -- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 -- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 -+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 +- StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 +- StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 +- StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 +- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 ++ _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 // mir::Constant -- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 +- // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } -- _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43 -- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 -- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 -+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55 +- _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 +- _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 +- _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 ++ // + span: $DIR/const_promotion_extern_static.rs:13:31: 13:55 + // + literal: Const { ty: &[&i32; 1], val: Unevaluated(FOO, [], Some(promoted[0])) } -+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 - _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 -- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46 - StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46 - _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 ++ _2 = &(*_6); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 +- StorageDead(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:45: +0:46 + StorageDead(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:45: +0:46 + _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53 + // + span: $DIR/const_promotion_extern_static.rs:13:47: 13:53 // + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::::as_ptr}, val: Value() } } bb1: { -- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 -- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 - StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 - return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56 +- StorageDead(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55 +- StorageDead(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55 + StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55 + return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56 } bb2 (cleanup): { - resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56 + resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56 } } - diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const_promotion_extern_static.rs similarity index 100% rename from src/test/mir-opt/const-promotion-extern-static.rs rename to src/test/mir-opt/const_promotion_extern_static.rs diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index a07bdd99825d6..8b3b9d0a4c1bb 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -2,15 +2,15 @@ + // MIR for `hello` after ConstProp fn hello() -> () { - let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14 - let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14 + let mut _1: bool; // in scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL bb0: { - StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 - _1 = const _; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 -- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 -+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + StorageLive(_1); // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 + _1 = const _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 +- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 ++ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 } bb1: { @@ -25,9 +25,9 @@ } bb2: { - nop; // scope 0 at $DIR/control-flow-simplification.rs:+3:6: +3:6 - StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:+3:5: +3:6 - return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2 + nop; // scope 0 at $DIR/control_flow_simplification.rs:+3:6: +3:6 + StorageDead(_1); // scope 0 at $DIR/control_flow_simplification.rs:+3:5: +3:6 + return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir index 70f9797751131..9f7528f0ce170 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir @@ -1,9 +1,9 @@ // MIR for `hello` before PreCodegen fn hello() -> () { - let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14 bb0: { - return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2 + return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control_flow_simplification.rs similarity index 100% rename from src/test/mir-opt/const_prop/control-flow-simplification.rs rename to src/test/mir-opt/const_prop/control_flow_simplification.rs diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff index 9d541dcabbb2c..7d8e647cbcede 100644 --- a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff @@ -2,32 +2,32 @@ + // MIR for `main` after ConstProp fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-66971.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 - let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - let mut _3: (); // in scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 + let mut _0: (); // return place in scope 0 at $DIR/issue_66971.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 + let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + let mut _3: (); // in scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 - StorageLive(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - StorageLive(_3); // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 - nop; // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 - Deinit(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - nop; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 - StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22 - _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 + StorageLive(_1); // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 + StorageLive(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + StorageLive(_3); // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 + nop; // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 + Deinit(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + nop; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 + StorageDead(_3); // scope 0 at $DIR/issue_66971.rs:+1:21: +1:22 + _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 // mir::Constant - // + span: $DIR/issue-66971.rs:17:5: 17:11 + // + span: $DIR/issue_66971.rs:17:5: 17:11 // + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value() } } bb1: { - StorageDead(_2); // scope 0 at $DIR/issue-66971.rs:+1:22: +1:23 - StorageDead(_1); // scope 0 at $DIR/issue-66971.rs:+1:23: +1:24 - nop; // scope 0 at $DIR/issue-66971.rs:+0:11: +2:2 - return; // scope 0 at $DIR/issue-66971.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue_66971.rs:+1:22: +1:23 + StorageDead(_1); // scope 0 at $DIR/issue_66971.rs:+1:23: +1:24 + nop; // scope 0 at $DIR/issue_66971.rs:+0:11: +2:2 + return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue_66971.rs similarity index 100% rename from src/test/mir-opt/const_prop/issue-66971.rs rename to src/test/mir-opt/const_prop/issue_66971.rs diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff index b79d814760d9e..79cd8bf483969 100644 --- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff @@ -2,33 +2,33 @@ + // MIR for `main` after ConstProp fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-67019.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 - let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 - let mut _3: (u8, u8); // in scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + let mut _0: (); // return place in scope 0 at $DIR/issue_67019.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_67019.rs:+1:5: +1:20 + let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + let mut _3: (u8, u8); // in scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 - StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 - StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 - Deinit(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 - (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 - (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 - Deinit(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 -- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 -+ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 - StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19 - _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 + StorageLive(_1); // scope 0 at $DIR/issue_67019.rs:+1:5: +1:20 + StorageLive(_2); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + StorageLive(_3); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + Deinit(_3); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17 + Deinit(_2); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 +- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 ++ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19 + StorageDead(_3); // scope 0 at $DIR/issue_67019.rs:+1:18: +1:19 + _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue_67019.rs:+1:5: +1:20 // mir::Constant - // + span: $DIR/issue-67019.rs:12:5: 12:9 + // + span: $DIR/issue_67019.rs:12:5: 12:9 // + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value() } } bb1: { - StorageDead(_2); // scope 0 at $DIR/issue-67019.rs:+1:19: +1:20 - StorageDead(_1); // scope 0 at $DIR/issue-67019.rs:+1:20: +1:21 - nop; // scope 0 at $DIR/issue-67019.rs:+0:11: +2:2 - return; // scope 0 at $DIR/issue-67019.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue_67019.rs:+1:19: +1:20 + StorageDead(_1); // scope 0 at $DIR/issue_67019.rs:+1:20: +1:21 + nop; // scope 0 at $DIR/issue_67019.rs:+0:11: +2:2 + return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue_67019.rs similarity index 100% rename from src/test/mir-opt/const_prop/issue-67019.rs rename to src/test/mir-opt/const_prop/issue_67019.rs diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index 96716a39a2bfd..08481777ed494 100644 --- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -1,83 +1,83 @@ // MIR for `match_tuple` after SimplifyCfg-initial fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { - debug x => _1; // in scope 0 at $DIR/exponential-or.rs:+0:16: +0:17 - let mut _0: u32; // return place in scope 0 at $DIR/exponential-or.rs:+0:53: +0:56 - let mut _2: isize; // in scope 0 at $DIR/exponential-or.rs:+2:37: +2:48 - let mut _3: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 - let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 - let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 - let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 - let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 - let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 - let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84 - let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + debug x => _1; // in scope 0 at $DIR/exponential_or.rs:+0:16: +0:17 + let mut _0: u32; // return place in scope 0 at $DIR/exponential_or.rs:+0:53: +0:56 + let mut _2: isize; // in scope 0 at $DIR/exponential_or.rs:+2:37: +2:48 + let mut _3: bool; // in scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + let mut _4: bool; // in scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + let mut _5: bool; // in scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + let mut _6: bool; // in scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + let _7: u32; // in scope 0 at $DIR/exponential_or.rs:+2:10: +2:11 + let _8: u32; // in scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + let mut _9: u32; // in scope 0 at $DIR/exponential_or.rs:+2:83: +2:84 + let mut _10: u32; // in scope 0 at $DIR/exponential_or.rs:+2:87: +2:88 scope 1 { - debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:11 - debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:58 + debug y => _7; // in scope 1 at $DIR/exponential_or.rs:+2:10: +2:11 + debug z => _8; // in scope 1 at $DIR/exponential_or.rs:+2:57: +2:58 } bb0: { - FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential-or.rs:+1:11: +1:12 - switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:15: +2:20 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential_or.rs:+1:11: +1:12 + switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:15: +2:20 } bb1: { - _0 = const 0_u32; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15 - goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15 + _0 = const 0_u32; // scope 0 at $DIR/exponential_or.rs:+3:14: +3:15 + goto -> bb10; // scope 0 at $DIR/exponential_or.rs:+3:14: +3:15 } bb2: { - _2 = discriminant((_1.2: std::option::Option)); // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 - switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 + _2 = discriminant((_1.2: std::option::Option)); // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 + switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 } bb3: { - switchInt((((_1.2: std::option::Option) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 + switchInt((((_1.2: std::option::Option) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 } bb4: { - _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 - switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 } bb5: { - _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 - switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 } bb6: { - _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 - switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 } bb7: { - _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 - switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 } bb8: { - falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:9: +2:79 + falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:9: +2:79 } bb9: { - StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 - _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 - StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 - _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 - StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 - _9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 - StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 - _10 = _8; // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 - _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:88 - StorageDead(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 - StorageDead(_9); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 - StorageDead(_8); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 - StorageDead(_7); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 - goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + StorageLive(_7); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11 + _7 = (_1.0: u32); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11 + StorageLive(_8); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + _8 = (_1.3: u32); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + StorageLive(_9); // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84 + _9 = _7; // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84 + StorageLive(_10); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88 + _10 = _8; // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88 + _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential_or.rs:+2:83: +2:88 + StorageDead(_10); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88 + StorageDead(_9); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88 + StorageDead(_8); // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88 + StorageDead(_7); // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88 + goto -> bb10; // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88 } bb10: { - return; // scope 0 at $DIR/exponential-or.rs:+5:2: +5:2 + return; // scope 0 at $DIR/exponential_or.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential_or.rs similarity index 100% rename from src/test/mir-opt/exponential-or.rs rename to src/test/mir-opt/exponential_or.rs diff --git a/src/test/mir-opt/fn-ptr-shim.rs b/src/test/mir-opt/fn_ptr_shim.rs similarity index 100% rename from src/test/mir-opt/fn-ptr-shim.rs rename to src/test/mir-opt/fn_ptr_shim.rs diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir index c718138b6b37e..c3b08bf064892 100644 --- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir +++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir @@ -14,71 +14,71 @@ }, } */ -fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () { - let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15 - let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14 - let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14 - let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:18: +0:18 - let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 +fn main::{closure#0}(_1: *mut [generator@$DIR/generator_drop_cleanup.rs:10:15: 10:17]) -> () { + let mut _0: (); // return place in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let mut _2: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let _3: std::string::String; // in scope 0 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15 + let _4: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14 + let mut _5: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14 + let mut _6: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:18: +0:18 + let mut _7: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + let mut _8: u32; // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 scope 1 { - debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15 + debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15 } bb0: { - _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + _8 = discriminant((*_1)); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb1: { - StorageDead(_5); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:13: +2:14 - StorageDead(_4); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:14: +2:15 - drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + StorageDead(_5); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:13: +2:14 + StorageDead(_4); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:14: +2:15 + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 } bb2: { - nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 - goto -> bb8; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + nop; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + goto -> bb8; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 } bb3: { - return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb4 (cleanup): { - resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + resume; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb5 (cleanup): { - nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 - goto -> bb4; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + nop; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 + goto -> bb4; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 } bb6: { - return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb7: { - goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + goto -> bb9; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb8: { - goto -> bb3; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + goto -> bb3; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6 } bb9: { - goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + goto -> bb6; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb10: { - StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 - goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + StorageLive(_4); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + StorageLive(_5); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + goto -> bb1; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb11: { - return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6 + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } } diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator_drop_cleanup.rs similarity index 100% rename from src/test/mir-opt/generator-drop-cleanup.rs rename to src/test/mir-opt/generator_drop_cleanup.rs diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir index 3184343f207b3..cfbe0aaf252dd 100644 --- a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir +++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir @@ -1,124 +1,124 @@ // MIR for `main::{closure#0}` before StateTransform -fn main::{closure#0}(_1: [generator@$DIR/generator-storage-dead-unwind.rs:22:16: 22:18], _2: ()) -> () +fn main::{closure#0}(_1: [generator@$DIR/generator_storage_dead_unwind.rs:22:16: 22:18], _2: ()) -> () yields () { - let mut _0: (); // return place in scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +0:19 - let _3: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 - let _5: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 - let mut _6: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 - let _7: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 - let mut _8: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 - let _9: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 - let mut _10: Bar; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 + let mut _0: (); // return place in scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +0:19 + let _3: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + let _5: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + let mut _6: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + let _7: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 + let mut _8: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + let _9: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 + let mut _10: Bar; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 scope 1 { - debug a => _3; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 - let _4: Bar; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 + debug a => _3; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + let _4: Bar; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 scope 2 { - debug b => _4; // in scope 2 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 + debug b => _4; // in scope 2 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 } } bb0: { - StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 - _3 = Foo(const 5_i32); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23 - StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 - _4 = Bar(const 6_i32); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23 - StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 - StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 - _6 = (); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 - _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + StorageLive(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14 + _3 = Foo(const 5_i32); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:17: +1:23 + StorageLive(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14 + _4 = Bar(const 6_i32); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:17: +2:23 + StorageLive(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + StorageLive(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + _6 = (); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 } bb1: { - StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14 - StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15 - StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 - StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 - _8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 - _7 = take::(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 + StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15 + StorageLive(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 + StorageLive(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + _8 = move _3; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15 + _7 = take::(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16 // mir::Constant - // + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13 + // + span: $DIR/generator_storage_dead_unwind.rs:26:9: 26:13 // + literal: Const { ty: fn(Foo) {take::}, val: Value() } } bb2: { - StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16 - StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17 - StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 - StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 - _10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 - _9 = take::(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 + StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16 + StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17 + StorageLive(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 + StorageLive(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 + _10 = move _4; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15 + _9 = take::(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16 // mir::Constant - // + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13 + // + span: $DIR/generator_storage_dead_unwind.rs:27:9: 27:13 // + literal: Const { ty: fn(Bar) {take::}, val: Value() } } bb3: { - StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16 - StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17 - _0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +6:6 - StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - goto -> bb4; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16 + StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17 + _0 = const (); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +6:6 + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + goto -> bb4; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb4: { - StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb5: { - return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:6: +6:6 + return; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:6: +6:6 } bb6: { - StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14 - StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15 - StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15 + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb7: { - StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb8: { - generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6 + generator_drop; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6 } bb9 (cleanup): { - StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16 - StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17 + StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16 + StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17 goto -> bb12; // scope 2 at no-location } bb10 (cleanup): { - goto -> bb11; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16 + goto -> bb11; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16 } bb11 (cleanup): { - StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16 - StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17 + StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16 + StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17 goto -> bb12; // scope 2 at no-location } bb12 (cleanup): { - StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - goto -> bb13; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + goto -> bb13; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb13 (cleanup): { - StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } bb14 (cleanup): { - resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6 + resume; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6 } bb15 (cleanup): { - StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 - drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 } } diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator_storage_dead_unwind.rs similarity index 100% rename from src/test/mir-opt/generator-storage-dead-unwind.rs rename to src/test/mir-opt/generator_storage_dead_unwind.rs diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir index 07aeeaae012c9..fee6da2c6352f 100644 --- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir +++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -14,71 +14,71 @@ }, } */ -fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> { - debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19 - let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15 - let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:+2:9: +5:10 - let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18 - let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18 - let _8: (); // in scope 0 at $DIR/generator-tiny.rs:+4:13: +4:21 - let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:+0:25: +0:25 - let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19 - let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 +fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> { + debug _x => _10; // in scope 0 at $DIR/generator_tiny.rs:+0:17: +0:19 + let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + let _3: HasDrop; // in scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15 + let mut _4: !; // in scope 0 at $DIR/generator_tiny.rs:+2:9: +5:10 + let mut _5: (); // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + let _6: u8; // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18 + let mut _7: (); // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18 + let _8: (); // in scope 0 at $DIR/generator_tiny.rs:+4:13: +4:21 + let mut _9: (); // in scope 0 at $DIR/generator_tiny.rs:+0:25: +0:25 + let _10: u8; // in scope 0 at $DIR/generator_tiny.rs:+0:17: +0:19 + let mut _11: u32; // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 scope 1 { - debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:+1:13: +1:15 + debug _d => (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator_tiny.rs:+1:13: +1:15 } bb0: { - _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 + _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 } bb1: { - _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - nop; // scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15 - (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25 - StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 - goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 + _10 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + nop; // scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15 + (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator_tiny.rs:+1:18: +1:25 + StorageLive(_4); // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10 + goto -> bb2; // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10 } bb2: { - StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - _7 = (); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 - return; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + StorageLive(_6); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + StorageLive(_7); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + _7 = (); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + Deinit(_0); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + discriminant(_0) = 0; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 + return; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18 } bb3: { - StorageDead(_7); // scope 1 at $DIR/generator-tiny.rs:+3:17: +3:18 - StorageDead(_6); // scope 1 at $DIR/generator-tiny.rs:+3:18: +3:19 - StorageLive(_8); // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21 - _8 = callee() -> bb4; // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21 + StorageDead(_7); // scope 1 at $DIR/generator_tiny.rs:+3:17: +3:18 + StorageDead(_6); // scope 1 at $DIR/generator_tiny.rs:+3:18: +3:19 + StorageLive(_8); // scope 1 at $DIR/generator_tiny.rs:+4:13: +4:21 + _8 = callee() -> bb4; // scope 1 at $DIR/generator_tiny.rs:+4:13: +4:21 // mir::Constant - // + span: $DIR/generator-tiny.rs:23:13: 23:19 + // + span: $DIR/generator_tiny.rs:23:13: 23:19 // + literal: Const { ty: fn() {callee}, val: Value() } } bb4: { - StorageDead(_8); // scope 1 at $DIR/generator-tiny.rs:+4:21: +4:22 - _5 = const (); // scope 1 at $DIR/generator-tiny.rs:+2:14: +5:10 - goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 + StorageDead(_8); // scope 1 at $DIR/generator_tiny.rs:+4:21: +4:22 + _5 = const (); // scope 1 at $DIR/generator_tiny.rs:+2:14: +5:10 + goto -> bb2; // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10 } bb5: { - StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 - goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 + StorageLive(_4); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + StorageLive(_6); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + StorageLive(_7); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + _6 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + goto -> bb3; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 } bb6: { - unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6 + unreachable; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 } } diff --git a/src/test/mir-opt/generator-tiny.rs b/src/test/mir-opt/generator_tiny.rs similarity index 100% rename from src/test/mir-opt/generator-tiny.rs rename to src/test/mir-opt/generator_tiny.rs diff --git a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff index 19b5ab44156f4..94180d2034399 100644 --- a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff @@ -2,29 +2,29 @@ + // MIR for `dont_opt_bool` after SimplifyComparisonIntegral fn dont_opt_bool(_1: bool) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:18: +0:19 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:30: +0:33 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:18: +0:19 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:30: +0:33 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _2 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _2 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 } bb1: { - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:12: +1:13 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:12: +1:13 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:26 } bb2: { - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:23: +1:24 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:23: +1:24 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:26 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:25: +1:26 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:25: +1:26 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff index 256af7b94be2c..b22c7eac622f5 100644 --- a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -2,33 +2,33 @@ + // MIR for `dont_opt_floats` after SimplifyComparisonIntegral fn dont_opt_floats(_1: f32) -> i32 { - debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:20: +0:21 - let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:31: +0:34 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 - let mut _3: f32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug a => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:20: +0:21 + let mut _0: i32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:31: +0:34 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 + let mut _3: f32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 - StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:17: +1:18 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 + StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:17: +1:18 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 } bb1: { - _0 = const 0_i32; // scope 0 at $DIR/if-condition-int.rs:+1:21: +1:22 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35 + _0 = const 0_i32; // scope 0 at $DIR/if_condition_int.rs:+1:21: +1:22 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:35 } bb2: { - _0 = const 1_i32; // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35 + _0 = const 1_i32; // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:35 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:34: +1:35 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:34: +1:35 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff index ed53c9a956ca8..cc0995f99cfdf 100644 --- a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -2,57 +2,57 @@ + // MIR for `dont_remove_comparison` after SimplifyComparisonIntegral fn dont_remove_comparison(_1: i8) -> i32 { - debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:27: +0:28 - let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:37: +0:40 - let _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10 - let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 - let mut _4: i32; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:31 - let mut _5: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:24 - let mut _6: i32; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:31 - let mut _7: bool; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:24 + debug a => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:27: +0:28 + let mut _0: i32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:37: +0:40 + let _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:9: +1:10 + let mut _3: i8; // in scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14 + let mut _4: i32; // in scope 0 at $DIR/if_condition_int.rs:+3:23: +3:31 + let mut _5: bool; // in scope 0 at $DIR/if_condition_int.rs:+3:23: +3:24 + let mut _6: i32; // in scope 0 at $DIR/if_condition_int.rs:+4:23: +4:31 + let mut _7: bool; // in scope 0 at $DIR/if_condition_int.rs:+4:23: +4:24 scope 1 { - debug b => _2; // in scope 1 at $DIR/if-condition-int.rs:+1:9: +1:10 + debug b => _2; // in scope 1 at $DIR/if_condition_int.rs:+1:9: +1:10 } bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 -- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 -- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 -+ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 -+ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14 +- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 +- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 ++ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 ++ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 } bb1: { -+ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 - StorageLive(_6); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31 - StorageLive(_7); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24 - _7 = _2; // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24 - _6 = move _7 as i32 (IntToInt); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31 - StorageDead(_7); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 - _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if-condition-int.rs:+4:17: +4:31 - StorageDead(_6); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 - goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 ++ StorageDead(_3); // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 + StorageLive(_6); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:31 + StorageLive(_7); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:24 + _7 = _2; // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:24 + _6 = move _7 as i32 (IntToInt); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:31 + StorageDead(_7); // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31 + _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if_condition_int.rs:+4:17: +4:31 + StorageDead(_6); // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31 + goto -> bb3; // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31 } bb2: { -+ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 - StorageLive(_4); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31 - StorageLive(_5); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24 - _5 = _2; // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24 - _4 = move _5 as i32 (IntToInt); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31 - StorageDead(_5); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 - _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if-condition-int.rs:+3:18: +3:31 - StorageDead(_4); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 - goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 ++ StorageDead(_3); // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 + StorageLive(_4); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:31 + StorageLive(_5); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:24 + _5 = _2; // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:24 + _4 = move _5 as i32 (IntToInt); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:31 + StorageDead(_5); // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31 + _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if_condition_int.rs:+3:18: +3:31 + StorageDead(_4); // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31 + goto -> bb3; // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+6:1: +6:2 - return; // scope 0 at $DIR/if-condition-int.rs:+6:2: +6:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+6:1: +6:2 + return; // scope 0 at $DIR/if_condition_int.rs:+6:2: +6:2 } } diff --git a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index 9b64c379fee77..801ea04020343 100644 --- a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -2,38 +2,38 @@ + // MIR for `opt_char` after SimplifyComparisonIntegral fn opt_char(_1: char) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:13: +0:14 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:25: +0:28 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - let mut _3: char; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:13: +0:14 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:25: +0:28 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + let mut _3: char; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 -- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 -+ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 ++ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 } bb1: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33 } bb2: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:30: +1:31 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index 8042d63bb34dd..4297f4d646645 100644 --- a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -2,38 +2,38 @@ + // MIR for `opt_i8` after SimplifyComparisonIntegral fn opt_i8(_1: i8) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:11: +0:12 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:24 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:11: +0:12 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + let mut _3: i8; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 -- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:18: +1:19 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32 } bb2: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:29: +1:30 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:31: +1:32 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index a408de1ef3e97..8fb794abbd41f 100644 --- a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -2,64 +2,64 @@ + // MIR for `opt_multiple_ifs` after SimplifyComparisonIntegral fn opt_multiple_ifs(_1: u32) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:22 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:32: +0:35 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - let mut _4: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 - let mut _5: u32; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:21: +0:22 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:32: +0:35 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + let mut _3: u32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + let mut _4: bool; // in scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + let mut _5: u32; // in scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 -- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+2:9: +2:10 - goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+2:9: +2:10 + goto -> bb6; // scope 0 at $DIR/if_condition_int.rs:+1:5: +7:6 } bb2: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - StorageLive(_4); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 - StorageLive(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 - _5 = _1; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 -- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 -- StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22 -- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22 -+ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + StorageLive(_4); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + StorageLive(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16 + _5 = _1; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16 +- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 +- StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22 +- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22 ++ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 } bb3: { -+ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+4:9: +4:10 - goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6 ++ StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+4:9: +4:10 + goto -> bb5; // scope 0 at $DIR/if_condition_int.rs:+3:12: +7:6 } bb4: { -+ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 - _0 = const 2_u32; // scope 0 at $DIR/if-condition-int.rs:+6:9: +6:10 - goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6 ++ StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + _0 = const 2_u32; // scope 0 at $DIR/if_condition_int.rs:+6:9: +6:10 + goto -> bb5; // scope 0 at $DIR/if_condition_int.rs:+3:12: +7:6 } bb5: { - StorageDead(_4); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6 - goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6 + StorageDead(_4); // scope 0 at $DIR/if_condition_int.rs:+7:5: +7:6 + goto -> bb6; // scope 0 at $DIR/if_condition_int.rs:+1:5: +7:6 } bb6: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6 - return; // scope 0 at $DIR/if-condition-int.rs:+8:2: +8:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+7:5: +7:6 + return; // scope 0 at $DIR/if_condition_int.rs:+8:2: +8:2 } } diff --git a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index 6802f89d9278b..992253ea780d9 100644 --- a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -2,38 +2,38 @@ + // MIR for `opt_negative` after SimplifyComparisonIntegral fn opt_negative(_1: i32) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:17: +0:18 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:28: +0:31 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - let mut _3: i32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:17: +0:18 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:28: +0:31 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + let mut _3: i32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 -- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 -+ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 ++ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 } bb1: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33 } bb2: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:30: +1:31 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 96387771d06f1..7cea9472d3a05 100644 --- a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -2,38 +2,38 @@ + // MIR for `opt_u32` after SimplifyComparisonIntegral fn opt_u32(_1: u32) -> u32 { - debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:12: +0:13 - let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:23: +0:26 - let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:12: +0:13 + let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:23: +0:26 + let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + let mut _3: u32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 -- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 -+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:18: +1:19 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32 } bb2: { -+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 - _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30 - goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 ++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:29: +1:30 + goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32 } bb3: { - StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32 - return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:31: +1:32 + return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/if-condition-int.rs b/src/test/mir-opt/if_condition_int.rs similarity index 100% rename from src/test/mir-opt/if-condition-int.rs rename to src/test/mir-opt/if_condition_int.rs diff --git a/src/test/mir-opt/inline/asm_unwind.main.Inline.diff b/src/test/mir-opt/inline/asm_unwind.main.Inline.diff index 57072fc0ad392..f1b62ac38ba4b 100644 --- a/src/test/mir-opt/inline/asm_unwind.main.Inline.diff +++ b/src/test/mir-opt/inline/asm_unwind.main.Inline.diff @@ -2,44 +2,44 @@ + // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/asm-unwind.rs:+0:15: +0:15 - let _1: (); // in scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10 -+ scope 1 (inlined foo) { // at $DIR/asm-unwind.rs:21:5: 21:10 -+ let _2: D; // in scope 1 at $DIR/asm-unwind.rs:15:9: 15:11 + let mut _0: (); // return place in scope 0 at $DIR/asm_unwind.rs:+0:15: +0:15 + let _1: (); // in scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 ++ scope 1 (inlined foo) { // at $DIR/asm_unwind.rs:21:5: 21:10 ++ let _2: D; // in scope 1 at $DIR/asm_unwind.rs:15:9: 15:11 + scope 2 { -+ debug _d => _2; // in scope 2 at $DIR/asm-unwind.rs:15:9: 15:11 ++ debug _d => _2; // in scope 2 at $DIR/asm_unwind.rs:15:9: 15:11 + scope 3 { + } + } + } bb0: { - StorageLive(_1); // scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10 -- _1 = foo() -> bb1; // scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10 + StorageLive(_1); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 +- _1 = foo() -> bb1; // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 - // mir::Constant -- // + span: $DIR/asm-unwind.rs:21:5: 21:8 +- // + span: $DIR/asm_unwind.rs:21:5: 21:8 - // + literal: Const { ty: fn() {foo}, val: Value() } -+ StorageLive(_2); // scope 1 at $DIR/asm-unwind.rs:15:9: 15:11 -+ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm-unwind.rs:16:14: 16:54 ++ StorageLive(_2); // scope 1 at $DIR/asm_unwind.rs:15:9: 15:11 ++ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm_unwind.rs:16:14: 16:54 } bb1: { -+ drop(_2) -> bb2; // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2 ++ drop(_2) -> bb2; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 + } + + bb2: { -+ StorageDead(_2); // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2 - StorageDead(_1); // scope 0 at $DIR/asm-unwind.rs:+1:10: +1:11 - _0 = const (); // scope 0 at $DIR/asm-unwind.rs:+0:15: +2:2 - return; // scope 0 at $DIR/asm-unwind.rs:+2:2: +2:2 ++ StorageDead(_2); // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 + StorageDead(_1); // scope 0 at $DIR/asm_unwind.rs:+1:10: +1:11 + _0 = const (); // scope 0 at $DIR/asm_unwind.rs:+0:15: +2:2 + return; // scope 0 at $DIR/asm_unwind.rs:+2:2: +2:2 + } + + bb3 (cleanup): { -+ drop(_2) -> bb4; // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2 ++ drop(_2) -> bb4; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 + } + + bb4 (cleanup): { -+ resume; // scope 1 at $DIR/asm-unwind.rs:14:1: 17:2 ++ resume; // scope 1 at $DIR/asm_unwind.rs:14:1: 17:2 } } diff --git a/src/test/mir-opt/inline/asm-unwind.rs b/src/test/mir-opt/inline/asm_unwind.rs similarity index 100% rename from src/test/mir-opt/inline/asm-unwind.rs rename to src/test/mir-opt/inline/asm_unwind.rs diff --git a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff index d7deb9c66cfa0..8b03006782b2c 100644 --- a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff +++ b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff @@ -2,32 +2,32 @@ + // MIR for `foo` after Inline fn foo() -> () { - let mut _0: (); // return place in scope 0 at $DIR/caller-with-trivial-bound.rs:+1:1: +1:1 - let mut _1: >::Item; // in scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 + let mut _0: (); // return place in scope 0 at $DIR/caller_with_trivial_bound.rs:+1:1: +1:1 + let mut _1: >::Item; // in scope 0 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14 scope 1 { - debug x => _1; // in scope 1 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 + debug x => _1; // in scope 1 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14 } bb0: { - StorageLive(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 - _1 = bar::() -> bb1; // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:51: +4:61 + StorageLive(_1); // scope 0 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14 + _1 = bar::() -> bb1; // scope 0 at $DIR/caller_with_trivial_bound.rs:+4:51: +4:61 // mir::Constant - // + span: $DIR/caller-with-trivial-bound.rs:20:51: 20:59 + // + span: $DIR/caller_with_trivial_bound.rs:20:51: 20:59 // + literal: Const { ty: fn() -> >::Item {bar::}, val: Value() } } bb1: { - _0 = const (); // scope 0 at $DIR/caller-with-trivial-bound.rs:+3:1: +5:2 - drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2 + _0 = const (); // scope 0 at $DIR/caller_with_trivial_bound.rs:+3:1: +5:2 + drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:1: +5:2 } bb2: { - StorageDead(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2 - return; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:2: +5:2 + StorageDead(_1); // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:1: +5:2 + return; // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:2: +5:2 } bb3 (cleanup): { - resume; // scope 0 at $DIR/caller-with-trivial-bound.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/caller_with_trivial_bound.rs:+0:1: +5:2 } } diff --git a/src/test/mir-opt/inline/caller-with-trivial-bound.rs b/src/test/mir-opt/inline/caller_with_trivial_bound.rs similarity index 100% rename from src/test/mir-opt/inline/caller-with-trivial-bound.rs rename to src/test/mir-opt/inline/caller_with_trivial_bound.rs diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff index 1e95b5b29ff4e..284306a352d15 100644 --- a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff +++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff @@ -2,61 +2,61 @@ + // MIR for `get_query` after Inline fn get_query(_1: &T) -> () { - debug t => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:31: +0:32 - let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:38: +0:38 - let _2: &::C; // in scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10 - let mut _3: &T; // in scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 - let mut _4: &::C; // in scope 0 at $DIR/dyn-trait.rs:+2:23: +2:24 + debug t => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:31: +0:32 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:38: +0:38 + let _2: &::C; // in scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10 + let mut _3: &T; // in scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + let mut _4: &::C; // in scope 0 at $DIR/dyn_trait.rs:+2:23: +2:24 scope 1 { - debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+1:9: +1:10 -+ scope 2 (inlined try_execute_query::<::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25 -+ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:26:36: 26:37 -+ let mut _5: &dyn Cache::V>; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ let mut _6: &::C; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ scope 3 (inlined mk_cycle::<::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16 -+ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:20:27: 20:28 -+ let mut _7: &dyn Cache::V>; // in scope 3 at $DIR/dyn-trait.rs:21:5: 21:22 + debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:+1:9: +1:10 ++ scope 2 (inlined try_execute_query::<::C>) { // at $DIR/dyn_trait.rs:34:5: 34:25 ++ debug c => _4; // in scope 2 at $DIR/dyn_trait.rs:26:36: 26:37 ++ let mut _5: &dyn Cache::V>; // in scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ let mut _6: &::C; // in scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ scope 3 (inlined mk_cycle::<::V>) { // at $DIR/dyn_trait.rs:27:5: 27:16 ++ debug c => _5; // in scope 3 at $DIR/dyn_trait.rs:20:27: 20:28 ++ let mut _7: &dyn Cache::V>; // in scope 3 at $DIR/dyn_trait.rs:21:5: 21:22 + } + } } bb0: { - StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 - _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 - _2 = ::cache::(move _3) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:13: +1:24 + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23 + _2 = ::cache::(move _3) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:13: +1:24 // mir::Constant - // + span: $DIR/dyn-trait.rs:33:13: 33:21 + // + span: $DIR/dyn_trait.rs:33:13: 33:21 // + user_ty: UserType(0) // + literal: Const { ty: for<'a> fn(&'a T) -> &'a ::C {::cache::}, val: Value() } } bb1: { - StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:23: +1:24 - StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24 - _4 = &(*_2); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24 -- _0 = try_execute_query::<::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:+2:5: +2:25 -+ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ _5 = move _6 as &dyn Cache::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15 -+ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22 -+ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22 -+ _0 = ::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22 + StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:23: +1:24 + StorageLive(_4); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24 + _4 = &(*_2); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24 +- _0 = try_execute_query::<::C>(move _4) -> bb2; // scope 1 at $DIR/dyn_trait.rs:+2:5: +2:25 ++ StorageLive(_5); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ StorageLive(_6); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ _6 = _4; // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ _5 = move _6 as &dyn Cache::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ StorageDead(_6); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ StorageLive(_7); // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22 ++ _7 = _5; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22 ++ _0 = ::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22 // mir::Constant -- // + span: $DIR/dyn-trait.rs:34:5: 34:22 +- // + span: $DIR/dyn_trait.rs:34:5: 34:22 - // + literal: Const { ty: for<'a> fn(&'a ::C) {try_execute_query::<::C>}, val: Value() } -+ // + span: $DIR/dyn-trait.rs:21:7: 21:20 ++ // + span: $DIR/dyn_trait.rs:21:7: 21:20 + // + literal: Const { ty: for<'a> fn(&'a dyn Cache::V>) {::V> as Cache>::store_nocache}, val: Value() } } bb2: { -+ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:21:21: 21:22 -+ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:27:15: 27:16 - StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+2:24: +2:25 - StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+3:1: +3:2 - return; // scope 0 at $DIR/dyn-trait.rs:+3:2: +3:2 ++ StorageDead(_7); // scope 3 at $DIR/dyn_trait.rs:21:21: 21:22 ++ StorageDead(_5); // scope 2 at $DIR/dyn_trait.rs:27:15: 27:16 + StorageDead(_4); // scope 1 at $DIR/dyn_trait.rs:+2:24: +2:25 + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+3:1: +3:2 + return; // scope 0 at $DIR/dyn_trait.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff index 7421db4d063af..7653a5ded440a 100644 --- a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff +++ b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff @@ -2,22 +2,22 @@ + // MIR for `mk_cycle` after Inline fn mk_cycle(_1: &dyn Cache) -> () { - debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:27: +0:28 - let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:49: +0:49 - let mut _2: &dyn Cache; // in scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:27: +0:28 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:49: +0:49 + let mut _2: &dyn Cache; // in scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 bb0: { - StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 - _2 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 - _0 = as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + _2 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 + _0 = as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22 // mir::Constant - // + span: $DIR/dyn-trait.rs:21:7: 21:20 + // + span: $DIR/dyn_trait.rs:21:7: 21:20 // + literal: Const { ty: for<'a> fn(&'a dyn Cache) { as Cache>::store_nocache}, val: Value() } } bb1: { - StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:21: +1:22 - return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:21: +1:22 + return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/dyn-trait.rs b/src/test/mir-opt/inline/dyn_trait.rs similarity index 100% rename from src/test/mir-opt/inline/dyn-trait.rs rename to src/test/mir-opt/inline/dyn_trait.rs diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff index e6e783744227e..0191045f3d1a5 100644 --- a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff +++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff @@ -2,36 +2,36 @@ + // MIR for `try_execute_query` after Inline fn try_execute_query(_1: &C) -> () { - debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:36: +0:37 - let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:43: +0:43 - let mut _2: &dyn Cache::V>; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 - let mut _3: &C; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 -+ scope 1 (inlined mk_cycle::<::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16 -+ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:20:27: 20:28 -+ let mut _4: &dyn Cache::V>; // in scope 1 at $DIR/dyn-trait.rs:21:5: 21:22 + debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:36: +0:37 + let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:43: +0:43 + let mut _2: &dyn Cache::V>; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + let mut _3: &C; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 ++ scope 1 (inlined mk_cycle::<::V>) { // at $DIR/dyn_trait.rs:27:5: 27:16 ++ debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:20:27: 20:28 ++ let mut _4: &dyn Cache::V>; // in scope 1 at $DIR/dyn_trait.rs:21:5: 21:22 + } bb0: { - StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 - StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 - _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 - _2 = move _3 as &dyn Cache::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 - StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 -- _0 = mk_cycle::<::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:16 -+ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22 -+ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22 -+ _0 = ::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22 + StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + _2 = move _3 as &dyn Cache::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 + StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15 +- _0 = mk_cycle::<::V>(move _2) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:16 ++ StorageLive(_4); // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22 ++ _4 = _2; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22 ++ _0 = ::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22 // mir::Constant -- // + span: $DIR/dyn-trait.rs:27:5: 27:13 +- // + span: $DIR/dyn_trait.rs:27:5: 27:13 - // + literal: Const { ty: for<'a> fn(&'a (dyn Cache::V> + 'a)) {mk_cycle::<::V>}, val: Value() } -+ // + span: $DIR/dyn-trait.rs:21:7: 21:20 ++ // + span: $DIR/dyn_trait.rs:21:7: 21:20 + // + literal: Const { ty: for<'a> fn(&'a dyn Cache::V>) {::V> as Cache>::store_nocache}, val: Value() } } bb1: { -+ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22 - StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:15: +1:16 - return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2 ++ StorageDead(_4); // scope 1 at $DIR/dyn_trait.rs:21:21: 21:22 + StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:15: +1:16 + return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir index b27425fb18c28..8956c80dcd2a9 100644 --- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -1,44 +1,44 @@ // MIR for `bar` after Inline fn bar() -> bool { - let mut _0: bool; // return place in scope 0 at $DIR/inline-any-operand.rs:+0:13: +0:17 - let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10 - let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:6 - let mut _3: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13 - let mut _4: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13 + let mut _0: bool; // return place in scope 0 at $DIR/inline_any_operand.rs:+0:13: +0:17 + let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline_any_operand.rs:+1:9: +1:10 + let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:6 + let mut _3: i32; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:13 + let mut _4: i32; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:13 scope 1 { - debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:+1:9: +1:10 - scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13 - debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:16:8: 16:9 - debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:16:16: 16:17 - let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6 - let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 + debug f => _1; // in scope 1 at $DIR/inline_any_operand.rs:+1:9: +1:10 + scope 2 (inlined foo) { // at $DIR/inline_any_operand.rs:12:5: 12:13 + debug x => _3; // in scope 2 at $DIR/inline_any_operand.rs:16:8: 16:9 + debug y => _4; // in scope 2 at $DIR/inline_any_operand.rs:16:16: 16:17 + let mut _5: i32; // in scope 2 at $DIR/inline_any_operand.rs:17:5: 17:6 + let mut _6: i32; // in scope 2 at $DIR/inline_any_operand.rs:17:10: 17:11 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10 - _1 = foo; // scope 0 at $DIR/inline-any-operand.rs:+1:13: +1:16 + StorageLive(_1); // scope 0 at $DIR/inline_any_operand.rs:+1:9: +1:10 + _1 = foo; // scope 0 at $DIR/inline_any_operand.rs:+1:13: +1:16 // mir::Constant - // + span: $DIR/inline-any-operand.rs:11:13: 11:16 + // + span: $DIR/inline_any_operand.rs:11:13: 11:16 // + literal: Const { ty: fn(i32, i32) -> bool {foo}, val: Value() } - StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6 - _2 = _1; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6 - StorageLive(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6 - _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6 - StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11 - StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 - StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:12: +2:13 - StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:+3:1: +3:2 - return; // scope 0 at $DIR/inline-any-operand.rs:+3:2: +3:2 + StorageLive(_2); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:6 + _2 = _1; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + _3 = const 1_i32; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + StorageLive(_4); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + _4 = const -1_i32; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + StorageLive(_5); // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:6 + _5 = _3; // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:6 + StorageLive(_6); // scope 2 at $DIR/inline_any_operand.rs:17:10: 17:11 + _6 = _4; // scope 2 at $DIR/inline_any_operand.rs:17:10: 17:11 + _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:11 + StorageDead(_6); // scope 2 at $DIR/inline_any_operand.rs:17:10: 17:11 + StorageDead(_5); // scope 2 at $DIR/inline_any_operand.rs:17:10: 17:11 + StorageDead(_4); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + StorageDead(_3); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13 + StorageDead(_2); // scope 1 at $DIR/inline_any_operand.rs:+2:12: +2:13 + StorageDead(_1); // scope 0 at $DIR/inline_any_operand.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline_any_operand.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/inline-any-operand.rs b/src/test/mir-opt/inline/inline_any_operand.rs similarity index 100% rename from src/test/mir-opt/inline/inline-any-operand.rs rename to src/test/mir-opt/inline/inline_any_operand.rs diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline_async.rs similarity index 100% rename from src/test/mir-opt/inline/inline-async.rs rename to src/test/mir-opt/inline/inline_async.rs diff --git a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir index 1fadd2464798d..9eb3a01eef91a 100644 --- a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir @@ -1,49 +1,49 @@ // MIR for `foo` after Inline fn foo(_1: T, _2: i32) -> i32 { - debug _t => _1; // in scope 0 at $DIR/inline-closure.rs:+0:17: +0:19 - debug q => _2; // in scope 0 at $DIR/inline-closure.rs:+0:24: +0:25 - let mut _0: i32; // return place in scope 0 at $DIR/inline-closure.rs:+0:35: +0:38 - let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+1:9: +1:10 - let mut _4: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:6 - let mut _5: (i32, i32); // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 - let mut _6: i32; // in scope 0 at $DIR/inline-closure.rs:+2:7: +2:8 - let mut _7: i32; // in scope 0 at $DIR/inline-closure.rs:+2:10: +2:11 - let mut _8: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 - let mut _9: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 + debug _t => _1; // in scope 0 at $DIR/inline_closure.rs:+0:17: +0:19 + debug q => _2; // in scope 0 at $DIR/inline_closure.rs:+0:24: +0:25 + let mut _0: i32; // return place in scope 0 at $DIR/inline_closure.rs:+0:35: +0:38 + let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure.rs:+1:9: +1:10 + let mut _4: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:6 + let mut _5: (i32, i32); // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12 + let mut _6: i32; // in scope 0 at $DIR/inline_closure.rs:+2:7: +2:8 + let mut _7: i32; // in scope 0 at $DIR/inline_closure.rs:+2:10: +2:11 + let mut _8: i32; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12 + let mut _9: i32; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12 scope 1 { - debug x => _3; // in scope 1 at $DIR/inline-closure.rs:+1:9: +1:10 - scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline-closure.rs:12:5: 12:12 - debug _t => _8; // in scope 2 at $DIR/inline-closure.rs:+1:14: +1:16 - debug _q => _9; // in scope 2 at $DIR/inline-closure.rs:+1:18: +1:20 + debug x => _3; // in scope 1 at $DIR/inline_closure.rs:+1:9: +1:10 + scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline_closure.rs:12:5: 12:12 + debug _t => _8; // in scope 2 at $DIR/inline_closure.rs:+1:14: +1:16 + debug _q => _9; // in scope 2 at $DIR/inline_closure.rs:+1:18: +1:20 } } bb0: { - StorageLive(_3); // scope 0 at $DIR/inline-closure.rs:+1:9: +1:10 - Deinit(_3); // scope 0 at $DIR/inline-closure.rs:+1:13: +1:24 - StorageLive(_4); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6 - _4 = &_3; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6 - StorageLive(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - StorageLive(_6); // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8 - _6 = _2; // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8 - StorageLive(_7); // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11 - _7 = _2; // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11 - Deinit(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - (_5.0: i32) = move _6; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - (_5.1: i32) = move _7; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - StorageLive(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - _8 = move (_5.0: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - StorageLive(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - _9 = move (_5.1: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - _0 = _8; // scope 2 at $DIR/inline-closure.rs:+1:22: +1:24 - StorageDead(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - StorageDead(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 - StorageDead(_7); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 - StorageDead(_6); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 - StorageDead(_5); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 - StorageDead(_4); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 - StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:+3:1: +3:2 - return; // scope 0 at $DIR/inline-closure.rs:+3:2: +3:2 + StorageLive(_3); // scope 0 at $DIR/inline_closure.rs:+1:9: +1:10 + Deinit(_3); // scope 0 at $DIR/inline_closure.rs:+1:13: +1:24 + StorageLive(_4); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:6 + _4 = &_3; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:6 + StorageLive(_5); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + StorageLive(_6); // scope 1 at $DIR/inline_closure.rs:+2:7: +2:8 + _6 = _2; // scope 1 at $DIR/inline_closure.rs:+2:7: +2:8 + StorageLive(_7); // scope 1 at $DIR/inline_closure.rs:+2:10: +2:11 + _7 = _2; // scope 1 at $DIR/inline_closure.rs:+2:10: +2:11 + Deinit(_5); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + (_5.0: i32) = move _6; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + (_5.1: i32) = move _7; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + StorageLive(_8); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + _8 = move (_5.0: i32); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + StorageLive(_9); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + _9 = move (_5.1: i32); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + _0 = _8; // scope 2 at $DIR/inline_closure.rs:+1:22: +1:24 + StorageDead(_9); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + StorageDead(_8); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12 + StorageDead(_7); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12 + StorageDead(_6); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12 + StorageDead(_5); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12 + StorageDead(_4); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12 + StorageDead(_3); // scope 0 at $DIR/inline_closure.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline_closure.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/inline-closure.rs b/src/test/mir-opt/inline/inline_closure.rs similarity index 100% rename from src/test/mir-opt/inline/inline-closure.rs rename to src/test/mir-opt/inline/inline_closure.rs diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir index 4069e9f89c8d8..e6275ac7f5dd9 100644 --- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -1,56 +1,56 @@ // MIR for `foo` after Inline fn foo(_1: T, _2: &i32) -> i32 { - debug _t => _1; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:17: +0:19 - debug q => _2; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:24: +0:25 - let mut _0: i32; // return place in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:36: +0:39 - let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 - let mut _4: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 - let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - let mut _6: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 - let mut _7: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 - let mut _8: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - let mut _9: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + debug _t => _1; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:17: +0:19 + debug q => _2; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:24: +0:25 + let mut _0: i32; // return place in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:36: +0:39 + let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10 + let mut _4: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6 + let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + let mut _6: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8 + let mut _7: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11 + let mut _8: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + let mut _9: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 scope 1 { - debug x => _3; // in scope 1 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 - scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 - debug r => _8; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:14: +1:15 - debug _s => _9; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:23: +1:25 - let _10: &i32; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 + debug x => _3; // in scope 1 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10 + scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline_closure_borrows_arg.rs:16:5: 16:12 + debug r => _8; // in scope 2 at $DIR/inline_closure_borrows_arg.rs:+1:14: +1:15 + debug _s => _9; // in scope 2 at $DIR/inline_closure_borrows_arg.rs:+1:23: +1:25 + let _10: &i32; // in scope 2 at $DIR/inline_closure_borrows_arg.rs:+2:13: +2:21 scope 3 { - debug variable => _10; // in scope 3 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 + debug variable => _10; // in scope 3 at $DIR/inline_closure_borrows_arg.rs:+2:13: +2:21 } } } bb0: { - StorageLive(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 - Deinit(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:13: +4:6 - StorageLive(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 - _4 = &_3; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 - StorageLive(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageLive(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 - _6 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 - StorageLive(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 - _7 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 - Deinit(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - (_5.0: &i32) = move _6; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - (_5.1: &i32) = move _7; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageLive(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - _8 = move (_5.0: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageLive(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 - _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:24: +2:27 - _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:+3:9: +3:18 - StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+4:5: +4:6 - StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 - StorageDead(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 - StorageDead(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 - StorageDead(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 - StorageDead(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 - StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:1: +6:2 - return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:2: +6:2 + StorageLive(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10 + Deinit(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:13: +4:6 + StorageLive(_4); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6 + _4 = &_3; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6 + StorageLive(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageLive(_6); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8 + _6 = &(*_2); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8 + StorageLive(_7); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11 + _7 = &(*_2); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11 + Deinit(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + (_5.0: &i32) = move _6; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + (_5.1: &i32) = move _7; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageLive(_8); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + _8 = move (_5.0: &i32); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageLive(_9); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + _9 = move (_5.1: &i32); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageLive(_10); // scope 2 at $DIR/inline_closure_borrows_arg.rs:+2:13: +2:21 + _10 = _8; // scope 2 at $DIR/inline_closure_borrows_arg.rs:+2:24: +2:27 + _0 = (*_10); // scope 3 at $DIR/inline_closure_borrows_arg.rs:+3:9: +3:18 + StorageDead(_10); // scope 2 at $DIR/inline_closure_borrows_arg.rs:+4:5: +4:6 + StorageDead(_9); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageDead(_8); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12 + StorageDead(_7); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12 + StorageDead(_6); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12 + StorageDead(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12 + StorageDead(_4); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12 + StorageDead(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+6:1: +6:2 + return; // scope 0 at $DIR/inline_closure_borrows_arg.rs:+6:2: +6:2 } } diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline_closure_borrows_arg.rs similarity index 100% rename from src/test/mir-opt/inline/inline-closure-borrows-arg.rs rename to src/test/mir-opt/inline/inline_closure_borrows_arg.rs diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index a2234e7c1effd..fd19c288666bd 100644 --- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -1,65 +1,65 @@ // MIR for `foo` after Inline fn foo(_1: T, _2: i32) -> (i32, T) { - debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:+0:17: +0:18 - debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:+0:23: +0:24 - let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:+0:34: +0:42 - let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10 - let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - let mut _6: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:6 - let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:7: +2:8 - let mut _9: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + debug t => _1; // in scope 0 at $DIR/inline_closure_captures.rs:+0:17: +0:18 + debug q => _2; // in scope 0 at $DIR/inline_closure_captures.rs:+0:23: +0:24 + let mut _0: (i32, T); // return place in scope 0 at $DIR/inline_closure_captures.rs:+0:34: +0:42 + let _3: [closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure_captures.rs:+1:9: +1:10 + let mut _4: &i32; // in scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + let mut _5: &T; // in scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + let mut _6: &[closure@foo::{closure#0}]; // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:6 + let mut _7: (i32,); // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + let mut _8: i32; // in scope 0 at $DIR/inline_closure_captures.rs:+2:7: +2:8 + let mut _9: i32; // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:9 scope 1 { - debug x => _3; // in scope 1 at $DIR/inline-closure-captures.rs:+1:9: +1:10 - scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline-closure-captures.rs:12:5: 12:9 - debug _q => _9; // in scope 2 at $DIR/inline-closure-captures.rs:+1:14: +1:16 - debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:23: +0:24 - debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:17: +0:18 - let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 - let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 - let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + debug x => _3; // in scope 1 at $DIR/inline_closure_captures.rs:+1:9: +1:10 + scope 2 (inlined foo::::{closure#0}) { // at $DIR/inline_closure_captures.rs:12:5: 12:9 + debug _q => _9; // in scope 2 at $DIR/inline_closure_captures.rs:+1:14: +1:16 + debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline_closure_captures.rs:+0:23: +0:24 + debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline_closure_captures.rs:+0:17: +0:18 + let mut _10: i32; // in scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20 + let mut _11: T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23 + let mut _12: &i32; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + let mut _13: &T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24 } } bb0: { - StorageLive(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10 - StorageLive(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - _4 = &_2; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - StorageLive(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - _5 = &_1; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - Deinit(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - (_3.0: &i32) = move _4; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - (_3.1: &T) = move _5; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 - StorageDead(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17 - StorageDead(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17 - StorageLive(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6 - _6 = &_3; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6 - StorageLive(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - StorageLive(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8 - _8 = _2; // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8 - Deinit(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - (_7.0: i32) = move _8; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 - _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 - _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 - StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 - _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 - _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 - Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 - (_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 - (_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 - StorageDead(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24 - StorageDead(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24 - StorageDead(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 - StorageDead(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 - StorageDead(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 - StorageDead(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 - StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:+3:1: +3:2 - return; // scope 0 at $DIR/inline-closure-captures.rs:+3:2: +3:2 + StorageLive(_3); // scope 0 at $DIR/inline_closure_captures.rs:+1:9: +1:10 + StorageLive(_4); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + _4 = &_2; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + StorageLive(_5); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + _5 = &_1; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + Deinit(_3); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + (_3.0: &i32) = move _4; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + (_3.1: &T) = move _5; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + StorageDead(_5); // scope 0 at $DIR/inline_closure_captures.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/inline_closure_captures.rs:+1:16: +1:17 + StorageLive(_6); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:6 + _6 = &_3; // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:6 + StorageLive(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + StorageLive(_8); // scope 1 at $DIR/inline_closure_captures.rs:+2:7: +2:8 + _8 = _2; // scope 1 at $DIR/inline_closure_captures.rs:+2:7: +2:8 + Deinit(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + (_7.0: i32) = move _8; // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + StorageLive(_9); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + _9 = move (_7.0: i32); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + StorageLive(_10); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20 + _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20 + _10 = (*_12); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20 + StorageLive(_11); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23 + _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23 + _11 = (*_13); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23 + Deinit(_0); // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24 + (_0.0: i32) = move _10; // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24 + (_0.1: T) = move _11; // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24 + StorageDead(_11); // scope 2 at $DIR/inline_closure_captures.rs:+1:23: +1:24 + StorageDead(_10); // scope 2 at $DIR/inline_closure_captures.rs:+1:23: +1:24 + StorageDead(_9); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9 + StorageDead(_8); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9 + StorageDead(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9 + StorageDead(_6); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9 + StorageDead(_3); // scope 0 at $DIR/inline_closure_captures.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline_closure_captures.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/inline-closure-captures.rs b/src/test/mir-opt/inline/inline_closure_captures.rs similarity index 100% rename from src/test/mir-opt/inline/inline-closure-captures.rs rename to src/test/mir-opt/inline/inline_closure_captures.rs diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff index cf800ba112945..e30a5e116ea4b 100644 --- a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff @@ -2,23 +2,23 @@ + // MIR for `inlined_no_sanitize` after Inline fn inlined_no_sanitize() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:37: +0:37 - let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 -+ scope 1 (inlined no_sanitize) { // at $DIR/inline-compatibility.rs:24:5: 24:18 + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:37: +0:37 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 ++ scope 1 (inlined no_sanitize) { // at $DIR/inline_compatibility.rs:24:5: 24:18 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 -- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 +- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 - // mir::Constant -- // + span: $DIR/inline-compatibility.rs:24:5: 24:16 +- // + span: $DIR/inline_compatibility.rs:24:5: 24:16 - // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } - } - - bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19 - _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:37: +2:2 - return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:37: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff index a45f959026d1c..c2b3c46a30c69 100644 --- a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff @@ -2,23 +2,23 @@ + // MIR for `inlined_target_feature` after Inline fn inlined_target_feature() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40 - let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 -+ scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:13:5: 13:21 + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 ++ scope 1 (inlined target_feature) { // at $DIR/inline_compatibility.rs:13:5: 13:21 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 -- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 +- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 - // mir::Constant -- // + span: $DIR/inline-compatibility.rs:13:5: 13:19 +- // + span: $DIR/inline_compatibility.rs:13:5: 13:19 - // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } - } - - bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22 - _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2 - return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff index 49aea431e46dd..0ca5a5f70b7fd 100644 --- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff @@ -2,24 +2,24 @@ + // MIR for `not_inlined_c_variadic` after Inline fn not_inlined_c_variadic() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40 - let _1: u32; // in scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10 + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40 + let _1: u32; // in scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10 scope 1 { - debug s => _1; // in scope 1 at $DIR/inline-compatibility.rs:+1:9: +1:10 + debug s => _1; // in scope 1 at $DIR/inline_compatibility.rs:+1:9: +1:10 } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10 - _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:13: +1:52 + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10 + _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:13: +1:52 // mir::Constant - // + span: $DIR/inline-compatibility.rs:42:13: 42:16 + // + span: $DIR/inline_compatibility.rs:42:13: 42:16 // + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value() } } bb1: { - _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2 - StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+2:1: +2:2 - return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff index 94ce574a94dc2..00d405c77f91d 100644 --- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff @@ -2,21 +2,21 @@ + // MIR for `not_inlined_no_sanitize` after Inline fn not_inlined_no_sanitize() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:41: +0:41 - let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:41: +0:41 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 - _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 + _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18 // mir::Constant - // + span: $DIR/inline-compatibility.rs:29:5: 29:16 + // + span: $DIR/inline_compatibility.rs:29:5: 29:16 // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19 - _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:41: +2:2 - return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:41: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff index 8506e257b3fe9..8b9c86f5515a3 100644 --- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff @@ -2,21 +2,21 @@ + // MIR for `not_inlined_target_feature` after Inline fn not_inlined_target_feature() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:44: +0:44 - let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:44: +0:44 + let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 - _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 + _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21 // mir::Constant - // + span: $DIR/inline-compatibility.rs:18:5: 18:19 + // + span: $DIR/inline_compatibility.rs:18:5: 18:19 // + literal: Const { ty: unsafe fn() {target_feature}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22 - _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:44: +2:2 - return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:44: +2:2 + return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline_compatibility.rs similarity index 100% rename from src/test/mir-opt/inline/inline-compatibility.rs rename to src/test/mir-opt/inline/inline_compatibility.rs diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff index a4d706de0ba58..5510cd7bc8ced 100644 --- a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff +++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff @@ -2,29 +2,29 @@ + // MIR for `one` after Inline fn one() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10 - let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 -+ scope 1 (inlined ::call) { // at $DIR/inline-cycle.rs:14:5: 14:24 -+ scope 2 (inlined as Call>::call) { // at $DIR/inline-cycle.rs:43:9: 43:23 -+ scope 3 (inlined as Call>::call) { // at $DIR/inline-cycle.rs:28:9: 28:31 + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 ++ scope 1 (inlined ::call) { // at $DIR/inline_cycle.rs:14:5: 14:24 ++ scope 2 (inlined as Call>::call) { // at $DIR/inline_cycle.rs:43:9: 43:23 ++ scope 3 (inlined as Call>::call) { // at $DIR/inline_cycle.rs:28:9: 28:31 + } + } + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 -- _1 = ::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 -+ _1 = ::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:36:9: 36:28 + StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 +- _1 = ::call() -> bb1; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24 ++ _1 = ::call() -> bb1; // scope 3 at $DIR/inline_cycle.rs:36:9: 36:28 // mir::Constant -- // + span: $DIR/inline-cycle.rs:14:5: 14:22 -+ // + span: $DIR/inline-cycle.rs:36:9: 36:26 +- // + span: $DIR/inline_cycle.rs:14:5: 14:22 ++ // + span: $DIR/inline_cycle.rs:36:9: 36:26 // + literal: Const { ty: fn() {::call}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:24: +1:25 - _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2 - return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline-cycle.rs b/src/test/mir-opt/inline/inline_cycle.rs similarity index 100% rename from src/test/mir-opt/inline/inline-cycle.rs rename to src/test/mir-opt/inline/inline_cycle.rs diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff index b1a5b62ef1d36..eceeb96f79f08 100644 --- a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff +++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff @@ -2,54 +2,54 @@ + // MIR for `two` after Inline fn two() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10 - let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 -+ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 -+ scope 1 (inlined call::) { // at $DIR/inline-cycle.rs:49:5: 49:12 -+ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:53:22: 53:23 -+ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8 -+ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:6 -+ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8 -+ scope 2 (inlined >::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:54:5: 54:8 + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ scope 1 (inlined call::) { // at $DIR/inline_cycle.rs:49:5: 49:12 ++ debug f => _2; // in scope 1 at $DIR/inline_cycle.rs:53:22: 53:23 ++ let _3: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ let mut _4: fn() {f}; // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:6 ++ let mut _5: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ scope 2 (inlined >::call_once - shim(fn() {f})) { // at $DIR/inline_cycle.rs:54:5: 54:8 + scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL -+ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:59:5: 59:12 ++ let _6: (); // in scope 3 at $DIR/inline_cycle.rs:59:5: 59:12 + } + } + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 -- _1 = call::(f) -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 -+ StorageLive(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 -+ _2 = f; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 + StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 +- _1 = call::(f) -> bb1; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ StorageLive(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 ++ _2 = f; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 // mir::Constant -- // + span: $DIR/inline-cycle.rs:49:5: 49:9 -+ // + span: $DIR/inline-cycle.rs:49:10: 49:11 +- // + span: $DIR/inline_cycle.rs:49:5: 49:9 ++ // + span: $DIR/inline_cycle.rs:49:10: 49:11 + // + literal: Const { ty: fn() {f}, val: Value() } -+ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8 -+ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6 -+ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6 -+ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8 -+ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12 -+ _6 = call::(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12 ++ StorageLive(_3); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ StorageLive(_4); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:6 ++ _4 = move _2; // scope 1 at $DIR/inline_cycle.rs:54:5: 54:6 ++ StorageLive(_5); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ StorageLive(_6); // scope 3 at $DIR/inline_cycle.rs:59:5: 59:12 ++ _6 = call::(f) -> bb1; // scope 3 at $DIR/inline_cycle.rs:59:5: 59:12 + // mir::Constant -+ // + span: $DIR/inline-cycle.rs:59:5: 59:9 ++ // + span: $DIR/inline_cycle.rs:59:5: 59:9 // + literal: Const { ty: fn(fn() {f}) {call::}, val: Value() } // mir::Constant -- // + span: $DIR/inline-cycle.rs:49:10: 49:11 -+ // + span: $DIR/inline-cycle.rs:59:10: 59:11 +- // + span: $DIR/inline_cycle.rs:49:10: 49:11 ++ // + span: $DIR/inline_cycle.rs:59:10: 59:11 // + literal: Const { ty: fn() {f}, val: Value() } } bb1: { -+ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:59:12: 59:13 -+ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8 -+ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8 -+ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:54:8: 54:9 -+ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 - StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:12: +1:13 - _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2 - return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2 ++ StorageDead(_6); // scope 3 at $DIR/inline_cycle.rs:59:12: 59:13 ++ StorageDead(_5); // scope 1 at $DIR/inline_cycle.rs:54:7: 54:8 ++ StorageDead(_4); // scope 1 at $DIR/inline_cycle.rs:54:7: 54:8 ++ StorageDead(_3); // scope 1 at $DIR/inline_cycle.rs:54:8: 54:9 ++ StorageDead(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12 + StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff index fc5d57ce8bf2f..52debab4dd1c0 100644 --- a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff @@ -2,31 +2,31 @@ + // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 -+ scope 1 (inlined ::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24 -+ scope 2 (inlined as Call>::call) { // at $DIR/inline-cycle-generic.rs:38:9: 38:31 -+ scope 3 (inlined ::call) { // at $DIR/inline-cycle-generic.rs:31:9: 31:28 -+ scope 4 (inlined as Call>::call) { // at $DIR/inline-cycle-generic.rs:23:9: 23:31 + let mut _0: (); // return place in scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 ++ scope 1 (inlined ::call) { // at $DIR/inline_cycle_generic.rs:9:5: 9:24 ++ scope 2 (inlined as Call>::call) { // at $DIR/inline_cycle_generic.rs:38:9: 38:31 ++ scope 3 (inlined ::call) { // at $DIR/inline_cycle_generic.rs:31:9: 31:28 ++ scope 4 (inlined as Call>::call) { // at $DIR/inline_cycle_generic.rs:23:9: 23:31 + } + } + } + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 -- _1 = ::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 -+ _1 = ::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:31:9: 31:28 + StorageLive(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 +- _1 = ::call() -> bb1; // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24 ++ _1 = ::call() -> bb1; // scope 4 at $DIR/inline_cycle_generic.rs:31:9: 31:28 // mir::Constant -- // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22 -+ // + span: $DIR/inline-cycle-generic.rs:31:9: 31:26 +- // + span: $DIR/inline_cycle_generic.rs:9:5: 9:22 ++ // + span: $DIR/inline_cycle_generic.rs:31:9: 31:26 // + literal: Const { ty: fn() {::call}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:24: +1:25 - _0 = const (); // scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +2:2 - return; // scope 0 at $DIR/inline-cycle-generic.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +2:2 + return; // scope 0 at $DIR/inline_cycle_generic.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline-cycle-generic.rs b/src/test/mir-opt/inline/inline_cycle_generic.rs similarity index 100% rename from src/test/mir-opt/inline/inline-cycle-generic.rs rename to src/test/mir-opt/inline/inline_cycle_generic.rs diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff index cef4cfc67ab29..b49191f495b94 100644 --- a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff @@ -2,23 +2,23 @@ + // MIR for `f` after Inline fn f() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12 - let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:+0:12: +2:2 - let _2: !; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 -+ scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12 + let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12 + let mut _1: !; // in scope 0 at $DIR/inline_diverging.rs:+0:12: +2:2 + let _2: !; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 ++ scope 1 (inlined sleep) { // at $DIR/inline_diverging.rs:8:5: 8:12 + } bb0: { - StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 -- _2 = sleep(); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 + StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 +- _2 = sleep(); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 - // mir::Constant -- // + span: $DIR/inline-diverging.rs:8:5: 8:10 +- // + span: $DIR/inline_diverging.rs:8:5: 8:10 - // + literal: Const { ty: fn() -> ! {sleep}, val: Value() } -+ goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 ++ goto -> bb1; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12 + } + + bb1: { -+ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:39:5: 39:12 ++ goto -> bb1; // scope 1 at $DIR/inline_diverging.rs:39:5: 39:12 } } diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index a71baad3e3ed9..1e703a8fd2baf 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -2,42 +2,42 @@ + // MIR for `g` after Inline fn g(_1: i32) -> u32 { - debug i => _1; // in scope 0 at $DIR/inline-diverging.rs:+0:10: +0:11 - let mut _0: u32; // return place in scope 0 at $DIR/inline-diverging.rs:+0:21: +0:24 - let mut _2: bool; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 - let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 - let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 - let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:+3:12: +5:6 - let _6: !; // in scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 -+ scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16 + debug i => _1; // in scope 0 at $DIR/inline_diverging.rs:+0:10: +0:11 + let mut _0: u32; // return place in scope 0 at $DIR/inline_diverging.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + let mut _3: i32; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + let mut _4: i32; // in scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + let mut _5: !; // in scope 0 at $DIR/inline_diverging.rs:+3:12: +5:6 + let _6: !; // in scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 ++ scope 1 (inlined panic) { // at $DIR/inline_diverging.rs:16:9: 16:16 + let mut _7: !; // in scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + } bb0: { - StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 - StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 - _3 = _1; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 - _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 - StorageDead(_3); // scope 0 at $DIR/inline-diverging.rs:+1:12: +1:13 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 + StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + StorageLive(_3); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 + _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + StorageDead(_3); // scope 0 at $DIR/inline_diverging.rs:+1:12: +1:13 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 } bb1: { - StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 - _4 = _1; // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 - _0 = move _4 as u32 (IntToInt); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:17 - StorageDead(_4); // scope 0 at $DIR/inline-diverging.rs:+2:16: +2:17 - StorageDead(_2); // scope 0 at $DIR/inline-diverging.rs:+5:5: +5:6 - return; // scope 0 at $DIR/inline-diverging.rs:+6:2: +6:2 + StorageLive(_4); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + _4 = _1; // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10 + _0 = move _4 as u32 (IntToInt); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:17 + StorageDead(_4); // scope 0 at $DIR/inline_diverging.rs:+2:16: +2:17 + StorageDead(_2); // scope 0 at $DIR/inline_diverging.rs:+5:5: +5:6 + return; // scope 0 at $DIR/inline_diverging.rs:+6:2: +6:2 } bb2: { - StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 -- _6 = panic(); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 + StorageLive(_6); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 +- _6 = panic(); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16 + StorageLive(_7); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + _7 = begin_panic::<&str>(const "explicit panic"); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL // mir::Constant -- // + span: $DIR/inline-diverging.rs:16:9: 16:14 +- // + span: $DIR/inline_diverging.rs:16:9: 16:14 - // + literal: Const { ty: fn() -> ! {panic}, val: Value() } + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value() } diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff index 6569ab24c3814..152153a813ce2 100644 --- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -2,55 +2,55 @@ + // MIR for `h` after Inline fn h() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12 - let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 -+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 -+ scope 1 (inlined call_twice:: ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22 -+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37 -+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 -+ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14 -+ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:16 -+ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7 -+ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10 + let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12 + let _1: (!, !); // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ scope 1 (inlined call_twice:: ! {sleep}>) { // at $DIR/inline_diverging.rs:22:5: 22:22 ++ debug f => _2; // in scope 1 at $DIR/inline_diverging.rs:26:36: 26:37 ++ let _3: !; // in scope 1 at $DIR/inline_diverging.rs:27:9: 27:10 ++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ let mut _5: (); // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:14 ++ let mut _8: (); // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:16 ++ let mut _9: !; // in scope 1 at $DIR/inline_diverging.rs:29:6: 29:7 ++ let mut _10: !; // in scope 1 at $DIR/inline_diverging.rs:29:9: 29:10 + scope 2 { -+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug a => _3; // in scope 2 at $DIR/inline_diverging.rs:27:9: 27:10 ++ let _6: !; // in scope 2 at $DIR/inline_diverging.rs:28:9: 28:10 + scope 3 { -+ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug b => _6; // in scope 3 at $DIR/inline_diverging.rs:28:9: 28:10 + } -+ scope 6 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16 ++ scope 6 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline_diverging.rs:28:13: 28:16 + scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + } + } -+ scope 4 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:27:13: 27:16 ++ scope 4 (inlined ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline_diverging.rs:27:13: 27:16 + scope 5 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + } + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 -- _1 = call_twice:: ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 -+ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 -+ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 + StorageLive(_1); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 +- _1 = call_twice:: ! {sleep}>(sleep); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ _2 = sleep; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 // mir::Constant -- // + span: $DIR/inline-diverging.rs:22:5: 22:15 +- // + span: $DIR/inline_diverging.rs:22:5: 22:15 - // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice:: ! {sleep}>}, val: Value() } - // mir::Constant - // + span: $DIR/inline-diverging.rs:22:16: 22:21 + // + span: $DIR/inline_diverging.rs:22:16: 22:21 // + literal: Const { ty: fn() -> ! {sleep}, val: Value() } -+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 -+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 ++ StorageLive(_3); // scope 1 at $DIR/inline_diverging.rs:27:9: 27:10 ++ StorageLive(_4); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ _4 = &_2; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ StorageLive(_5); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ goto -> bb1; // scope 5 at $DIR/inline_diverging.rs:39:5: 39:12 + } + + bb1: { -+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 ++ goto -> bb1; // scope 5 at $DIR/inline_diverging.rs:39:5: 39:12 } } diff --git a/src/test/mir-opt/inline/inline-diverging.rs b/src/test/mir-opt/inline/inline_diverging.rs similarity index 100% rename from src/test/mir-opt/inline/inline-diverging.rs rename to src/test/mir-opt/inline/inline_diverging.rs diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff index 3fd8aad723880..26202f2f40db5 100644 --- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -2,59 +2,59 @@ + // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-generator.rs:+0:11: +0:11 - let _1: std::ops::GeneratorState; // in scope 0 at $DIR/inline-generator.rs:+1:9: +1:11 - let mut _2: std::pin::Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 - let mut _3: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 - let mut _4: [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 -+ let mut _7: bool; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + let mut _0: (); // return place in scope 0 at $DIR/inline_generator.rs:+0:11: +0:11 + let _1: std::ops::GeneratorState; // in scope 0 at $DIR/inline_generator.rs:+1:9: +1:11 + let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 + let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 + let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 ++ let mut _7: bool; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 scope 1 { - debug _r => _1; // in scope 1 at $DIR/inline-generator.rs:+1:9: +1:11 + debug _r => _1; // in scope 1 at $DIR/inline_generator.rs:+1:9: +1:11 } -+ scope 2 (inlined g) { // at $DIR/inline-generator.rs:9:28: 9:31 ++ scope 2 (inlined g) { // at $DIR/inline_generator.rs:9:28: 9:31 + } -+ scope 3 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new) { // at $DIR/inline-generator.rs:9:14: 9:32 ++ scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) { // at $DIR/inline_generator.rs:9:14: 9:32 + debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL -+ let mut _5: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL ++ let mut _5: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL + scope 4 { -+ scope 5 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL ++ scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL + debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ let mut _6: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + } + } + } -+ scope 6 (inlined g::{closure#0}) { // at $DIR/inline-generator.rs:9:14: 9:46 -+ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7 -+ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:15:17: 15:39 -+ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:15:20: 15:21 -+ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:15:9: 15:9 -+ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7 -+ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ scope 6 (inlined g::{closure#0}) { // at $DIR/inline_generator.rs:9:14: 9:46 ++ debug a => _11; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 ++ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ let mut _9: bool; // in scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ let mut _10: bool; // in scope 6 at $DIR/inline_generator.rs:15:9: 15:9 ++ let _11: bool; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 ++ let mut _12: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _13: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _14: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _15: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-generator.rs:+1:9: +1:11 - StorageLive(_2); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 - StorageLive(_3); // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 - StorageLive(_4); // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 -- _4 = g() -> bb1; // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 + StorageLive(_1); // scope 0 at $DIR/inline_generator.rs:+1:9: +1:11 + StorageLive(_2); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 + StorageLive(_3); // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 + StorageLive(_4); // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 +- _4 = g() -> bb1; // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 - // mir::Constant -- // + span: $DIR/inline-generator.rs:9:28: 9:29 +- // + span: $DIR/inline_generator.rs:9:28: 9:29 - // + literal: Const { ty: fn() -> impl Generator {g}, val: Value() } - } - - bb1: { -+ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:15:5: 15:41 -+ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:15:5: 15:41 - _3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 -- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 ++ Deinit(_4); // scope 2 at $DIR/inline_generator.rs:15:5: 15:41 ++ discriminant(_4) = 0; // scope 2 at $DIR/inline_generator.rs:15:5: 15:41 + _3 = &mut _4; // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 +- _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 - // mir::Constant -- // + span: $DIR/inline-generator.rs:9:14: 9:22 +- // + span: $DIR/inline_generator.rs:9:14: 9:22 - // + user_ty: UserType(0) -- // + literal: Const { ty: fn(&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new}, val: Value() } +- // + literal: Const { ty: fn(&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new}, val: Value() } - } - - bb2: { @@ -63,86 +63,86 @@ + StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + Deinit(_2); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:+1:31: +1:32 -- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + StorageDead(_3); // scope 0 at $DIR/inline_generator.rs:+1:31: +1:32 +- _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 - // mir::Constant -- // + span: $DIR/inline-generator.rs:9:33: 9:39 -- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::resume}, val: Value() } -+ StorageLive(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ _7 = const false; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 +- // + span: $DIR/inline_generator.rs:9:33: 9:39 +- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Yield, <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Return> {<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume}, val: Value() } ++ StorageLive(_7); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ StorageLive(_10); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ StorageLive(_11); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ _12 = discriminant((*_13)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 } - bb3: { + bb1: { -+ StorageDead(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 -+ StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 - StorageDead(_2); // scope 0 at $DIR/inline-generator.rs:+1:45: +1:46 - StorageDead(_4); // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 - _0 = const (); // scope 0 at $DIR/inline-generator.rs:+0:11: +2:2 - StorageDead(_1); // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 - return; // scope 0 at $DIR/inline-generator.rs:+2:2: +2:2 ++ StorageDead(_11); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ StorageDead(_10); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 ++ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 + StorageDead(_2); // scope 0 at $DIR/inline_generator.rs:+1:45: +1:46 + StorageDead(_4); // scope 0 at $DIR/inline_generator.rs:+1:46: +1:47 + _0 = const (); // scope 0 at $DIR/inline_generator.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_generator.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_generator.rs:+2:2: +2:2 } - bb4 (cleanup): { + bb2 (cleanup): { - resume; // scope 0 at $DIR/inline-generator.rs:+0:1: +2:2 + resume; // scope 0 at $DIR/inline_generator.rs:+0:1: +2:2 + } + + bb3: { -+ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 -+ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 -+ _9 = _11; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 -+ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 ++ _11 = move _7; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ StorageLive(_9); // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ _9 = _11; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 + } + + bb4: { -+ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:15:24: 15:25 -+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 ++ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25 ++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 + } + + bb5: { -+ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:15:35: 15:37 -+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 ++ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37 ++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 + } + + bb6: { -+ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39 -+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39 ++ StorageDead(_9); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 ++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant(_1) = 0; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant((*_14)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39 + } + + bb7: { -+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39 -+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41 ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ _10 = move _7; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 ++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant(_1) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant((*_15)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41 + } + + bb8: { -+ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } + + bb9: { -+ unreachable; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ unreachable; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 } } diff --git a/src/test/mir-opt/inline/inline-generator.rs b/src/test/mir-opt/inline/inline_generator.rs similarity index 100% rename from src/test/mir-opt/inline/inline-generator.rs rename to src/test/mir-opt/inline/inline_generator.rs diff --git a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff index 076509df34949..e421428dcdff5 100644 --- a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff +++ b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff @@ -2,43 +2,43 @@ + // MIR for `default` after Inline fn default() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:18: +0:18 - let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 - let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 - let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 -+ scope 1 (inlined instruction_set_default) { // at $DIR/inline-instruction-set.rs:53:5: 53:30 + let mut _0: (); // return place in scope 0 at $DIR/inline_instruction_set.rs:+0:18: +0:18 + let _1: (); // in scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 + let _2: (); // in scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 + let _3: (); // in scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30 ++ scope 1 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:53:5: 53:30 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 - _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + StorageLive(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 + _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 // mir::Constant - // + span: $DIR/inline-instruction-set.rs:51:5: 51:24 + // + span: $DIR/inline_instruction_set.rs:51:5: 51:24 // + literal: Const { ty: fn() {instruction_set_a32}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27 - StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 - _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + StorageDead(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:26: +1:27 + StorageLive(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 + _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 // mir::Constant - // + span: $DIR/inline-instruction-set.rs:52:5: 52:24 + // + span: $DIR/inline_instruction_set.rs:52:5: 52:24 // + literal: Const { ty: fn() {instruction_set_t32}, val: Value() } } bb2: { - StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27 - StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 -- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 + StorageDead(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:26: +2:27 + StorageLive(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30 +- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30 - // mir::Constant -- // + span: $DIR/inline-instruction-set.rs:53:5: 53:28 +- // + span: $DIR/inline_instruction_set.rs:53:5: 53:28 - // + literal: Const { ty: fn() {instruction_set_default}, val: Value() } - } - - bb3: { - StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:30: +3:31 - _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:18: +4:2 - return; // scope 0 at $DIR/inline-instruction-set.rs:+4:2: +4:2 + StorageDead(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:30: +3:31 + _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:18: +4:2 + return; // scope 0 at $DIR/inline_instruction_set.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/inline/inline-instruction-set.rs b/src/test/mir-opt/inline/inline_instruction_set.rs similarity index 100% rename from src/test/mir-opt/inline/inline-instruction-set.rs rename to src/test/mir-opt/inline/inline_instruction_set.rs diff --git a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff index b275d08e05f92..1ea2b87e53acd 100644 --- a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff +++ b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff @@ -2,45 +2,45 @@ + // MIR for `t32` after Inline fn t32() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:14: +0:14 - let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 - let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 - let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 -+ scope 1 (inlined instruction_set_t32) { // at $DIR/inline-instruction-set.rs:43:5: 43:26 + let mut _0: (); // return place in scope 0 at $DIR/inline_instruction_set.rs:+0:14: +0:14 + let _1: (); // in scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 + let _2: (); // in scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 + let _3: (); // in scope 0 at $DIR/inline_instruction_set.rs:+5:5: +5:30 ++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline_instruction_set.rs:43:5: 43:26 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 - _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + StorageLive(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 + _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26 // mir::Constant - // + span: $DIR/inline-instruction-set.rs:42:5: 42:24 + // + span: $DIR/inline_instruction_set.rs:42:5: 42:24 // + literal: Const { ty: fn() {instruction_set_a32}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27 - StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 -- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + StorageDead(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:26: +1:27 + StorageLive(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 +- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26 - // mir::Constant -- // + span: $DIR/inline-instruction-set.rs:43:5: 43:24 +- // + span: $DIR/inline_instruction_set.rs:43:5: 43:24 - // + literal: Const { ty: fn() {instruction_set_t32}, val: Value() } - } - - bb2: { - StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27 - StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 -- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 -+ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 + StorageDead(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:26: +2:27 + StorageLive(_3); // scope 0 at $DIR/inline_instruction_set.rs:+5:5: +5:30 +- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline_instruction_set.rs:+5:5: +5:30 ++ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+5:5: +5:30 // mir::Constant - // + span: $DIR/inline-instruction-set.rs:46:5: 46:28 + // + span: $DIR/inline_instruction_set.rs:46:5: 46:28 // + literal: Const { ty: fn() {instruction_set_default}, val: Value() } } - bb3: { + bb2: { - StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:30: +5:31 - _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:14: +6:2 - return; // scope 0 at $DIR/inline-instruction-set.rs:+6:2: +6:2 + StorageDead(_3); // scope 0 at $DIR/inline_instruction_set.rs:+5:30: +5:31 + _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:14: +6:2 + return; // scope 0 at $DIR/inline_instruction_set.rs:+6:2: +6:2 } } diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff index 7e017373b4410..2a4dc9e3e8099 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff @@ -2,45 +2,45 @@ + // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11 - let _1: std::boxed::Box>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 - let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _5: std::boxed::Box>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 - let mut _7: *const std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 -+ let mut _8: &mut std::vec::Vec; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + let mut _0: (); // return place in scope 0 at $DIR/inline_into_box_place.rs:+0:11: +0:11 + let _1: std::boxed::Box>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11 + let mut _2: usize; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + let mut _3: usize; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + let mut _4: *mut u8; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + let mut _5: std::boxed::Box>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + let mut _6: (); // in scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43 + let mut _7: *const std::vec::Vec; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 ++ let mut _8: &mut std::vec::Vec; // in scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 scope 1 { - debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + debug _x => _1; // in scope 1 at $DIR/inline_into_box_place.rs:+1:9: +1:11 } scope 2 { } -+ scope 3 (inlined Vec::::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ scope 3 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:8:33: 8:43 + let mut _9: alloc::raw_vec::RawVec; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 - _2 = SizeOf(std::vec::Vec); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - _3 = AlignOf(std::vec::Vec); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + StorageLive(_1); // scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11 + _2 = SizeOf(std::vec::Vec); // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + _3 = AlignOf(std::vec::Vec); // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43 // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:29: 8:43 + // + span: $DIR/inline_into_box_place.rs:8:29: 8:43 // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } } bb1: { - StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - _5 = ShallowInitBox(move _4, std::vec::Vec); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - _7 = (((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -- (*_7) = Vec::::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 -+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + StorageLive(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + _5 = ShallowInitBox(move _4, std::vec::Vec); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + _7 = (((_5.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 +- (*_7) = Vec::::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ StorageLive(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ _8 = &mut (*_7); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant -- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 +- // + span: $DIR/inline_into_box_place.rs:8:33: 8:41 - // + user_ty: UserType(1) - // + literal: Const { ty: fn() -> Vec {Vec::::new}, val: Value() } - } @@ -53,29 +53,29 @@ + ((*_8).0: alloc::raw_vec::RawVec) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 - _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 - StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 - _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2 -- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 -+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 ++ StorageDead(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 + _1 = move _5; // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43 + StorageDead(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43 + _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2 +- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 ++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 } - bb3: { + bb2: { - StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 - return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2 } - bb4 (cleanup): { + bb3 (cleanup): { - resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2 + resume; // scope 0 at $DIR/inline_into_box_place.rs:+0:1: +2:2 - } - - bb5 (cleanup): { -- _6 = alloc::alloc::box_free::, std::alloc::Global>(move (_5.0: std::ptr::Unique>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 +- _6 = alloc::alloc::box_free::, std::alloc::Global>(move (_5.0: std::ptr::Unique>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43 - // mir::Constant -- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43 +- // + span: $DIR/inline_into_box_place.rs:8:42: 8:43 - // + literal: Const { ty: unsafe fn(Unique>, std::alloc::Global) {alloc::alloc::box_free::, std::alloc::Global>}, val: Value() } } } diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline_into_box_place.rs similarity index 100% rename from src/test/mir-opt/inline/inline-into-box-place.rs rename to src/test/mir-opt/inline/inline_into_box_place.rs diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir index 361b02715266f..1c590be945c9e 100644 --- a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir @@ -1,55 +1,55 @@ // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-options.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/inline-options.rs:+1:5: +1:18 - let _2: (); // in scope 0 at $DIR/inline-options.rs:+2:5: +2:21 - scope 1 (inlined inlined::) { // at $DIR/inline-options.rs:10:5: 10:21 - let _3: (); // in scope 1 at $DIR/inline-options.rs:16:23: 16:26 - let _4: (); // in scope 1 at $DIR/inline-options.rs:16:28: 16:31 - let _5: (); // in scope 1 at $DIR/inline-options.rs:16:33: 16:36 + let mut _0: (); // return place in scope 0 at $DIR/inline_options.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline_options.rs:+1:5: +1:18 + let _2: (); // in scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + scope 1 (inlined inlined::) { // at $DIR/inline_options.rs:10:5: 10:21 + let _3: (); // in scope 1 at $DIR/inline_options.rs:16:23: 16:26 + let _4: (); // in scope 1 at $DIR/inline_options.rs:16:28: 16:31 + let _5: (); // in scope 1 at $DIR/inline_options.rs:16:33: 16:36 } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-options.rs:+1:5: +1:18 - _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline-options.rs:+1:5: +1:18 + StorageLive(_1); // scope 0 at $DIR/inline_options.rs:+1:5: +1:18 + _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline_options.rs:+1:5: +1:18 // mir::Constant - // + span: $DIR/inline-options.rs:9:5: 9:16 + // + span: $DIR/inline_options.rs:9:5: 9:16 // + literal: Const { ty: fn() {not_inlined}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/inline-options.rs:+1:18: +1:19 - StorageLive(_2); // scope 0 at $DIR/inline-options.rs:+2:5: +2:21 - StorageLive(_3); // scope 1 at $DIR/inline-options.rs:16:23: 16:26 - _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:16:23: 16:26 + StorageDead(_1); // scope 0 at $DIR/inline_options.rs:+1:18: +1:19 + StorageLive(_2); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21 + StorageLive(_3); // scope 1 at $DIR/inline_options.rs:16:23: 16:26 + _3 = g() -> bb2; // scope 1 at $DIR/inline_options.rs:16:23: 16:26 // mir::Constant - // + span: $DIR/inline-options.rs:16:23: 16:24 + // + span: $DIR/inline_options.rs:16:23: 16:24 // + literal: Const { ty: fn() {g}, val: Value() } } bb2: { - StorageDead(_3); // scope 1 at $DIR/inline-options.rs:16:26: 16:27 - StorageLive(_4); // scope 1 at $DIR/inline-options.rs:16:28: 16:31 - _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:16:28: 16:31 + StorageDead(_3); // scope 1 at $DIR/inline_options.rs:16:26: 16:27 + StorageLive(_4); // scope 1 at $DIR/inline_options.rs:16:28: 16:31 + _4 = g() -> bb3; // scope 1 at $DIR/inline_options.rs:16:28: 16:31 // mir::Constant - // + span: $DIR/inline-options.rs:16:28: 16:29 + // + span: $DIR/inline_options.rs:16:28: 16:29 // + literal: Const { ty: fn() {g}, val: Value() } } bb3: { - StorageDead(_4); // scope 1 at $DIR/inline-options.rs:16:31: 16:32 - StorageLive(_5); // scope 1 at $DIR/inline-options.rs:16:33: 16:36 - _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:16:33: 16:36 + StorageDead(_4); // scope 1 at $DIR/inline_options.rs:16:31: 16:32 + StorageLive(_5); // scope 1 at $DIR/inline_options.rs:16:33: 16:36 + _5 = g() -> bb4; // scope 1 at $DIR/inline_options.rs:16:33: 16:36 // mir::Constant - // + span: $DIR/inline-options.rs:16:33: 16:34 + // + span: $DIR/inline_options.rs:16:33: 16:34 // + literal: Const { ty: fn() {g}, val: Value() } } bb4: { - StorageDead(_5); // scope 1 at $DIR/inline-options.rs:16:36: 16:37 - StorageDead(_2); // scope 0 at $DIR/inline-options.rs:+2:21: +2:22 - _0 = const (); // scope 0 at $DIR/inline-options.rs:+0:11: +3:2 - return; // scope 0 at $DIR/inline-options.rs:+3:2: +3:2 + StorageDead(_5); // scope 1 at $DIR/inline_options.rs:16:36: 16:37 + StorageDead(_2); // scope 0 at $DIR/inline_options.rs:+2:21: +2:22 + _0 = const (); // scope 0 at $DIR/inline_options.rs:+0:11: +3:2 + return; // scope 0 at $DIR/inline_options.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/inline-options.rs b/src/test/mir-opt/inline/inline_options.rs similarity index 100% rename from src/test/mir-opt/inline/inline-options.rs rename to src/test/mir-opt/inline/inline_options.rs diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index 169e7f5c5d936..75af20d482ddd 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -1,72 +1,72 @@ // MIR for `bar` after Inline fn bar() -> bool { - let mut _0: bool; // return place in scope 0 at $DIR/inline-retag.rs:+0:13: +0:17 - let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+1:9: +1:10 - let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+2:5: +2:6 - let mut _3: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9 - let _4: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9 - let _5: i32; // in scope 0 at $DIR/inline-retag.rs:+2:8: +2:9 - let mut _6: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14 - let _7: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14 - let _8: i32; // in scope 0 at $DIR/inline-retag.rs:+2:12: +2:14 + let mut _0: bool; // return place in scope 0 at $DIR/inline_retag.rs:+0:13: +0:17 + let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+1:9: +1:10 + let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+2:5: +2:6 + let mut _3: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:7: +2:9 + let _4: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:7: +2:9 + let _5: i32; // in scope 0 at $DIR/inline_retag.rs:+2:8: +2:9 + let mut _6: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:11: +2:14 + let _7: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:11: +2:14 + let _8: i32; // in scope 0 at $DIR/inline_retag.rs:+2:12: +2:14 scope 1 { - debug f => _1; // in scope 1 at $DIR/inline-retag.rs:+1:9: +1:10 - let mut _9: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - let mut _10: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - scope 2 (inlined foo) { // at $DIR/inline-retag.rs:12:5: 12:15 - debug x => _3; // in scope 2 at $DIR/inline-retag.rs:16:8: 16:9 - debug y => _6; // in scope 2 at $DIR/inline-retag.rs:16:17: 16:18 - let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:17:5: 17:7 - let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:17:11: 17:13 + debug f => _1; // in scope 1 at $DIR/inline_retag.rs:+1:9: +1:10 + let mut _9: &i32; // in scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + let mut _10: &i32; // in scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + scope 2 (inlined foo) { // at $DIR/inline_retag.rs:12:5: 12:15 + debug x => _3; // in scope 2 at $DIR/inline_retag.rs:16:8: 16:9 + debug y => _6; // in scope 2 at $DIR/inline_retag.rs:16:17: 16:18 + let mut _11: i32; // in scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + let mut _12: i32; // in scope 2 at $DIR/inline_retag.rs:17:11: 17:13 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-retag.rs:+1:9: +1:10 - _1 = foo; // scope 0 at $DIR/inline-retag.rs:+1:13: +1:16 + StorageLive(_1); // scope 0 at $DIR/inline_retag.rs:+1:9: +1:10 + _1 = foo; // scope 0 at $DIR/inline_retag.rs:+1:13: +1:16 // mir::Constant - // + span: $DIR/inline-retag.rs:11:13: 11:16 + // + span: $DIR/inline_retag.rs:11:13: 11:16 // + literal: Const { ty: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}, val: Value() } - StorageLive(_2); // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6 - _2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6 - StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - _10 = const _; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + StorageLive(_2); // scope 1 at $DIR/inline_retag.rs:+2:5: +2:6 + _2 = _1; // scope 1 at $DIR/inline_retag.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + StorageLive(_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + _10 = const _; // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 // mir::Constant - // + span: $DIR/inline-retag.rs:12:7: 12:9 + // + span: $DIR/inline_retag.rs:12:7: 12:9 // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) } - Retag(_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - Retag(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - _3 = &(*_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - _9 = const _; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + Retag(_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + _4 = &(*_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + Retag(_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + _3 = &(*_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + Retag(_3); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 + StorageLive(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + StorageLive(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + _9 = const _; // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 // mir::Constant - // + span: $DIR/inline-retag.rs:12:11: 12:14 + // + span: $DIR/inline_retag.rs:12:11: 12:14 // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) } - Retag(_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - _6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - Retag(_3); // scope 2 at $DIR/inline-retag.rs:16:8: 16:9 - Retag(_6); // scope 2 at $DIR/inline-retag.rs:16:17: 16:18 - StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7 - _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7 - StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13 - _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13 - _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:17:5: 17:13 - StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13 - StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13 - StorageDead(_6); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 - StorageDead(_3); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 - StorageDead(_2); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 - StorageDead(_1); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 - StorageDead(_7); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 - StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 - return; // scope 0 at $DIR/inline-retag.rs:+3:2: +3:2 + Retag(_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + _7 = &(*_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + Retag(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + _6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + Retag(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9 + Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18 + StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + _11 = (*_3); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + StorageLive(_12); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13 + _12 = (*_6); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13 + _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline_retag.rs:17:5: 17:13 + StorageDead(_12); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13 + StorageDead(_11); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13 + StorageDead(_6); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15 + StorageDead(_3); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15 + StorageDead(_2); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15 + StorageDead(_1); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2 + StorageDead(_7); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2 + StorageDead(_4); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline_retag.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline_retag.rs similarity index 100% rename from src/test/mir-opt/inline/inline-retag.rs rename to src/test/mir-opt/inline/inline_retag.rs diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff index d691e90b7dac6..969573ba3253f 100644 --- a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff +++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff @@ -2,25 +2,25 @@ + // MIR for `clone` after Inline fn clone(_1: fn(A, B)) -> fn(A, B) { - debug f => _1; // in scope 0 at $DIR/inline-shims.rs:+0:20: +0:21 - let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:+0:36: +0:44 - let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 -+ scope 1 (inlined ::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:6:5: 6:14 + debug f => _1; // in scope 0 at $DIR/inline_shims.rs:+0:20: +0:21 + let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline_shims.rs:+0:36: +0:44 + let mut _2: &fn(A, B); // in scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 ++ scope 1 (inlined ::clone - shim(fn(A, B))) { // at $DIR/inline_shims.rs:6:5: 6:14 + } bb0: { - StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 - _2 = &_1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 -- _0 = ::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 + StorageLive(_2); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 + _2 = &_1; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 +- _0 = ::clone(move _2) -> bb1; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14 - // mir::Constant -- // + span: $DIR/inline-shims.rs:6:7: 6:12 +- // + span: $DIR/inline_shims.rs:6:7: 6:12 - // + literal: Const { ty: for<'a> fn(&'a fn(A, B)) -> fn(A, B) {::clone}, val: Value() } - } - - bb1: { + _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL - StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:+1:13: +1:14 - return; // scope 0 at $DIR/inline-shims.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/inline_shims.rs:+1:13: +1:14 + return; // scope 0 at $DIR/inline_shims.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff index f7b1cde80bdc7..7a54beca2336c 100644 --- a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -2,51 +2,51 @@ + // MIR for `drop` after Inline fn drop(_1: *mut Vec, _2: *mut Option) -> () { - debug a => _1; // in scope 0 at $DIR/inline-shims.rs:+0:19: +0:20 - debug b => _2; // in scope 0 at $DIR/inline-shims.rs:+0:35: +0:36 - let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:+0:54: +0:54 - let _3: (); // in scope 0 at $DIR/inline-shims.rs:+1:14: +1:40 - let mut _4: *mut std::vec::Vec; // in scope 0 at $DIR/inline-shims.rs:+1:38: +1:39 - let mut _5: *mut std::option::Option; // in scope 0 at $DIR/inline-shims.rs:+2:38: +2:39 + debug a => _1; // in scope 0 at $DIR/inline_shims.rs:+0:19: +0:20 + debug b => _2; // in scope 0 at $DIR/inline_shims.rs:+0:35: +0:36 + let mut _0: (); // return place in scope 0 at $DIR/inline_shims.rs:+0:54: +0:54 + let _3: (); // in scope 0 at $DIR/inline_shims.rs:+1:14: +1:40 + let mut _4: *mut std::vec::Vec; // in scope 0 at $DIR/inline_shims.rs:+1:38: +1:39 + let mut _5: *mut std::option::Option; // in scope 0 at $DIR/inline_shims.rs:+2:38: +2:39 scope 1 { } scope 2 { -+ scope 3 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { // at $DIR/inline-shims.rs:12:14: 12:40 ++ scope 3 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { // at $DIR/inline_shims.rs:12:14: 12:40 + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + } } bb0: { - StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:42 - StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39 - _4 = _1; // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39 - _3 = std::ptr::drop_in_place::>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:+1:14: +1:40 + StorageLive(_3); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:42 + StorageLive(_4); // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39 + _4 = _1; // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39 + _3 = std::ptr::drop_in_place::>(move _4) -> bb1; // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40 // mir::Constant - // + span: $DIR/inline-shims.rs:11:14: 11:37 + // + span: $DIR/inline_shims.rs:11:14: 11:37 // + literal: Const { ty: unsafe fn(*mut Vec) {std::ptr::drop_in_place::>}, val: Value() } } bb1: { - StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:+1:39: +1:40 - StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:+1:41: +1:42 - StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39 - _5 = _2; // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39 -- _0 = std::ptr::drop_in_place::>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 + StorageDead(_4); // scope 1 at $DIR/inline_shims.rs:+1:39: +1:40 + StorageDead(_3); // scope 0 at $DIR/inline_shims.rs:+1:41: +1:42 + StorageLive(_5); // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39 + _5 = _2; // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39 +- _0 = std::ptr::drop_in_place::>(move _5) -> bb2; // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 - // mir::Constant -- // + span: $DIR/inline-shims.rs:12:14: 12:37 +- // + span: $DIR/inline_shims.rs:12:14: 12:37 - // + literal: Const { ty: unsafe fn(*mut Option) {std::ptr::drop_in_place::>}, val: Value() } -+ StorageLive(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 -+ StorageLive(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 ++ StorageLive(_6); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 ++ StorageLive(_7); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 + _6 = discriminant((*_5)); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL } bb2: { -+ StorageDead(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 -+ StorageDead(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 - StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:+2:39: +2:40 - return; // scope 0 at $DIR/inline-shims.rs:+3:2: +3:2 ++ StorageDead(_7); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 ++ StorageDead(_6); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 + StorageDead(_5); // scope 2 at $DIR/inline_shims.rs:+2:39: +2:40 + return; // scope 0 at $DIR/inline_shims.rs:+3:2: +3:2 + } + + bb3: { diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline_shims.rs similarity index 100% rename from src/test/mir-opt/inline/inline-shims.rs rename to src/test/mir-opt/inline/inline_shims.rs diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff index fdf2a1e1ff93f..af08296edea57 100644 --- a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff @@ -2,27 +2,27 @@ + // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inline-specialization.rs:+0:11: +0:11 - let _1: u32; // in scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10 + let mut _0: (); // return place in scope 0 at $DIR/inline_specialization.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10 scope 1 { - debug x => _1; // in scope 1 at $DIR/inline-specialization.rs:+1:9: +1:10 + debug x => _1; // in scope 1 at $DIR/inline_specialization.rs:+1:9: +1:10 } -+ scope 2 (inlined as Foo>::bar) { // at $DIR/inline-specialization.rs:5:13: 5:38 ++ scope 2 (inlined as Foo>::bar) { // at $DIR/inline_specialization.rs:5:13: 5:38 + } bb0: { - StorageLive(_1); // scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10 -- _1 = as Foo>::bar() -> bb1; // scope 0 at $DIR/inline-specialization.rs:+1:13: +1:38 + StorageLive(_1); // scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10 +- _1 = as Foo>::bar() -> bb1; // scope 0 at $DIR/inline_specialization.rs:+1:13: +1:38 - // mir::Constant -- // + span: $DIR/inline-specialization.rs:5:13: 5:36 +- // + span: $DIR/inline_specialization.rs:5:13: 5:36 - // + literal: Const { ty: fn() -> u32 { as Foo>::bar}, val: Value() } - } - - bb1: { -+ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:14:31: 14:34 - _0 = const (); // scope 0 at $DIR/inline-specialization.rs:+0:11: +2:2 - StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:+2:1: +2:2 - return; // scope 0 at $DIR/inline-specialization.rs:+2:2: +2:2 ++ _1 = const 123_u32; // scope 2 at $DIR/inline_specialization.rs:14:31: 14:34 + _0 = const (); // scope 0 at $DIR/inline_specialization.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline_specialization.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline_specialization.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline-specialization.rs b/src/test/mir-opt/inline/inline_specialization.rs similarity index 100% rename from src/test/mir-opt/inline/inline-specialization.rs rename to src/test/mir-opt/inline/inline_specialization.rs diff --git a/src/test/mir-opt/inline/inline-trait-method.rs b/src/test/mir-opt/inline/inline_trait_method.rs similarity index 100% rename from src/test/mir-opt/inline/inline-trait-method.rs rename to src/test/mir-opt/inline/inline_trait_method.rs diff --git a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir index 89eefc2926911..637bf282a65bf 100644 --- a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir @@ -1,21 +1,21 @@ // MIR for `test` after Inline fn test(_1: &dyn X) -> u32 { - debug x => _1; // in scope 0 at $DIR/inline-trait-method.rs:+0:9: +0:10 - let mut _0: u32; // return place in scope 0 at $DIR/inline-trait-method.rs:+0:23: +0:26 - let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + debug x => _1; // in scope 0 at $DIR/inline_trait_method.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/inline_trait_method.rs:+0:23: +0:26 + let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 bb0: { - StorageLive(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 - _2 = &(*_1); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 - _0 = ::y(move _2) -> bb1; // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + StorageLive(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + _2 = &(*_1); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 + _0 = ::y(move _2) -> bb1; // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10 // mir::Constant - // + span: $DIR/inline-trait-method.rs:9:7: 9:8 + // + span: $DIR/inline_trait_method.rs:9:7: 9:8 // + literal: Const { ty: for<'a> fn(&'a dyn X) -> u32 {::y}, val: Value() } } bb1: { - StorageDead(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:9: +1:10 - return; // scope 0 at $DIR/inline-trait-method.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:9: +1:10 + return; // scope 0 at $DIR/inline_trait_method.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline_trait_method_2.rs similarity index 100% rename from src/test/mir-opt/inline/inline-trait-method_2.rs rename to src/test/mir-opt/inline/inline_trait_method_2.rs diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir index 3d05869fa513e..dab8bb9a0c62b 100644 --- a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir @@ -1,32 +1,32 @@ // MIR for `test2` after Inline fn test2(_1: &dyn X) -> bool { - debug x => _1; // in scope 0 at $DIR/inline-trait-method_2.rs:+0:10: +0:11 - let mut _0: bool; // return place in scope 0 at $DIR/inline-trait-method_2.rs:+0:24: +0:28 - let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - scope 1 (inlined test) { // at $DIR/inline-trait-method_2.rs:5:5: 5:12 - debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:9:9: 9:10 - let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 + debug x => _1; // in scope 0 at $DIR/inline_trait_method_2.rs:+0:10: +0:11 + let mut _0: bool; // return place in scope 0 at $DIR/inline_trait_method_2.rs:+0:24: +0:28 + let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + let mut _3: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + scope 1 (inlined test) { // at $DIR/inline_trait_method_2.rs:5:5: 5:12 + debug x => _2; // in scope 1 at $DIR/inline_trait_method_2.rs:9:9: 9:10 + let mut _4: &dyn X; // in scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10 } bb0: { - StorageLive(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - StorageLive(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - _3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 - StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 - _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 - _0 = ::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 + StorageLive(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + StorageLive(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + _3 = &(*_1); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11 + StorageLive(_4); // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10 + _4 = _2; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10 + _0 = ::y(move _4) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10 // mir::Constant - // + span: $DIR/inline-trait-method_2.rs:10:7: 10:8 + // + span: $DIR/inline_trait_method_2.rs:10:7: 10:8 // + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {::y}, val: Value() } } bb1: { - StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:9: 10:10 - StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:11: +1:12 - return; // scope 0 at $DIR/inline-trait-method_2.rs:+2:2: +2:2 + StorageDead(_4); // scope 1 at $DIR/inline_trait_method_2.rs:10:9: 10:10 + StorageDead(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:11: +1:12 + return; // scope 0 at $DIR/inline_trait_method_2.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index 5168ae031f04c..777681e1ce7ec 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -1,30 +1,30 @@ // MIR for `a` after Inline fn a(_1: &mut [T]) -> &mut [T] { - debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 - let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:29: +0:37 - let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 + debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14 + let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:29: +0:37 + let mut _2: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _3: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _4: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:3:5: 3:15 debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL _5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL _3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 - _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 06d442ae88b96..83545c991000e 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -1,12 +1,12 @@ // MIR for `b` after Inline fn b(_1: &mut Box) -> &mut T { - debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 - let mut _0: &mut T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:32: +0:38 - let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14 + let mut _0: &mut T; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:32: +0:38 + let mut _2: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _3: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:5: 8:15 debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -15,10 +15,10 @@ fn b(_1: &mut Box) -> &mut T { } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -28,11 +28,11 @@ fn b(_1: &mut Box) -> &mut T { _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 - _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir index c7f20ff98ff72..ed4e9927ce9cd 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir @@ -1,22 +1,22 @@ // MIR for `c` after Inline fn c(_1: &[T]) -> &[T] { - debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 - let mut _0: &[T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:25: +0:29 - let _2: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _3: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15 + debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14 + let mut _0: &[T]; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:25: +0:29 + let _2: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _3: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:13:5: 13:15 debug self => _3; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _2 = _3; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 - StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 + StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index d5f06c54a57c0..18a2670be2158 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -1,26 +1,26 @@ // MIR for `d` after Inline fn d(_1: &Box) -> &T { - debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 - let mut _0: &T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:28: +0:30 - let _2: &T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - let mut _3: &std::boxed::Box; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 + debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14 + let mut _0: &T; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:28: +0:30 + let _2: &T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + let mut _3: &std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:18:5: 18:15 debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _4: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _5 = (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 - StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 - StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 + StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs similarity index 100% rename from src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs rename to src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index fca53a72f8820..d99ae1a6c7c83 100644 --- a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -1,42 +1,42 @@ // MIR for `main` after Inline fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+0:11: +0:11 - let _1: [closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 - let mut _2: &[closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 - let mut _3: ((),); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - let mut _4: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 - let mut _5: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + let mut _0: (); // return place in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+0:11: +0:11 + let _1: [closure@$DIR/issue_76997_inline_scopes_parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10 + let mut _2: &[closure@$DIR/issue_76997_inline_scopes_parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6 + let mut _3: ((),); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + let mut _4: (); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9 + let mut _5: (); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 scope 1 { - debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 - scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 - debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:14: +1:15 - let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 + debug f => _1; // in scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10 + scope 2 (inlined main::{closure#0}) { // at $DIR/issue_76997_inline_scopes_parenting.rs:6:5: 6:10 + debug x => _5; // in scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:14: +1:15 + let _6: (); // in scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24 scope 3 { - debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 + debug y => _6; // in scope 3 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 - Deinit(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:13: +1:33 - StorageLive(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 - _2 = &_1; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 - StorageLive(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - StorageLive(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 - Deinit(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 - Deinit(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 - StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:32: +1:33 - StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 - StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 - StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 - StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:1: +3:2 - return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:2: +3:2 + StorageLive(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:13: +1:33 + StorageLive(_2); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6 + _2 = &_1; // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + StorageLive(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9 + Deinit(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9 + Deinit(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + (_3.0: ()) = move _4; // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + StorageLive(_5); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + _5 = move (_3.0: ()); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + StorageLive(_6); // scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24 + StorageDead(_6); // scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:32: +1:33 + StorageDead(_5); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10 + StorageDead(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10 + StorageDead(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10 + StorageDead(_2); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10 + StorageDead(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+3:1: +3:2 + return; // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.rs similarity index 100% rename from src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs rename to src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.rs diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff index 4186650dfabe0..51a98465fd9a7 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff @@ -2,67 +2,67 @@ + // MIR for `bar` after Inline fn bar(_1: P) -> () { - debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9 - let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3 - let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -+ scope 1 (inlined >::call - shim(fn() {foo})) { // at $DIR/issue-78442.rs:11:5: 11:17 + debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 ++ scope 1 (inlined >::call - shim(fn() {foo})) { // at $DIR/issue_78442.rs:11:5: 11:17 + } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -+ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 +- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 ++ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:13 + // + span: $DIR/issue_78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } } bb1: { - _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + Deinit(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 - // mir::Constant -- // + span: $DIR/issue-78442.rs:11:5: 11:15 +- // + span: $DIR/issue_78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> >::Output {>::call}, val: Value() } + _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL } bb2: { -- StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -- StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 -- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 -+ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 +- StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 +- StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 +- StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 +- StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 +- _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2 +- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 ++ return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 } - bb3: { -- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 +- return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 + bb3 (cleanup): { -+ drop(_1) -> bb4; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ drop(_1) -> bb4; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 } bb4 (cleanup): { -- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 -+ resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 +- drop(_1) -> bb5; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 ++ resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2 } - bb5 (cleanup): { -- resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 +- resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2 + bb5: { -+ StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -+ StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -+ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -+ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -+ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 -+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 ++ StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 ++ StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 ++ StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 ++ _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2 ++ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 } } diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff index 24e9a3df15acd..e47466c5e8047 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff @@ -2,56 +2,56 @@ + // MIR for `bar` after RevealAll fn bar(_1: P) -> () { - debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9 - let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3 - let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -+ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 +- let _4: impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 ++ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 ++ let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:13 + // + span: $DIR/issue_78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } } bb1: { - _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 + Deinit(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17 // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:15 + // + span: $DIR/issue_78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> >::Output {>::call}, val: Value() } + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> >::Output {>::call}, val: Value() } } bb2: { - StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 - StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 - StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 - StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 - _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 - drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17 + StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18 + _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2 + drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 } bb3: { - return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 + return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2 } bb4 (cleanup): { - drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + drop(_1) -> bb5; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2 } bb5 (cleanup): { - resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2 } } diff --git a/src/test/mir-opt/inline/issue-78442.rs b/src/test/mir-opt/inline/issue_78442.rs similarity index 100% rename from src/test/mir-opt/inline/issue-78442.rs rename to src/test/mir-opt/inline/issue_78442.rs diff --git a/src/test/mir-opt/inline/polymorphic-recursion.rs b/src/test/mir-opt/inline/polymorphic_recursion.rs similarity index 100% rename from src/test/mir-opt/inline/polymorphic-recursion.rs rename to src/test/mir-opt/inline/polymorphic_recursion.rs diff --git a/src/test/mir-opt/issue_101973.inner.ConstProp.diff b/src/test/mir-opt/issue_101973.inner.ConstProp.diff index 281afe4be17ef..c24abedae927f 100644 --- a/src/test/mir-opt/issue_101973.inner.ConstProp.diff +++ b/src/test/mir-opt/issue_101973.inner.ConstProp.diff @@ -2,29 +2,29 @@ + // MIR for `inner` after ConstProp fn inner(_1: u32) -> i64 { - debug fields => _1; // in scope 0 at $DIR/issue-101973.rs:+0:14: +0:20 - let mut _0: i64; // return place in scope 0 at $DIR/issue-101973.rs:+0:30: +0:33 - let mut _2: i32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:65 - let mut _3: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:58 - let mut _4: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:17 - let mut _5: u32; // in scope 0 at $DIR/issue-101973.rs:+1:10: +1:16 - let mut _6: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 - let mut _7: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:52 - let mut _8: u32; // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 - let mut _9: u32; // in scope 0 at $DIR/issue-101973.rs:+1:33: +1:39 - let mut _10: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 - let mut _11: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 - scope 1 (inlined imm8) { // at $DIR/issue-101973.rs:14:5: 14:17 - debug x => _5; // in scope 1 at $DIR/issue-101973.rs:5:13: 5:14 - let mut _12: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:27 - let mut _13: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20 - let mut _14: u32; // in scope 1 at $DIR/issue-101973.rs:7:13: 7:14 - let mut _15: (u32, bool); // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20 + debug fields => _1; // in scope 0 at $DIR/issue_101973.rs:+0:14: +0:20 + let mut _0: i64; // return place in scope 0 at $DIR/issue_101973.rs:+0:30: +0:33 + let mut _2: i32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + let mut _3: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + let mut _4: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + let mut _5: u32; // in scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + let mut _6: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + let mut _10: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _11: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:14:5: 14:17 + debug x => _5; // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14 + let mut _12: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27 + let mut _13: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 + let mut _14: u32; // in scope 1 at $DIR/issue_101973.rs:7:13: 7:14 + let mut _15: (u32, bool); // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 scope 2 { - debug out => _4; // in scope 2 at $DIR/issue-101973.rs:6:9: 6:16 + debug out => _4; // in scope 2 at $DIR/issue_101973.rs:6:9: 6:16 } } - scope 3 (inlined core::num::::rotate_right) { // at $DIR/issue-101973.rs:14:5: 14:58 + scope 3 (inlined core::num::::rotate_right) { // at $DIR/issue_101973.rs:14:5: 14:58 debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL @@ -32,32 +32,32 @@ } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65 - StorageLive(_3); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:58 - StorageLive(_4); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:17 - StorageLive(_5); // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16 - _5 = _1; // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16 - _4 = const 0_u32; // scope 1 at $DIR/issue-101973.rs:6:19: 6:23 - StorageLive(_12); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27 - StorageLive(_13); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20 - StorageLive(_14); // scope 2 at $DIR/issue-101973.rs:7:13: 7:14 - _14 = _5; // scope 2 at $DIR/issue-101973.rs:7:13: 7:14 - _15 = CheckedShr(_14, const 0_i32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20 - assert(!move (_15.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue-101973.rs:7:12: 7:20 + StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + StorageLive(_5); // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + _5 = _1; // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + _4 = const 0_u32; // scope 1 at $DIR/issue_101973.rs:6:19: 6:23 + StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + StorageLive(_14); // scope 2 at $DIR/issue_101973.rs:7:13: 7:14 + _14 = _5; // scope 2 at $DIR/issue_101973.rs:7:13: 7:14 + _15 = CheckedShr(_14, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + assert(!move (_15.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 } bb1: { - _8 = move (_10.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 - StorageDead(_9); // scope 0 at $DIR/issue-101973.rs:+1:44: +1:45 - _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52 - StorageDead(_8); // scope 0 at $DIR/issue-101973.rs:+1:51: +1:52 - _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 - assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 + _8 = move (_10.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + StorageDead(_9); // scope 0 at $DIR/issue_101973.rs:+1:44: +1:45 + _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52 + _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 } bb2: { - _6 = move (_11.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 - StorageDead(_7); // scope 0 at $DIR/issue-101973.rs:+1:56: +1:57 + _6 = move (_11.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57 StorageLive(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL _16 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageLive(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL @@ -69,32 +69,32 @@ } bb3: { - _13 = move (_15.0: u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20 - StorageDead(_14); // scope 2 at $DIR/issue-101973.rs:7:19: 7:20 - _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27 - StorageDead(_13); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27 - _4 = BitOr(_4, move _12); // scope 2 at $DIR/issue-101973.rs:7:5: 7:27 - StorageDead(_12); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27 - StorageDead(_5); // scope 0 at $DIR/issue-101973.rs:+1:16: +1:17 - StorageLive(_6); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57 - StorageLive(_7); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52 - StorageLive(_8); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 - StorageLive(_9); // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39 - _9 = _1; // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39 - _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 - assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45 + _13 = move (_15.0: u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + StorageDead(_14); // scope 2 at $DIR/issue_101973.rs:7:19: 7:20 + _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + _4 = BitOr(_4, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27 + StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + StorageDead(_5); // scope 0 at $DIR/issue_101973.rs:+1:16: +1:17 + StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + StorageLive(_9); // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + _9 = _1; // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 } bb4: { StorageDead(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_6); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58 - StorageDead(_4); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58 - _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65 - StorageDead(_3); // scope 0 at $DIR/issue-101973.rs:+1:64: +1:65 - _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:72 - StorageDead(_2); // scope 0 at $DIR/issue-101973.rs:+1:71: +1:72 - return; // scope 0 at $DIR/issue-101973.rs:+2:2: +2:2 + StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65 + _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72 + StorageDead(_2); // scope 0 at $DIR/issue_101973.rs:+1:71: +1:72 + return; // scope 0 at $DIR/issue_101973.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/issue-101973.rs b/src/test/mir-opt/issue_101973.rs similarity index 100% rename from src/test/mir-opt/issue-101973.rs rename to src/test/mir-opt/issue_101973.rs diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index b13987f7360e6..82210081832c8 100644 --- a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -1,52 +1,52 @@ // MIR for `main` after SimplifyCfg-initial fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-38669.rs:+0:11: +0:11 - let mut _1: bool; // in scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 - let mut _2: (); // in scope 0 at $DIR/issue-38669.rs:+0:1: +8:2 - let _3: (); // in scope 0 at $DIR/issue-38669.rs:+3:9: +5:10 - let mut _4: bool; // in scope 0 at $DIR/issue-38669.rs:+3:12: +3:24 - let mut _5: !; // in scope 0 at $DIR/issue-38669.rs:+3:25: +5:10 + let mut _0: (); // return place in scope 0 at $DIR/issue_38669.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/issue_38669.rs:+1:9: +1:25 + let mut _2: (); // in scope 0 at $DIR/issue_38669.rs:+0:1: +8:2 + let _3: (); // in scope 0 at $DIR/issue_38669.rs:+3:9: +5:10 + let mut _4: bool; // in scope 0 at $DIR/issue_38669.rs:+3:12: +3:24 + let mut _5: !; // in scope 0 at $DIR/issue_38669.rs:+3:25: +5:10 scope 1 { - debug should_break => _1; // in scope 1 at $DIR/issue-38669.rs:+1:9: +1:25 + debug should_break => _1; // in scope 1 at $DIR/issue_38669.rs:+1:9: +1:25 } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 - _1 = const false; // scope 0 at $DIR/issue-38669.rs:+1:28: +1:33 - FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 - goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + StorageLive(_1); // scope 0 at $DIR/issue_38669.rs:+1:9: +1:25 + _1 = const false; // scope 0 at $DIR/issue_38669.rs:+1:28: +1:33 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_38669.rs:+1:9: +1:25 + goto -> bb1; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6 } bb1: { - falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6 } bb2: { - StorageLive(_3); // scope 1 at $DIR/issue-38669.rs:+3:9: +5:10 - StorageLive(_4); // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 - _4 = _1; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 - switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 + StorageLive(_3); // scope 1 at $DIR/issue_38669.rs:+3:9: +5:10 + StorageLive(_4); // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 + _4 = _1; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 + switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 } bb3: { - _0 = const (); // scope 1 at $DIR/issue-38669.rs:+4:13: +4:18 - StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 - StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 - StorageDead(_1); // scope 0 at $DIR/issue-38669.rs:+8:1: +8:2 - return; // scope 0 at $DIR/issue-38669.rs:+8:2: +8:2 + _0 = const (); // scope 1 at $DIR/issue_38669.rs:+4:13: +4:18 + StorageDead(_4); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10 + StorageDead(_3); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10 + StorageDead(_1); // scope 0 at $DIR/issue_38669.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue_38669.rs:+8:2: +8:2 } bb4: { - _3 = const (); // scope 1 at $DIR/issue-38669.rs:+5:10: +5:10 - StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 - StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 - _1 = const true; // scope 1 at $DIR/issue-38669.rs:+6:9: +6:28 - _2 = const (); // scope 1 at $DIR/issue-38669.rs:+2:10: +7:6 - goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + _3 = const (); // scope 1 at $DIR/issue_38669.rs:+5:10: +5:10 + StorageDead(_4); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10 + StorageDead(_3); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10 + _1 = const true; // scope 1 at $DIR/issue_38669.rs:+6:9: +6:28 + _2 = const (); // scope 1 at $DIR/issue_38669.rs:+2:10: +7:6 + goto -> bb1; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6 } bb5 (cleanup): { - resume; // scope 0 at $DIR/issue-38669.rs:+0:1: +8:2 + resume; // scope 0 at $DIR/issue_38669.rs:+0:1: +8:2 } } diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue_38669.rs similarity index 100% rename from src/test/mir-opt/issue-38669.rs rename to src/test/mir-opt/issue_38669.rs diff --git a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir index 1d7cb91d6a7e8..c573ad5a8e4a4 100644 --- a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir @@ -1,70 +1,70 @@ // MIR for `main` after ElaborateDrops fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - let mut _2: S; // in scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - let mut _3: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 - let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 - let mut _5: bool; // in scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + let mut _3: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + let mut _5: bool; // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 scope 1 { - debug x => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10 + debug x => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 } bb0: { - _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - _5 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - _2 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 - StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 - _4 = S; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 - _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 + _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _5 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _2 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_3); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + StorageLive(_4); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _4 = S; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 // mir::Constant - // + span: $DIR/issue-41110.rs:8:23: 8:25 + // + span: $DIR/issue_41110.rs:8:23: 8:25 // + literal: Const { ty: fn(S) -> S {S::id}, val: Value() } } bb1: { - StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27 - _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28 - _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28 + StorageDead(_4); // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 + _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 + _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 // mir::Constant - // + span: $DIR/issue-41110.rs:8:15: 8:20 + // + span: $DIR/issue_41110.rs:8:15: 8:20 // + literal: Const { ty: fn(S, S) {S::other}, val: Value() } } bb2: { - StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 - _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 - StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 - _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:11: +2:2 - StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-41110.rs:+2:2: +2:2 + StorageDead(_3); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + StorageDead(_2); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2 } bb3 (cleanup): { - goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 } bb4 (cleanup): { - goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27 + goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 } bb5 (cleanup): { - goto -> bb8; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + goto -> bb8; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 } bb6 (cleanup): { - resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +2:2 + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2 } bb7 (cleanup): { - drop(_2) -> bb6; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + drop(_2) -> bb6; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 } bb8 (cleanup): { - switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 } } diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue_41110.rs similarity index 100% rename from src/test/mir-opt/issue-41110.rs rename to src/test/mir-opt/issue_41110.rs diff --git a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir index b0e3496b2c8eb..470b032328184 100644 --- a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir @@ -1,101 +1,101 @@ // MIR for `test` after ElaborateDrops fn test() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:15: +0:15 - let _1: S; // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - let _3: (); // in scope 0 at $DIR/issue-41110.rs:+3:5: +3:12 - let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+3:10: +3:11 - let mut _5: S; // in scope 0 at $DIR/issue-41110.rs:+4:9: +4:10 - let mut _6: bool; // in scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15 + let _1: S; // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11 + let mut _5: S; // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10 + let mut _6: bool; // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 scope 1 { - debug u => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10 - let mut _2: S; // in scope 1 at $DIR/issue-41110.rs:+2:9: +2:14 + debug u => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 scope 2 { - debug v => _2; // in scope 2 at $DIR/issue-41110.rs:+2:9: +2:14 + debug v => _2; // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14 } } bb0: { - _6 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 - _6 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - _1 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 - StorageLive(_2); // scope 1 at $DIR/issue-41110.rs:+2:9: +2:14 - _2 = S; // scope 1 at $DIR/issue-41110.rs:+2:17: +2:18 - StorageLive(_3); // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12 - StorageLive(_4); // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11 - _4 = move _2; // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11 - _3 = std::mem::drop::(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12 + _6 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + _6 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _1 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 + _2 = S; // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 + StorageLive(_4); // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _4 = move _2; // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _3 = std::mem::drop::(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 // mir::Constant - // + span: $DIR/issue-41110.rs:17:5: 17:9 + // + span: $DIR/issue_41110.rs:17:5: 17:9 // + literal: Const { ty: fn(S) {std::mem::drop::}, val: Value() } } bb1: { - StorageDead(_4); // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12 - StorageDead(_3); // scope 2 at $DIR/issue-41110.rs:+3:12: +3:13 - StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 - _6 = const false; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 - _5 = move _1; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 - goto -> bb12; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + StorageDead(_4); // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + StorageDead(_3); // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13 + StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + goto -> bb12; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 } bb2: { - goto -> bb3; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + goto -> bb3; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 } bb3: { - StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 - _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:15: +5:2 - drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 + StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 + drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 } bb4: { - StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 - goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } bb5: { - _6 = const false; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 - StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 - return; // scope 0 at $DIR/issue-41110.rs:+5:2: +5:2 + _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2 } bb6 (cleanup): { - goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 } bb7 (cleanup): { - goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12 + goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 } bb8 (cleanup): { - goto -> bb9; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 + goto -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 } bb9 (cleanup): { - goto -> bb14; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + goto -> bb14; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } bb10 (cleanup): { - resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2 } bb11 (cleanup): { - _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 - goto -> bb6; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + goto -> bb6; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 } bb12: { - _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 - goto -> bb2; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 } bb13 (cleanup): { - drop(_1) -> bb10; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } bb14 (cleanup): { - switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } } diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue_41697.rs similarity index 100% rename from src/test/mir-opt/issue-41697.rs rename to src/test/mir-opt/issue_41697.rs diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir index 047b24db46643..8af087d84f116 100644 --- a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir +++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir @@ -1,20 +1,20 @@ -// MIR for `::{constant#0}` after SimplifyCfg-promote-consts +// MIR for `::{constant#0}` after SimplifyCfg-promote-consts -::{constant#0}: usize = { - let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 - let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 +::{constant#0}: usize = { + let mut _0: usize; // return place in scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 + let mut _1: (usize, bool); // in scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 bb0: { - _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 - assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 + assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 } bb1: { - _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 - return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + _0 = move (_1.0: usize); // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 + return; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 } bb2 (cleanup): { - resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + resume; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22 } } diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir index f95a0a1c013bc..73372c97bea72 100644 --- a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir @@ -1,152 +1,152 @@ // MIR for `main` after ElaborateDrops fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-41888.rs:+0:11: +0:11 - let _1: E; // in scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 - let mut _2: bool; // in scope 0 at $DIR/issue-41888.rs:+2:8: +2:14 - let mut _3: E; // in scope 0 at $DIR/issue-41888.rs:+3:13: +3:20 - let mut _4: K; // in scope 0 at $DIR/issue-41888.rs:+3:18: +3:19 - let mut _5: isize; // in scope 0 at $DIR/issue-41888.rs:+4:16: +4:24 - let mut _7: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - let mut _8: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - let mut _9: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - let mut _10: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - let mut _11: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + let mut _0: (); // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11 + let _1: E; // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + let mut _2: bool; // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14 + let mut _3: E; // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20 + let mut _4: K; // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19 + let mut _5: isize; // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24 + let mut _7: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + let mut _8: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + let mut _9: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + let mut _10: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + let mut _11: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 scope 1 { - debug e => _1; // in scope 1 at $DIR/issue-41888.rs:+1:9: +1:10 + debug e => _1; // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10 scope 2 { - debug _k => _6; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 - let _6: K; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + debug _k => _6; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + let _6: K; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 } } bb0: { - _9 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 - _7 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 - _8 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 - _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 + _9 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + _7 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + _8 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 // mir::Constant - // + span: $DIR/issue-41888.rs:8:8: 8:12 + // + span: $DIR/issue_41888.rs:8:8: 8:12 // + literal: Const { ty: fn() -> bool {cond}, val: Value() } } bb1: { - switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 + switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 } bb2: { - StorageLive(_3); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20 - StorageLive(_4); // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19 - _4 = K; // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19 - _3 = E::F(move _4); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20 - StorageDead(_4); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 - goto -> bb14; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageLive(_4); // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + goto -> bb14; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 } bb3: { - goto -> bb4; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + goto -> bb4; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 } bb4: { - StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 - _5 = discriminant(_1); // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24 - switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24 + StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 } bb5: { - StorageLive(_6); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 - _9 = const false; // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 - _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 - _0 = const (); // scope 2 at $DIR/issue-41888.rs:+4:29: +7:10 - StorageDead(_6); // scope 1 at $DIR/issue-41888.rs:+7:9: +7:10 - goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10 + StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10 + StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 } bb6: { - _0 = const (); // scope 1 at $DIR/issue-41888.rs:+7:10: +7:10 - goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10 + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 } bb7: { - _0 = const (); // scope 1 at $DIR/issue-41888.rs:+8:6: +8:6 - goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+2:5: +8:6 + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 } bb8: { - StorageDead(_2); // scope 1 at $DIR/issue-41888.rs:+8:5: +8:6 - goto -> bb20; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 + goto -> bb20; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb9: { - _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - _8 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - _9 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - StorageDead(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - return; // scope 0 at $DIR/issue-41888.rs:+9:2: +9:2 + _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2 } bb10 (cleanup): { - goto -> bb11; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + goto -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 } bb11 (cleanup): { - goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb12 (cleanup): { - resume; // scope 0 at $DIR/issue-41888.rs:+0:1: +9:2 + resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 } bb13 (cleanup): { - _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - goto -> bb10; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + goto -> bb10; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 } bb14: { - _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 - goto -> bb3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 } bb15: { - _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - goto -> bb9; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + goto -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb16 (cleanup): { - goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb17: { - drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb18 (cleanup): { - drop(_1) -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb19: { - _10 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb20: { - switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb21 (cleanup): { - _11 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 - switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb22 (cleanup): { - switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } } diff --git a/src/test/mir-opt/issue-41888.rs b/src/test/mir-opt/issue_41888.rs similarity index 100% rename from src/test/mir-opt/issue-41888.rs rename to src/test/mir-opt/issue_41888.rs diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue_62289.rs similarity index 100% rename from src/test/mir-opt/issue-62289.rs rename to src/test/mir-opt/issue_62289.rs diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir index 72603dc5dbea2..6969a66ac1925 100644 --- a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir +++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir @@ -1,122 +1,122 @@ // MIR for `test` before ElaborateDrops fn test() -> Option> { - let mut _0: std::option::Option>; // return place in scope 0 at $DIR/issue-62289.rs:+0:14: +0:30 - let mut _1: std::boxed::Box; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - let mut _2: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - let mut _3: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - let mut _4: *mut u8; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - let mut _5: std::boxed::Box; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - let mut _6: std::ops::ControlFlow, u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 - let mut _7: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 - let mut _8: isize; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - let _9: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - let mut _10: !; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - let mut _11: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - let _12: u32; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + let mut _0: std::option::Option>; // return place in scope 0 at $DIR/issue_62289.rs:+0:14: +0:30 + let mut _1: std::boxed::Box; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + let mut _2: usize; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + let mut _3: usize; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + let mut _4: *mut u8; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + let mut _5: std::boxed::Box; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + let mut _6: std::ops::ControlFlow, u32>; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + let mut _7: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:19 + let mut _8: isize; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + let _9: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + let mut _10: !; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + let mut _11: std::option::Option; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + let _12: u32; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 scope 1 { } scope 2 { - debug residual => _9; // in scope 2 at $DIR/issue-62289.rs:+1:19: +1:20 + debug residual => _9; // in scope 2 at $DIR/issue_62289.rs:+1:19: +1:20 scope 3 { } } scope 4 { - debug val => _12; // in scope 4 at $DIR/issue-62289.rs:+1:15: +1:20 + debug val => _12; // in scope 4 at $DIR/issue_62289.rs:+1:15: +1:20 scope 5 { } } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - _2 = SizeOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 - _3 = AlignOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 - _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 + StorageLive(_1); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + _2 = SizeOf(u32); // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21 + _3 = AlignOf(u32); // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21 // mir::Constant - // + span: $DIR/issue-62289.rs:9:10: 9:21 + // + span: $DIR/issue_62289.rs:9:10: 9:21 // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } } bb1: { - StorageLive(_5); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - StorageLive(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 - StorageLive(_7); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 - _7 = Option::::None; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 - _6 = as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + StorageLive(_5); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + StorageLive(_6); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + StorageLive(_7); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:19 + _7 = Option::::None; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:19 + _6 = as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 // mir::Constant - // + span: $DIR/issue-62289.rs:9:15: 9:20 + // + span: $DIR/issue_62289.rs:9:15: 9:20 // + literal: Const { ty: fn(Option) -> ControlFlow< as Try>::Residual, as Try>::Output> { as Try>::branch}, val: Value() } } bb2: { - StorageDead(_7); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - _8 = discriminant(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 - switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + StorageDead(_7); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + _8 = discriminant(_6); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 } bb3: { - StorageLive(_12); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 - _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 - (*_5) = _12; // scope 5 at $DIR/issue-62289.rs:+1:15: +1:20 - StorageDead(_12); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - _1 = move _5; // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 - drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + StorageLive(_12); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + (*_5) = _12; // scope 5 at $DIR/issue_62289.rs:+1:15: +1:20 + StorageDead(_12); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + _1 = move _5; // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21 + drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21 } bb4: { - unreachable; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + unreachable; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 } bb5: { - StorageLive(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - _9 = ((_6 as Break).0: std::option::Option); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - StorageLive(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 - _11 = _9; // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 - _0 = > as FromResidual>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue-62289.rs:+1:15: +1:20 + StorageLive(_9); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + _9 = ((_6 as Break).0: std::option::Option); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + StorageLive(_11); // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20 + _11 = _9; // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20 + _0 = > as FromResidual>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue_62289.rs:+1:15: +1:20 // mir::Constant - // + span: $DIR/issue-62289.rs:9:19: 9:20 + // + span: $DIR/issue_62289.rs:9:19: 9:20 // + literal: Const { ty: fn(Option) -> Option> {> as FromResidual>>::from_residual}, val: Value() } } bb6: { - StorageDead(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 - StorageDead(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 - drop(_5) -> bb9; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + StorageDead(_11); // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20 + StorageDead(_9); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 + drop(_5) -> bb9; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21 } bb7: { - StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 - _0 = Option::>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:+1:5: +1:22 - drop(_1) -> bb8; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21 + _0 = Option::>::Some(move _1); // scope 0 at $DIR/issue_62289.rs:+1:5: +1:22 + drop(_1) -> bb8; // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22 } bb8: { - StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 - StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2 - goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22 + StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+2:1: +2:2 + goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2 } bb9: { - StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 - StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 - StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2 - goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21 + StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22 + StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+2:1: +2:2 + goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2 } bb10: { - return; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + return; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2 } bb11 (cleanup): { - drop(_1) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + drop(_1) -> bb13; // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22 } bb12 (cleanup): { - drop(_5) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + drop(_5) -> bb13; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21 } bb13 (cleanup): { - resume; // scope 0 at $DIR/issue-62289.rs:+0:1: +2:2 + resume; // scope 0 at $DIR/issue_62289.rs:+0:1: +2:2 } } diff --git a/src/test/mir-opt/issue_72181.bar.built.after.mir b/src/test/mir-opt/issue_72181.bar.built.after.mir index aa9c9986aac19..ebee89001b998 100644 --- a/src/test/mir-opt/issue_72181.bar.built.after.mir +++ b/src/test/mir-opt/issue_72181.bar.built.after.mir @@ -1,17 +1,17 @@ // MIR for `bar` after built fn bar(_1: [(Never, u32); 1]) -> u32 { - let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43 - let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + let mut _0: u32; // return place in scope 0 at $DIR/issue_72181.rs:+0:40: +0:43 + let _2: u32; // in scope 0 at $DIR/issue_72181.rs:+0:13: +0:14 scope 1 { - debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14 + debug x => _2; // in scope 1 at $DIR/issue_72181.rs:+0:13: +0:14 } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 - _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 - _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47 - StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 - return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + StorageLive(_2); // scope 0 at $DIR/issue_72181.rs:+0:13: +0:14 + _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue_72181.rs:+0:13: +0:14 + _0 = _2; // scope 1 at $DIR/issue_72181.rs:+0:46: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue_72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue_72181.rs:+0:49: +0:49 } } diff --git a/src/test/mir-opt/issue_72181.foo.built.after.mir b/src/test/mir-opt/issue_72181.foo.built.after.mir index 1d771ad3656d2..90c9785202a74 100644 --- a/src/test/mir-opt/issue_72181.foo.built.after.mir +++ b/src/test/mir-opt/issue_72181.foo.built.after.mir @@ -1,27 +1,27 @@ // MIR for `foo` after built fn foo(_1: [(Never, u32); 1]) -> u32 { - debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10 - let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37 - let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 - let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 - let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + debug xs => _1; // in scope 0 at $DIR/issue_72181.rs:+0:8: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/issue_72181.rs:+0:34: +0:37 + let _2: usize; // in scope 0 at $DIR/issue_72181.rs:+0:43: +0:44 + let mut _3: usize; // in scope 0 at $DIR/issue_72181.rs:+0:40: +0:45 + let mut _4: bool; // in scope 0 at $DIR/issue_72181.rs:+0:40: +0:45 bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 - _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 - _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 - _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 - assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + StorageLive(_2); // scope 0 at $DIR/issue_72181.rs:+0:43: +0:44 + _2 = const 0_usize; // scope 0 at $DIR/issue_72181.rs:+0:43: +0:44 + _3 = Len(_1); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45 + _4 = Lt(_2, _3); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45 + assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45 } bb1: { - _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47 - StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 - return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue_72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue_72181.rs:+0:49: +0:49 } bb2 (cleanup): { - resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49 + resume; // scope 0 at $DIR/issue_72181.rs:+0:1: +0:49 } } diff --git a/src/test/mir-opt/issue_72181.main.built.after.mir b/src/test/mir-opt/issue_72181.main.built.after.mir index afa09b16fe964..e8683692770d1 100644 --- a/src/test/mir-opt/issue_72181.main.built.after.mir +++ b/src/test/mir-opt/issue_72181.main.built.after.mir @@ -1,18 +1,18 @@ // MIR for `main` after built fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11 - let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 - let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27 - let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42 - let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30 - let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25 - let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 - let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 + let mut _0: (); // return place in scope 0 at $DIR/issue_72181.rs:+0:11: +0:11 + let mut _1: usize; // in scope 0 at $DIR/issue_72181.rs:+1:13: +1:34 + let mut _3: Foo; // in scope 0 at $DIR/issue_72181.rs:+3:14: +3:27 + let mut _4: Foo; // in scope 0 at $DIR/issue_72181.rs:+3:29: +3:42 + let mut _5: u64; // in scope 0 at $DIR/issue_72181.rs:+4:13: +4:30 + let _6: usize; // in scope 0 at $DIR/issue_72181.rs:+4:24: +4:25 + let mut _7: usize; // in scope 0 at $DIR/issue_72181.rs:+4:22: +4:26 + let mut _8: bool; // in scope 0 at $DIR/issue_72181.rs:+4:22: +4:26 scope 1 { - let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + let _2: [Foo; 2]; // in scope 1 at $DIR/issue_72181.rs:+3:9: +3:10 scope 2 { - debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10 + debug f => _2; // in scope 2 at $DIR/issue_72181.rs:+3:9: +3:10 scope 3 { } scope 4 { @@ -21,42 +21,42 @@ fn main() -> () { } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 - _1 = std::mem::size_of::() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + StorageLive(_1); // scope 0 at $DIR/issue_72181.rs:+1:13: +1:34 + _1 = std::mem::size_of::() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_72181.rs:+1:13: +1:34 // mir::Constant - // + span: $DIR/issue-72181.rs:24:13: 24:32 + // + span: $DIR/issue_72181.rs:24:13: 24:32 // + literal: Const { ty: fn() -> usize {std::mem::size_of::}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35 - StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 - StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 - _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 - StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 - _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 - _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43 - StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 - StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 - FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 - StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30 - StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 - _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 - _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 - _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + StorageDead(_1); // scope 0 at $DIR/issue_72181.rs:+1:34: +1:35 + StorageLive(_2); // scope 1 at $DIR/issue_72181.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/issue_72181.rs:+3:14: +3:27 + _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue_72181.rs:+3:14: +3:27 + StorageLive(_4); // scope 1 at $DIR/issue_72181.rs:+3:29: +3:42 + _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue_72181.rs:+3:29: +3:42 + _2 = [move _3, move _4]; // scope 1 at $DIR/issue_72181.rs:+3:13: +3:43 + StorageDead(_4); // scope 1 at $DIR/issue_72181.rs:+3:42: +3:43 + StorageDead(_3); // scope 1 at $DIR/issue_72181.rs:+3:42: +3:43 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue_72181.rs:+3:9: +3:10 + StorageLive(_5); // scope 2 at $DIR/issue_72181.rs:+4:13: +4:30 + StorageLive(_6); // scope 4 at $DIR/issue_72181.rs:+4:24: +4:25 + _6 = const 0_usize; // scope 4 at $DIR/issue_72181.rs:+4:24: +4:25 + _7 = Len(_2); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26 + _8 = Lt(_6, _7); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26 + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26 } bb2: { - _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28 - StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 - StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 - _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2 - StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2 - return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2 + _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:28 + StorageDead(_6); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31 + StorageDead(_5); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31 + _0 = const (); // scope 0 at $DIR/issue_72181.rs:+0:11: +5:2 + StorageDead(_2); // scope 1 at $DIR/issue_72181.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_72181.rs:+5:2: +5:2 } bb3 (cleanup): { - resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/issue_72181.rs:+0:1: +5:2 } } diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue_72181.rs similarity index 100% rename from src/test/mir-opt/issue-72181.rs rename to src/test/mir-opt/issue_72181.rs diff --git a/src/test/mir-opt/issue_72181_1.f.built.after.mir b/src/test/mir-opt/issue_72181_1.f.built.after.mir index 31e997f9b33d9..4086da5201134 100644 --- a/src/test/mir-opt/issue_72181_1.f.built.after.mir +++ b/src/test/mir-opt/issue_72181_1.f.built.after.mir @@ -1,29 +1,29 @@ // MIR for `f` after built fn f(_1: Void) -> ! { - debug v => _1; // in scope 0 at $DIR/issue-72181-1.rs:+0:6: +0:7 - let mut _0: !; // return place in scope 0 at $DIR/issue-72181-1.rs:+0:18: +0:19 - let mut _2: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 - let mut _3: !; // in scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 + debug v => _1; // in scope 0 at $DIR/issue_72181_1.rs:+0:6: +0:7 + let mut _0: !; // return place in scope 0 at $DIR/issue_72181_1.rs:+0:18: +0:19 + let mut _2: !; // in scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2 + let mut _3: !; // in scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15 bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 - StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 - FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12 - unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12 + StorageLive(_2); // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2 + StorageLive(_3); // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12 + unreachable; // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12 } bb1: { - unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 + unreachable; // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15 } bb2: { - StorageDead(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:14: +1:15 - unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 + StorageDead(_3); // scope 0 at $DIR/issue_72181_1.rs:+1:14: +1:15 + unreachable; // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2 } bb3: { - StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue-72181-1.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue_72181_1.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_72181_1.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/issue_72181_1.main.built.after.mir b/src/test/mir-opt/issue_72181_1.main.built.after.mir index 65177a81b03b4..2172f3aa9e285 100644 --- a/src/test/mir-opt/issue_72181_1.main.built.after.mir +++ b/src/test/mir-opt/issue_72181_1.main.built.after.mir @@ -1,57 +1,57 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue_72181_1.rs:16:12: 16:16, inferred_ty: Void +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue_72181_1.rs:16:12: 16:16, inferred_ty: Void | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:+0:11: +0:11 - let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2 - let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 - let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:+2:41: +2:43 - let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:+5:5: +5:9 - let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:+5:7: +5:8 + let mut _0: (); // return place in scope 0 at $DIR/issue_72181_1.rs:+0:11: +0:11 + let mut _1: !; // in scope 0 at $DIR/issue_72181_1.rs:+0:11: +6:2 + let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10 + let mut _3: (); // in scope 0 at $DIR/issue_72181_1.rs:+2:41: +2:43 + let _4: !; // in scope 0 at $DIR/issue_72181_1.rs:+5:5: +5:9 + let mut _5: Void; // in scope 0 at $DIR/issue_72181_1.rs:+5:7: +5:8 scope 1 { - debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:+1:9: +1:10 + debug v => _2; // in scope 1 at $DIR/issue_72181_1.rs:+1:9: +1:10 } scope 2 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 - StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43 - _3 = (); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43 - _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:+2:9: +2:44 + StorageLive(_2); // scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10 + StorageLive(_3); // scope 2 at $DIR/issue_72181_1.rs:+2:41: +2:43 + _3 = (); // scope 2 at $DIR/issue_72181_1.rs:+2:41: +2:43 + _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue_72181_1.rs:+2:9: +2:44 // mir::Constant - // + span: $DIR/issue-72181-1.rs:17:9: 17:40 + // + span: $DIR/issue_72181_1.rs:17:9: 17:40 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value() } } bb1: { - StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:43: +2:44 - FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 - AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:+1:12: +1:16 - StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9 - StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8 - _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8 - _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9 + StorageDead(_3); // scope 2 at $DIR/issue_72181_1.rs:+2:43: +2:44 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10 + AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_72181_1.rs:+1:12: +1:16 + StorageLive(_4); // scope 1 at $DIR/issue_72181_1.rs:+5:5: +5:9 + StorageLive(_5); // scope 1 at $DIR/issue_72181_1.rs:+5:7: +5:8 + _5 = move _2; // scope 1 at $DIR/issue_72181_1.rs:+5:7: +5:8 + _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue_72181_1.rs:+5:5: +5:9 // mir::Constant - // + span: $DIR/issue-72181-1.rs:20:5: 20:6 + // + span: $DIR/issue_72181_1.rs:20:5: 20:6 // + literal: Const { ty: fn(Void) -> ! {f}, val: Value() } } bb2: { - StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:8: +5:9 - StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:9: +5:10 - StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+6:1: +6:2 - unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2 + StorageDead(_5); // scope 1 at $DIR/issue_72181_1.rs:+5:8: +5:9 + StorageDead(_4); // scope 1 at $DIR/issue_72181_1.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/issue_72181_1.rs:+6:1: +6:2 + unreachable; // scope 0 at $DIR/issue_72181_1.rs:+0:11: +6:2 } bb3: { - return; // scope 0 at $DIR/issue-72181-1.rs:+6:2: +6:2 + return; // scope 0 at $DIR/issue_72181_1.rs:+6:2: +6:2 } bb4 (cleanup): { - resume; // scope 0 at $DIR/issue-72181-1.rs:+0:1: +6:2 + resume; // scope 0 at $DIR/issue_72181_1.rs:+0:1: +6:2 } } diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue_72181_1.rs similarity index 100% rename from src/test/mir-opt/issue-72181-1.rs rename to src/test/mir-opt/issue_72181_1.rs diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff index 269e4e3261751..c9a9511586d78 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -2,18 +2,18 @@ + // MIR for `main` after SimplifyArmIdentity fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 - let mut _2: std::option::Option; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16 - let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 - let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 - let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27 + let mut _0: (); // return place in scope 0 at $DIR/issue_73223.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/issue_73223.rs:+1:9: +1:14 + let mut _2: std::option::Option; // in scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + let mut _3: isize; // in scope 0 at $DIR/issue_73223.rs:+2:9: +2:16 + let _4: i32; // in scope 0 at $DIR/issue_73223.rs:+2:14: +2:15 + let mut _5: !; // in scope 0 at $DIR/issue_73223.rs:+3:17: +3:23 + let mut _7: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27 let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24 + let _12: i32; // in scope 0 at $DIR/issue_73223.rs:+7:23: +7:24 let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -27,10 +27,10 @@ let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _27: std::option::Option>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { - debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14 - let _6: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + debug split => _1; // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14 + let _6: std::option::Option; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 scope 3 { - debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14 + debug _prev => _6; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14 let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -45,43 +45,43 @@ } } scope 2 { - debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15 + debug v => _4; // in scope 2 at $DIR/issue_73223.rs:+2:14: +2:15 } bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 - StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 - goto -> bb3; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30 + StorageLive(_1); // scope 0 at $DIR/issue_73223.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + Deinit(_2); // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + discriminant(_2) = 1; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + _3 = const 1_isize; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + goto -> bb3; // scope 0 at $DIR/issue_73223.rs:+1:17: +1:30 } bb1: { - nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 - StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 - StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 - return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + nop; // scope 0 at $DIR/issue_73223.rs:+3:17: +3:23 + StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7 + StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2 } bb2: { - unreachable; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + unreachable; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 } bb3: { - StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 - _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 - _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21 - StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21 - StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 - StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 - StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 - _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 - Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 - ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 - discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 - StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28 + StorageLive(_4); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15 + _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15 + _1 = _4; // scope 2 at $DIR/issue_73223.rs:+2:20: +2:21 + StorageDead(_4); // scope 0 at $DIR/issue_73223.rs:+2:20: +2:21 + StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7 + StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 + StorageLive(_7); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + _7 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + Deinit(_6); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + discriminant(_6) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + StorageDead(_7); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28 StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -152,10 +152,10 @@ StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2 - StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2 - StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 - return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + nop; // scope 0 at $DIR/issue_73223.rs:+0:11: +8:2 + StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2 } } diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue_73223.rs similarity index 100% rename from src/test/mir-opt/issue-73223.rs rename to src/test/mir-opt/issue_73223.rs diff --git a/src/test/mir-opt/issue_78192.f.InstCombine.diff b/src/test/mir-opt/issue_78192.f.InstCombine.diff index 8ec94d65fda52..116ca304c9939 100644 --- a/src/test/mir-opt/issue_78192.f.InstCombine.diff +++ b/src/test/mir-opt/issue_78192.f.InstCombine.diff @@ -2,28 +2,28 @@ + // MIR for `f` after InstCombine fn f(_1: &T) -> *const T { - debug a => _1; // in scope 0 at $DIR/issue-78192.rs:+0:13: +0:14 - let mut _0: *const T; // return place in scope 0 at $DIR/issue-78192.rs:+0:23: +0:31 - let _2: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:9: +1:10 - let _3: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 - let _4: *const T; // in scope 0 at $DIR/issue-78192.rs:+1:25: +1:40 + debug a => _1; // in scope 0 at $DIR/issue_78192.rs:+0:13: +0:14 + let mut _0: *const T; // return place in scope 0 at $DIR/issue_78192.rs:+0:23: +0:31 + let _2: &*const T; // in scope 0 at $DIR/issue_78192.rs:+1:9: +1:10 + let _3: &*const T; // in scope 0 at $DIR/issue_78192.rs:+1:24: +1:40 + let _4: *const T; // in scope 0 at $DIR/issue_78192.rs:+1:25: +1:40 scope 1 { - debug b => _2; // in scope 1 at $DIR/issue-78192.rs:+1:9: +1:10 + debug b => _2; // in scope 1 at $DIR/issue_78192.rs:+1:9: +1:10 } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-78192.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 - StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:+1:25: +1:40 - _4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:+1:26: +1:27 - _3 = &_4; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 -- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 -+ _2 = _3; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 - StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:+1:40: +1:41 - _0 = (*_2); // scope 1 at $DIR/issue-78192.rs:+2:5: +2:7 - StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2 - StorageDead(_2); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2 - return; // scope 0 at $DIR/issue-78192.rs:+3:2: +3:2 + StorageLive(_2); // scope 0 at $DIR/issue_78192.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40 + StorageLive(_4); // scope 0 at $DIR/issue_78192.rs:+1:25: +1:40 + _4 = &raw const (*_1); // scope 0 at $DIR/issue_78192.rs:+1:26: +1:27 + _3 = &_4; // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40 +- _2 = &(*_3); // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40 ++ _2 = _3; // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40 + StorageDead(_3); // scope 0 at $DIR/issue_78192.rs:+1:40: +1:41 + _0 = (*_2); // scope 1 at $DIR/issue_78192.rs:+2:5: +2:7 + StorageDead(_4); // scope 0 at $DIR/issue_78192.rs:+3:1: +3:2 + StorageDead(_2); // scope 0 at $DIR/issue_78192.rs:+3:1: +3:2 + return; // scope 0 at $DIR/issue_78192.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/issue-78192.rs b/src/test/mir-opt/issue_78192.rs similarity index 100% rename from src/test/mir-opt/issue-78192.rs rename to src/test/mir-opt/issue_78192.rs diff --git a/src/test/mir-opt/issue_91633.bar.built.after.mir b/src/test/mir-opt/issue_91633.bar.built.after.mir index 19b1b6fe12b8b..c3fb90e84024e 100644 --- a/src/test/mir-opt/issue_91633.bar.built.after.mir +++ b/src/test/mir-opt/issue_91633.bar.built.after.mir @@ -1,39 +1,39 @@ // MIR for `bar` after built fn bar(_1: Box<[T]>) -> () { - debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14 - let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2 - let mut _2: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:19 - let mut _3: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:16 + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2 + let mut _2: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 + let mut _3: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 scope 1 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19 - StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16 - _3 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16 - _2 = <[T] as Index>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19 + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 + _3 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 + _2 = <[T] as Index>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 // mir::Constant - // + span: $DIR/issue-91633.rs:15:14: 15:19 + // + span: $DIR/issue_91633.rs:15:14: 15:19 // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index>::Output {<[T] as Index>::index}, val: Value() } } bb1: { - StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:18: +4:19 - StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20 - _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3 - drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:18: +4:19 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 + drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 } bb2: { - return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3 + return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3 } bb3 (cleanup): { - drop(_1) -> bb4; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3 + drop(_1) -> bb4; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 } bb4 (cleanup): { - resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3 + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3 } } diff --git a/src/test/mir-opt/issue_91633.foo.built.after.mir b/src/test/mir-opt/issue_91633.foo.built.after.mir index 1a6eee93d3689..4e3dd365e924f 100644 --- a/src/test/mir-opt/issue_91633.foo.built.after.mir +++ b/src/test/mir-opt/issue_91633.foo.built.after.mir @@ -1,57 +1,57 @@ // MIR for `foo` after built fn foo(_1: Box<[T]>) -> T { - debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21 - let mut _0: T; // return place in scope 0 at $DIR/issue-91633.rs:+0:36: +0:37 - let _2: T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - let mut _3: &T; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:27 - let _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:17: +2:18 - let mut _5: usize; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19 - let mut _6: bool; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19 + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:19: +0:21 + let mut _0: T; // return place in scope 0 at $DIR/issue_91633.rs:+0:36: +0:37 + let _2: T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + let mut _3: &T; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + let _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + let mut _5: usize; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 scope 1 { - debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11 + debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11 } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27 - StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18 - _4 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18 - _5 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19 - _6 = Lt(_4, _5); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19 - assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19 + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + _4 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + _5 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + _6 = Lt(_4, _5); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 } bb1: { - _3 = &(*_1)[_4]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27 - _2 = ::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27 + _3 = &(*_1)[_4]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + _2 = ::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 // mir::Constant - // + span: $DIR/issue-91633.rs:28:20: 28:25 + // + span: $DIR/issue_91633.rs:28:20: 28:25 // + literal: Const { ty: for<'a> fn(&'a T) -> T {::clone}, val: Value() } } bb2: { - StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+2:26: +2:27 - FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+2:27: +2:28 - _0 = move _2; // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7 - drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+2:26: +2:27 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+2:27: +2:28 + _0 = move _2; // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7 + drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 } bb3: { - StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 - drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 } bb4: { - return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3 + return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3 } bb5 (cleanup): { - drop(_1) -> bb6; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 + drop(_1) -> bb6; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 } bb6 (cleanup): { - resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3 + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3 } } diff --git a/src/test/mir-opt/issue_91633.fun.built.after.mir b/src/test/mir-opt/issue_91633.fun.built.after.mir index b3eea60033011..42486d3a50e38 100644 --- a/src/test/mir-opt/issue_91633.fun.built.after.mir +++ b/src/test/mir-opt/issue_91633.fun.built.after.mir @@ -1,35 +1,35 @@ // MIR for `fun` after built fn fun(_1: &[T]) -> &T { - debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14 - let mut _0: &T; // return place in scope 0 at $DIR/issue-91633.rs:+0:25: +0:27 - let _2: &T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - let _3: usize; // in scope 0 at $DIR/issue-91633.rs:+2:18: +2:19 - let mut _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20 - let mut _5: bool; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20 + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: &T; // return place in scope 0 at $DIR/issue_91633.rs:+0:25: +0:27 + let _2: &T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + let _3: usize; // in scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + let mut _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + let mut _5: bool; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 scope 1 { - debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11 + debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11 } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19 - _3 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19 - _4 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20 - _5 = Lt(_3, _4); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20 - assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20 + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + _3 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + _4 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + _5 = Lt(_3, _4); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 } bb1: { - _2 = &(*_1)[_3]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:20 - FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11 - _0 = &(*_2); // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7 - StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 - StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3 - return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3 + _2 = &(*_1)[_3]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:20 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + _0 = &(*_2); // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3 } bb2 (cleanup): { - resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3 + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3 } } diff --git a/src/test/mir-opt/issue_91633.hey.built.after.mir b/src/test/mir-opt/issue_91633.hey.built.after.mir index e7e31ad33c1be..ccb06dd5983f4 100644 --- a/src/test/mir-opt/issue_91633.hey.built.after.mir +++ b/src/test/mir-opt/issue_91633.hey.built.after.mir @@ -1,35 +1,35 @@ // MIR for `hey` after built fn hey(_1: &[T]) -> () { - debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14 - let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2 - let mut _2: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:20 - let _3: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:20 - let mut _4: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:17 + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2 + let mut _2: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + let _3: &<[T] as std::ops::Index>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 + let mut _4: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 scope 1 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20 - StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20 - StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17 - _4 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17 - _3 = <[T] as Index>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20 + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 + StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 + _4 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 + _3 = <[T] as Index>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 // mir::Constant - // + span: $DIR/issue-91633.rs:7:15: 7:20 + // + span: $DIR/issue_91633.rs:7:15: 7:20 // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index>::Output {<[T] as Index>::index}, val: Value() } } bb1: { - StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20 - _2 = &(*_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20 - StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:20: +4:21 - _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3 - StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3 - return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3 + StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 + _2 = &(*_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:20: +4:21 + _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 + return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3 } bb2 (cleanup): { - resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3 + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3 } } diff --git a/src/test/mir-opt/issue-91633.rs b/src/test/mir-opt/issue_91633.rs similarity index 100% rename from src/test/mir-opt/issue-91633.rs rename to src/test/mir-opt/issue_91633.rs diff --git a/src/test/mir-opt/issue_99325.main.built.after.mir b/src/test/mir-opt/issue_99325.main.built.after.mir index f588f06b7e4a3..3db40412b2ef4 100644 --- a/src/test/mir-opt/issue_99325.main.built.after.mir +++ b/src/test/mir-opt/issue_99325.main.built.after.mir @@ -1,18 +1,18 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }) }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15 + let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15 let _1: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _2: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _3: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _4: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 + let _4: &[u8]; // in scope 0 at $DIR/issue_99325.rs:+1:16: +1:48 let mut _5: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _6: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 - let _7: [u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 + let _6: &[u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+1:50: +1:75 + let _7: [u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+1:51: +1:75 let _8: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _9: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -30,9 +30,9 @@ fn main() -> () { let _23: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _24: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _25: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _26: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 + let _26: &[u8]; // in scope 0 at $DIR/issue_99325.rs:+2:16: +2:70 let mut _27: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _28: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 + let _28: &[u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+2:72: +2:79 let _29: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _30: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _31: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -68,10 +68,10 @@ fn main() -> () { StorageLive(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_4); // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 + StorageLive(_4); // scope 0 at $DIR/issue_99325.rs:+1:16: +1:48 + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue_99325.rs:+1:16: +1:48 // mir::Constant - // + span: $DIR/issue-99325.rs:10:16: 10:46 + // + span: $DIR/issue_99325.rs:10:16: 10:46 // + user_ty: UserType(0) // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value() } } @@ -79,10 +79,10 @@ fn main() -> () { bb1: { _3 = &_4; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_6); // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 - StorageLive(_7); // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 - _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 - _6 = &_7; // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 + StorageLive(_6); // scope 0 at $DIR/issue_99325.rs:+1:50: +1:75 + StorageLive(_7); // scope 0 at $DIR/issue_99325.rs:+1:51: +1:75 + _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue_99325.rs:+1:51: +1:75 + _6 = &_7; // scope 0 at $DIR/issue_99325.rs:+1:50: +1:75 _5 = &_6; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _2 = (move _3, move _5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -176,10 +176,10 @@ fn main() -> () { StorageLive(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_26); // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 - _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 + StorageLive(_26); // scope 0 at $DIR/issue_99325.rs:+2:16: +2:70 + _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue_99325.rs:+2:16: +2:70 // mir::Constant - // + span: $DIR/issue-99325.rs:11:16: 11:68 + // + span: $DIR/issue_99325.rs:11:16: 11:68 // + user_ty: UserType(1) // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value() } } @@ -187,10 +187,10 @@ fn main() -> () { bb10: { _25 = &_26; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_28); // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 - _28 = const b"AAAA"; // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 + StorageLive(_28); // scope 0 at $DIR/issue_99325.rs:+2:72: +2:79 + _28 = const b"AAAA"; // scope 0 at $DIR/issue_99325.rs:+2:72: +2:79 // mir::Constant - // + span: $DIR/issue-99325.rs:11:72: 11:79 + // + span: $DIR/issue_99325.rs:11:72: 11:79 // + literal: Const { ty: &[u8; 4], val: Value(Scalar(alloc4)) } _27 = &_28; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _24 = (move _25, move _27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -281,12 +281,12 @@ fn main() -> () { StorageDead(_26); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _0 = const (); // scope 0 at $DIR/issue-99325.rs:+0:15: +3:2 - return; // scope 0 at $DIR/issue-99325.rs:+3:2: +3:2 + _0 = const (); // scope 0 at $DIR/issue_99325.rs:+0:15: +3:2 + return; // scope 0 at $DIR/issue_99325.rs:+3:2: +3:2 } bb19 (cleanup): { - resume; // scope 0 at $DIR/issue-99325.rs:+0:1: +3:2 + resume; // scope 0 at $DIR/issue_99325.rs:+0:1: +3:2 } } diff --git a/src/test/mir-opt/issue-99325.rs b/src/test/mir-opt/issue_99325.rs similarity index 100% rename from src/test/mir-opt/issue-99325.rs rename to src/test/mir-opt/issue_99325.rs diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index f46c10711f688..1cfa41b4daa49 100644 --- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -1,14 +1,14 @@ // MIR for `num_to_digit` after PreCodegen fn num_to_digit(_1: char) -> u32 { - debug num => _1; // in scope 0 at $DIR/issue-59352.rs:+0:21: +0:24 - let mut _0: u32; // return place in scope 0 at $DIR/issue-59352.rs:+0:35: +0:38 - let mut _2: char; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 - let mut _3: std::option::Option; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 - let mut _4: char; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 - let mut _5: u32; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24 + let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 + let mut _2: char; // in scope 0 at $DIR/issue_59352.rs:+2:8: +2:11 + let mut _3: std::option::Option; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + let mut _4: char; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:29 + let mut _5: u32; // in scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 let mut _12: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - scope 1 (inlined char::methods::::is_digit) { // at $DIR/issue-59352.rs:14:8: 14:23 + scope 1 (inlined char::methods::::is_digit) { // at $DIR/issue_59352.rs:14:8: 14:23 debug self => _2; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL debug radix => _5; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL let mut _6: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL @@ -19,7 +19,7 @@ fn num_to_digit(_1: char) -> u32 { let mut _9: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } } - scope 3 (inlined #[track_caller] Option::::unwrap) { // at $DIR/issue-59352.rs:14:26: 14:50 + scope 3 (inlined #[track_caller] Option::::unwrap) { // at $DIR/issue_59352.rs:14:26: 14:50 debug self => _3; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL let mut _10: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL let mut _11: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL @@ -29,9 +29,9 @@ fn num_to_digit(_1: char) -> u32 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 - _2 = _1; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 - StorageLive(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + StorageLive(_2); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:11 + _2 = _1; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:11 + StorageLive(_5); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL @@ -43,30 +43,30 @@ fn num_to_digit(_1: char) -> u32 { } bb1: { - StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 - StorageLive(_3); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 - StorageLive(_4); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 - _4 = _1; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 - _3 = char::methods::::to_digit(move _4, const 8_u32) -> bb2; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 + StorageDead(_12); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + StorageLive(_4); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:29 + _4 = _1; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:29 + _3 = char::methods::::to_digit(move _4, const 8_u32) -> bb2; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 // mir::Constant - // + span: $DIR/issue-59352.rs:14:30: 14:38 + // + span: $DIR/issue_59352.rs:14:30: 14:38 // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } } bb2: { - StorageDead(_4); // scope 0 at $DIR/issue-59352.rs:+2:40: +2:41 + StorageDead(_4); // scope 0 at $DIR/issue_59352.rs:+2:40: +2:41 _10 = discriminant(_3); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL switchInt(move _10) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL } bb3: { - StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 - _0 = const 0_u32; // scope 0 at $DIR/issue-59352.rs:+2:60: +2:61 - goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63 + StorageDead(_12); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + _0 = const 0_u32; // scope 0 at $DIR/issue_59352.rs:+2:60: +2:61 + goto -> bb4; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63 } bb4: { - return; // scope 0 at $DIR/issue-59352.rs:+3:2: +3:2 + return; // scope 0 at $DIR/issue_59352.rs:+3:2: +3:2 } bb5: { @@ -77,9 +77,9 @@ fn num_to_digit(_1: char) -> u32 { _12 = move _9; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 - StorageDead(_2); // scope 0 at $DIR/issue-59352.rs:+2:22: +2:23 - switchInt(move _12) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + StorageDead(_5); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + StorageDead(_2); // scope 0 at $DIR/issue_59352.rs:+2:22: +2:23 + switchInt(move _12) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { @@ -99,7 +99,7 @@ fn num_to_digit(_1: char) -> u32 { bb8: { _0 = move ((_3 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/issue-59352.rs:+2:49: +2:50 - goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63 + StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:49: +2:50 + goto -> bb4; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63 } } diff --git a/src/test/mir-opt/issues/issue-59352.rs b/src/test/mir-opt/issues/issue_59352.rs similarity index 100% rename from src/test/mir-opt/issues/issue-59352.rs rename to src/test/mir-opt/issues/issue_59352.rs diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff index 2ee4332ad3827..87066cc62c02a 100644 --- a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff +++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -2,17 +2,17 @@ + // MIR for `foo` after MatchBranchSimplification fn foo(_1: [u8; 16]) -> Option<[u8; 4]> { - debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:+0:12: +0:17 - let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:+0:32: +0:47 - let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:+2:9: +2:15 - let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:+2:47: +2:52 - let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:+5:14: +5:38 - let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:+5:33: +5:35 + debug bytes => _1; // in scope 0 at $DIR/issue_75439.rs:+0:12: +0:17 + let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue_75439.rs:+0:32: +0:47 + let _2: [u32; 4]; // in scope 0 at $DIR/issue_75439.rs:+2:9: +2:15 + let mut _3: [u8; 16]; // in scope 0 at $DIR/issue_75439.rs:+2:47: +2:52 + let mut _5: [u8; 4]; // in scope 0 at $DIR/issue_75439.rs:+5:14: +5:38 + let mut _6: u32; // in scope 0 at $DIR/issue_75439.rs:+5:33: +5:35 scope 1 { - debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:+2:9: +2:15 + debug dwords => _2; // in scope 1 at $DIR/issue_75439.rs:+2:9: +2:15 scope 3 { - debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 - let _4: u32; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + debug ip => _4; // in scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 + let _4: u32; // in scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 scope 4 { } } @@ -21,69 +21,69 @@ } bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:+2:9: +2:15 - StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52 - _3 = _1; // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52 - _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:+2:37: +2:53 + StorageLive(_2); // scope 0 at $DIR/issue_75439.rs:+2:9: +2:15 + StorageLive(_3); // scope 2 at $DIR/issue_75439.rs:+2:47: +2:52 + _3 = _1; // scope 2 at $DIR/issue_75439.rs:+2:47: +2:52 + _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue_75439.rs:+2:37: +2:53 // mir::Constant - // + span: $DIR/issue-75439.rs:7:37: 7:46 + // + span: $DIR/issue_75439.rs:7:37: 7:46 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn([u8; 16]) -> [u32; 4] {transmute::<[u8; 16], [u32; 4]>}, val: Value() } } bb1: { - StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:+2:52: +2:53 - switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + StorageDead(_3); // scope 2 at $DIR/issue_75439.rs:+2:52: +2:53 + switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb2: { - switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb3: { - switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb4: { - StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:+5:14: +5:38 - StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35 - _6 = _4; // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35 - _5 = transmute::(move _6) -> bb7; // scope 4 at $DIR/issue-75439.rs:+5:23: +5:36 + StorageLive(_5); // scope 3 at $DIR/issue_75439.rs:+5:14: +5:38 + StorageLive(_6); // scope 4 at $DIR/issue_75439.rs:+5:33: +5:35 + _6 = _4; // scope 4 at $DIR/issue_75439.rs:+5:33: +5:35 + _5 = transmute::(move _6) -> bb7; // scope 4 at $DIR/issue_75439.rs:+5:23: +5:36 // mir::Constant - // + span: $DIR/issue-75439.rs:10:23: 10:32 + // + span: $DIR/issue_75439.rs:10:23: 10:32 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32) -> [u8; 4] {transmute::}, val: Value() } } bb5: { - StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 - _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 - goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + StorageLive(_4); // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 + _4 = _2[3 of 4]; // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 + goto -> bb4; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb6: { - StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 - _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 - goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + StorageLive(_4); // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 + _4 = _2[3 of 4]; // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29 + goto -> bb4; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb7: { - StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:+5:35: +5:36 - Deinit(_0); // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 - ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 - discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 - StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:+5:38: +5:39 - StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:+6:5: +6:6 - goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6 + StorageDead(_6); // scope 4 at $DIR/issue_75439.rs:+5:35: +5:36 + Deinit(_0); // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39 + ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39 + discriminant(_0) = 1; // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39 + StorageDead(_5); // scope 3 at $DIR/issue_75439.rs:+5:38: +5:39 + StorageDead(_4); // scope 1 at $DIR/issue_75439.rs:+6:5: +6:6 + goto -> bb9; // scope 1 at $DIR/issue_75439.rs:+4:5: +8:6 } bb8: { - Deinit(_0); // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13 - discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13 - goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6 + Deinit(_0); // scope 1 at $DIR/issue_75439.rs:+7:9: +7:13 + discriminant(_0) = 0; // scope 1 at $DIR/issue_75439.rs:+7:9: +7:13 + goto -> bb9; // scope 1 at $DIR/issue_75439.rs:+4:5: +8:6 } bb9: { - StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:+9:1: +9:2 - return; // scope 0 at $DIR/issue-75439.rs:+9:2: +9:2 + StorageDead(_2); // scope 0 at $DIR/issue_75439.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue_75439.rs:+9:2: +9:2 } } diff --git a/src/test/mir-opt/issues/issue-75439.rs b/src/test/mir-opt/issues/issue_75439.rs similarity index 100% rename from src/test/mir-opt/issues/issue-75439.rs rename to src/test/mir-opt/issues/issue_75439.rs diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff index 25ab0c9f7f4c0..d3db3b182717d 100644 --- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -2,271 +2,271 @@ + // MIR for `complicated_match` after ElaborateDrops fn complicated_match(_1: bool, _2: (bool, bool, String)) -> i32 { - debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:+0:22: +0:26 - debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:+0:34: +0:39 - let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:+0:66: +0:69 - let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 - let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 - let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 - let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 - let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 - let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 - let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60 - let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 - let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 - let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60 - let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 - let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 + debug cond => _1; // in scope 0 at $DIR/match_arm_scopes.rs:+0:22: +0:26 + debug items => _2; // in scope 0 at $DIR/match_arm_scopes.rs:+0:34: +0:39 + let mut _0: i32; // return place in scope 0 at $DIR/match_arm_scopes.rs:+0:66: +0:69 + let mut _3: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + let mut _4: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + let _5: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + let _6: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + let _7: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + let _8: &std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + let mut _9: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + let mut _10: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + let mut _11: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60 + let mut _12: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + let mut _13: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + let mut _14: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60 + let _15: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + let _16: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 scope 1 { - debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21 - debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + debug a => _5; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + debug a => _6; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + debug s => _7; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + debug s => _8; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21 } scope 2 { - debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:+3:16: +3:17 - debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:+3:19: +3:20 + debug b => _15; // in scope 2 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + debug t => _16; // in scope 2 at $DIR/match_arm_scopes.rs:+3:19: +3:20 } bb0: { -- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 -- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 -+ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 +- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb1: { -- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:9: +2:22 -+ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 +- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:9: +2:22 ++ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb2: { -- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 -+ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 +- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb3: { -- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:25: +2:38 +- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:25: +2:38 - } - - bb4: { -- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 +- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 - } - - bb5: { -- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+3:9: +3:21 +- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+3:9: +3:21 - } - - bb6: { - StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33 - _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33 - StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36 - _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36 -- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 -+ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33 + _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33 + StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36 +- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 } - bb7: { + bb4: { - _0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -+ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + _0 = const 1_i32; // scope 1 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 ++ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 } - bb8: { + bb5: { - StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - _6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 - _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 -- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 -- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 - StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 - StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 - _10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 -- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 -+ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + _6 = &(_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + StorageLive(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + StorageLive(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + _10 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 } - bb9: { + bb6: { - _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60 - StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60 + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 - goto -> bb23; // scope 0 at no-location + goto -> bb20; // scope 0 at no-location } - bb10: { + bb7: { - _9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71 -- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 -+ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + _9 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 +- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb11: { + bb8: { - StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - _5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 - StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 - _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 -- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 -+ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + _5 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18 + StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21 +- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 } - bb12: { + bb9: { - StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 -+ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ goto -> bb1; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb13: { + bb10: { - StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 - _6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 - StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 - _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 -- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 -- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 - StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 - StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 - _13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 -- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 -+ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + _6 = &(_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 + StorageLive(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 + StorageLive(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 + _13 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 } - bb14: { + bb11: { - _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60 - StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60 + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 - goto -> bb23; // scope 0 at no-location + goto -> bb20; // scope 0 at no-location } - bb15: { + bb12: { - _12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71 -- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 -+ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + _12 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 +- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb16: { + bb13: { - StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 -- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 - _5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 - StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 - _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 -- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 -+ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + _5 = (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27 + StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37 +- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 } - bb17: { + bb14: { - StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 - StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 -+ goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ goto -> bb2; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb18: { + bb15: { - StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -+ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 ++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 } - bb19: { + bb16: { - _0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:+3:41: +3:42 -- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 -+ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 + _0 = const 2_i32; // scope 2 at $DIR/match_arm_scopes.rs:+3:41: +3:42 +- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 ++ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 } - bb20: { + bb17: { - StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 - _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 - StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 - _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 -- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 -+ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17 + StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20 +- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6 } - bb21: { + bb18: { - StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 - StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 -- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 -+ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 + StorageDead(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 + StorageDead(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 +- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 ++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42 } - bb22: { -- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + bb19: { -+ goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb26; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 } - bb23: { + bb20: { - StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 - StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 -- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 -+ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 + StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78 +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 ++ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 } - bb24: { + bb21: { - return; // scope 0 at $DIR/match-arm-scopes.rs:+5:2: +5:2 + return; // scope 0 at $DIR/match_arm_scopes.rs:+5:2: +5:2 } - bb25 (cleanup): { -- drop(_2) -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 +- drop(_2) -> bb26; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + bb22 (cleanup): { -+ goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb27; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 } - bb26 (cleanup): { + bb23 (cleanup): { - resume; // scope 0 at $DIR/match-arm-scopes.rs:+0:1: +5:2 + resume; // scope 0 at $DIR/match_arm_scopes.rs:+0:1: +5:2 + } + + bb24: { -+ goto -> bb21; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb21; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + + bb25 (cleanup): { -+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + + bb26: { -+ goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb24; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 + } + + bb27 (cleanup): { -+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2 } } diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match_arm_scopes.rs similarity index 100% rename from src/test/mir-opt/match-arm-scopes.rs rename to src/test/mir-opt/match_arm_scopes.rs diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named_lifetimes_basic.rs similarity index 100% rename from src/test/mir-opt/nll/named-lifetimes-basic.rs rename to src/test/mir-opt/nll/named_lifetimes_basic.rs diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index 0ab9d712d9f69..6cd6d8b77959e 100644 --- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -24,24 +24,24 @@ | '_#2r live at {bb0[0..=1]} | '_#3r live at {bb0[0..=1]} | '_#4r live at {bb0[0..=1]} -| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) -| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) -| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) -| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) -| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) -| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) -| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) -| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) +| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) +| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) +| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) +| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) +| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) +| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) +| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) | fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool { - debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27 - debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43 - debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55 - debug z => _4; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:66: +0:67 - let mut _0: bool; // return place in scope 0 at $DIR/named-lifetimes-basic.rs:+0:81: +0:85 + debug w => _1; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:26: +0:27 + debug x => _2; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:42: +0:43 + debug y => _3; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:54: +0:55 + debug z => _4; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:66: +0:67 + let mut _0: bool; // return place in scope 0 at $DIR/named_lifetimes_basic.rs:+0:81: +0:85 bb0: { - _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:88: +0:92 - return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:94: +0:94 + _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named_lifetimes_basic.rs:+0:88: +0:92 + return; // bb0[1]: scope 0 at $DIR/named_lifetimes_basic.rs:+0:94: +0:94 } } diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 36705d18e0161..3e3fda6141aec 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -17,95 +17,95 @@ | '_#2r live at {bb1[0]} | '_#3r live at {bb1[1..=3]} | '_#4r live at {bb1[4..=7], bb2[0..=2]} -| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) -| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 - let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x00000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 - let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 + let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x00000003)) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + let mut _7: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + let _8: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 + let mut _9: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 scope 1 { - debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 scope 2 { - debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 scope 3 { - debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26 - FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + StorageLive(_1); // bb0[0]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region_subtyping_basic.rs:+1:17: +1:26 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + StorageLive(_2); // bb0[3]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + StorageLive(_3); // bb0[4]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 } bb1: { - _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 - FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 - _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 - FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 - StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 } bb2: { - StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 - StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + StorageLive(_8); // bb2[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 + StorageLive(_9); // bb2[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + _9 = (*_6); // bb2[2]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 // mir::Constant - // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14 + // + span: $DIR/region_subtyping_basic.rs:21:9: 21:14 // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value() } } bb3: { - StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18 - StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19 - _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6 - goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + StorageDead(_9); // bb3[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:17: +5:18 + StorageDead(_8); // bb3[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:18: +5:19 + _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:13: +6:6 + goto -> bb6; // bb3[3]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6 } bb4: { - StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 - _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + StorageLive(_10); // bb4[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 // mir::Constant - // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14 + // + span: $DIR/region_subtyping_basic.rs:23:9: 23:14 // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value() } } bb5: { - StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19 - _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6 - goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + StorageDead(_10); // bb5[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:18: +7:19 + _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region_subtyping_basic.rs:+6:12: +8:6 + goto -> bb6; // bb5[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6 } bb6: { - StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6 - StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2 + StorageDead(_7); // bb6[0]: scope 3 at $DIR/region_subtyping_basic.rs:+8:5: +8:6 + StorageDead(_6); // bb6[1]: scope 2 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_3); // bb6[2]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_2); // bb6[3]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_1); // bb6[4]: scope 0 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + return; // bb6[5]: scope 0 at $DIR/region_subtyping_basic.rs:+9:2: +9:2 } bb7 (cleanup): { - resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2 + resume; // bb7[0]: scope 0 at $DIR/region_subtyping_basic.rs:+0:1: +9:2 } } diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 4f6256a67f46f..39a53702a4cbb 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -17,95 +17,95 @@ | '_#2r live at {bb1[0]} | '_#3r live at {bb1[1..=3]} | '_#4r live at {bb1[4..=7], bb2[0..=2]} -| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) -| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) | fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 - let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 - let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 + let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x0000000000000003)) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + let mut _7: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + let _8: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 + let mut _9: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 scope 1 { - debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 scope 2 { - debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 scope 3 { - debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26 - FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 - StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 - _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 - assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + StorageLive(_1); // bb0[0]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region_subtyping_basic.rs:+1:17: +1:26 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + StorageLive(_2); // bb0[3]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + StorageLive(_3); // bb0[4]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 + _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 } bb1: { - _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 - FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 - StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 - _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 - FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 - StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 - switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 } bb2: { - StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 - StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 - _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + StorageLive(_8); // bb2[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 + StorageLive(_9); // bb2[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + _9 = (*_6); // bb2[2]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17 + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18 // mir::Constant - // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14 + // + span: $DIR/region_subtyping_basic.rs:21:9: 21:14 // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value() } } bb3: { - StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18 - StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19 - _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6 - goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + StorageDead(_9); // bb3[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:17: +5:18 + StorageDead(_8); // bb3[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:18: +5:19 + _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:13: +6:6 + goto -> bb6; // bb3[3]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6 } bb4: { - StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 - _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + StorageLive(_10); // bb4[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 // mir::Constant - // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14 + // + span: $DIR/region_subtyping_basic.rs:23:9: 23:14 // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value() } } bb5: { - StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19 - _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6 - goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + StorageDead(_10); // bb5[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:18: +7:19 + _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region_subtyping_basic.rs:+6:12: +8:6 + goto -> bb6; // bb5[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6 } bb6: { - StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6 - StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 - return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2 + StorageDead(_7); // bb6[0]: scope 3 at $DIR/region_subtyping_basic.rs:+8:5: +8:6 + StorageDead(_6); // bb6[1]: scope 2 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_3); // bb6[2]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_2); // bb6[3]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + StorageDead(_1); // bb6[4]: scope 0 at $DIR/region_subtyping_basic.rs:+9:1: +9:2 + return; // bb6[5]: scope 0 at $DIR/region_subtyping_basic.rs:+9:2: +9:2 } bb7 (cleanup): { - resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2 + resume; // bb7[0]: scope 0 at $DIR/region_subtyping_basic.rs:+0:1: +9:2 } } diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region_subtyping_basic.rs similarity index 100% rename from src/test/mir-opt/nll/region-subtyping-basic.rs rename to src/test/mir-opt/nll/region_subtyping_basic.rs diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no_drop_for_inactive_variant.rs similarity index 100% rename from src/test/mir-opt/no-drop-for-inactive-variant.rs rename to src/test/mir-opt/no_drop_for_inactive_variant.rs diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir index 50fd98ff13a62..e708255cea430 100644 --- a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir @@ -1,21 +1,21 @@ // MIR for `unwrap` after SimplifyCfg-elaborate-drops fn unwrap(_1: Option) -> T { - debug opt => _1; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:14: +0:17 - let mut _0: T; // return place in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:33: +0:34 - let mut _2: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:9: +2:16 - let _3: T; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + debug opt => _1; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:14: +0:17 + let mut _0: T; // return place in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:33: +0:34 + let mut _2: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:9: +2:16 + let _3: T; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL - let mut _5: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 - let mut _6: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 - let mut _7: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + let mut _5: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + let mut _6: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + let mut _7: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 scope 1 { - debug x => _3; // in scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + debug x => _3; // in scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 } bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14 - switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:5: +1:14 + _2 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14 + switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:5: +1:14 } bb1: { @@ -30,20 +30,20 @@ fn unwrap(_1: Option) -> T { } bb2: { - unreachable; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14 + unreachable; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14 } bb3: { - StorageLive(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 - _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 - _0 = move _3; // scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21 - StorageDead(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21 - _5 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 - return; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:2: +5:2 + StorageLive(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15 + _0 = move _3; // scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21 + StorageDead(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21 + _5 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + return; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:2: +5:2 } bb4 (cleanup): { - _7 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 - resume; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:1: +5:2 + _7 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2 + resume; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:1: +5:2 } } diff --git a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir index 963e7cde6567b..0cb34a2f27476 100644 --- a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir @@ -1,49 +1,49 @@ // MIR for `main` before ElaborateDrops fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 - let mut _2: std::string::String; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 - let mut _3: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 - let _4: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 + let mut _0: (); // return place in scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 + let mut _2: std::string::String; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + let mut _3: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + let _4: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 bb0: { - StorageLive(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 - StorageLive(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 - StorageLive(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 - StorageLive(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 - _4 = const ""; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 + StorageLive(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 + StorageLive(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + StorageLive(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + StorageLive(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 + _4 = const ""; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22 // mir::Constant - // + span: $DIR/no-spurious-drop-after-call.rs:9:20: 9:22 + // + span: $DIR/no_spurious_drop_after_call.rs:9:20: 9:22 // + literal: Const { ty: &str, val: Value(Slice(..)) } - _3 = &(*_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 - _2 = ::to_string(move _3) -> bb1; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + _3 = &(*_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 + _2 = ::to_string(move _3) -> bb1; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34 // mir::Constant - // + span: $DIR/no-spurious-drop-after-call.rs:9:23: 9:32 + // + span: $DIR/no_spurious_drop_after_call.rs:9:23: 9:32 // + literal: Const { ty: for<'a> fn(&'a str) -> String {::to_string}, val: Value() } } bb1: { - StorageDead(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:33: +1:34 - _1 = std::mem::drop::(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 + StorageDead(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:33: +1:34 + _1 = std::mem::drop::(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35 // mir::Constant - // + span: $DIR/no-spurious-drop-after-call.rs:9:5: 9:19 + // + span: $DIR/no_spurious_drop_after_call.rs:9:5: 9:19 // + literal: Const { ty: fn(String) {std::mem::drop::}, val: Value() } } bb2: { - StorageDead(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35 - StorageDead(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36 - StorageDead(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36 - _0 = const (); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +2:2 - return; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+2:2: +2:2 + StorageDead(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35 + StorageDead(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36 + StorageDead(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36 + _0 = const (); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +2:2 + return; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+2:2: +2:2 } bb3 (cleanup): { - drop(_2) -> bb4; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35 + drop(_2) -> bb4; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35 } bb4 (cleanup): { - resume; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:1: +2:2 + resume; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:1: +2:2 } } diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no_spurious_drop_after_call.rs similarity index 100% rename from src/test/mir-opt/no-spurious-drop-after-call.rs rename to src/test/mir-opt/no_spurious_drop_after_call.rs diff --git a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff index ce35f920bf627..61a16065bfbdc 100644 --- a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff +++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff @@ -2,42 +2,42 @@ + // MIR for `nrvo` after RenameReturnPlace fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { - debug init => _1; // in scope 0 at $DIR/nrvo-simple.rs:+0:9: +0:13 -- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+0:39: +0:49 -+ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 - let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 - let _3: (); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:19 - let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:9 - let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18 - let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18 + debug init => _1; // in scope 0 at $DIR/nrvo_simple.rs:+0:9: +0:13 +- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+0:39: +0:49 ++ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 + let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 + let _3: (); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:19 + let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:9 + let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18 + let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18 scope 1 { -- debug buf => _2; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16 -+ debug buf => _0; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16 +- debug buf => _2; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16 ++ debug buf => _0; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16 } bb0: { -- StorageLive(_2); // scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 -- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28 -+ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28 - StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19 - StorageLive(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9 - _4 = _1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9 - StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 - StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 -- _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 -+ _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 - _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 - _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19 +- StorageLive(_2); // scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16 +- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28 ++ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28 + StorageLive(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19 + StorageLive(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9 + _4 = _1; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9 + StorageLive(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + StorageLive(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 +- _6 = &mut _2; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 ++ _6 = &mut _0; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + _5 = &mut (*_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18 + _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19 } bb1: { - StorageDead(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19 - StorageDead(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19 - StorageDead(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20 - StorageDead(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20 -- _0 = _2; // scope 1 at $DIR/nrvo-simple.rs:+3:5: +3:8 -- StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:+4:1: +4:2 - return; // scope 0 at $DIR/nrvo-simple.rs:+4:2: +4:2 + StorageDead(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19 + StorageDead(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19 + StorageDead(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20 + StorageDead(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20 +- _0 = _2; // scope 1 at $DIR/nrvo_simple.rs:+3:5: +3:8 +- StorageDead(_2); // scope 0 at $DIR/nrvo_simple.rs:+4:1: +4:2 + return; // scope 0 at $DIR/nrvo_simple.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo_simple.rs similarity index 100% rename from src/test/mir-opt/nrvo-simple.rs rename to src/test/mir-opt/nrvo_simple.rs diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir index f9ed1036f0060..e522534867d50 100644 --- a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir @@ -1,60 +1,60 @@ // MIR for `main` after SimplifyCfg-elaborate-drops fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11 - let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 - let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 - let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 - let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 - let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 - let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + let mut _0: (); // return place in scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +0:11 + let mut _1: Packed; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 + let mut _2: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + let mut _3: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + let mut _4: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + let mut _5: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + let mut _6: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 scope 1 { - debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + debug x => _1; // in scope 1 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 } bb0: { - StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 - StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 - StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 - Deinit(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 - (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 - Deinit(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 - (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 - StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42 - Deinit(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43 - (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43 - StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43 - StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 - StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 - Deinit(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 - (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 - Deinit(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 - (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 - StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 - StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 - _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 - drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + StorageLive(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + StorageLive(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + Deinit(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + Deinit(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + StorageDead(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:41: +1:42 + Deinit(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43 + (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43 + StorageDead(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:42: +1:43 + StorageLive(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + StorageLive(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + Deinit(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + Deinit(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + StorageDead(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 + StorageLive(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 } bb1: { - StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 - return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2 + StorageDead(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + return; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:2: +3:2 } bb2 (cleanup): { - resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2 + resume; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:1: +3:2 } bb3 (cleanup): { - (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 - drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + drop(_1) -> bb2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 } bb4: { - StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 - (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 - StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 - _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2 - drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + StorageDead(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + StorageDead(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 + _0 = const (); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +3:2 + drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 } } diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed_struct_drop_aligned.rs similarity index 100% rename from src/test/mir-opt/packed-struct-drop-aligned.rs rename to src/test/mir-opt/packed_struct_drop_aligned.rs diff --git a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir index 76bdd23be1684..8eb0e9c8f483f 100644 --- a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir +++ b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir @@ -1,11 +1,11 @@ // MIR for `no_codegen` after PreCodegen fn no_codegen() -> () { - let mut _0: (); // return place in scope 0 at $DIR/remove-never-const.rs:+0:20: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/remove_never_const.rs:+0:20: +0:20 scope 1 { } bb0: { - unreachable; // scope 0 at $DIR/remove-never-const.rs:+1:13: +1:33 + unreachable; // scope 0 at $DIR/remove_never_const.rs:+1:13: +1:33 } } diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove_never_const.rs similarity index 100% rename from src/test/mir-opt/remove-never-const.rs rename to src/test/mir-opt/remove_never_const.rs diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify_arm.rs similarity index 100% rename from src/test/mir-opt/simplify-arm.rs rename to src/test/mir-opt/simplify_arm.rs diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify_arm_identity.rs similarity index 100% rename from src/test/mir-opt/simplify-arm-identity.rs rename to src/test/mir-opt/simplify_arm_identity.rs diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff index 5d7517e4eb43c..1a5143aa0fa03 100644 --- a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff @@ -2,32 +2,32 @@ + // MIR for `c` after SimplifyLocals fn c() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8 - let _1: [u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 -- let mut _2: &[u8]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 -- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 -- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 + let _1: [u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 +- let mut _2: &[u8]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 +- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 +- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 scope 1 { - debug bytes => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14 + debug bytes => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 scope 2 { } } bb0: { - StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 - _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:26 -- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- _4 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- _3 = &(*_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 -- StorageDead(_3); // scope 1 at $DIR/simplify-locals.rs:+3:25: +3:26 -- StorageDead(_4); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27 -- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +4:2 - StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+4:1: +4:2 - return; // scope 0 at $DIR/simplify-locals.rs:+4:2: +4:2 + StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 + _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:26 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageLive(_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _4 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _3 = &(*_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageDead(_3); // scope 1 at $DIR/simplify_locals.rs:+3:25: +3:26 +- StorageDead(_4); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 +- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +4:2 + StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+4:1: +4:2 + return; // scope 0 at $DIR/simplify_locals.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff index a9ea8869a9698..6426bf926a43d 100644 --- a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff @@ -2,18 +2,18 @@ + // MIR for `d1` after SimplifyLocals fn d1() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 -- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 scope 1 { } bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 -- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 -- discriminant(_1) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- discriminant(_1) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff index 6a89e45843b9b..db5ab182d6f30 100644 --- a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff @@ -2,28 +2,28 @@ + // MIR for `d2` after SimplifyLocals fn d2() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 -- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 -- let mut _2: (i32, E); // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 -- let mut _3: E; // in scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- let mut _2: (i32, E); // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- let mut _3: E; // in scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 -- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 -- discriminant(_1) = 1; // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 -- StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 -- StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 -- Deinit(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 -- discriminant(_3) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 -- Deinit(_2); // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 -- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 -- (_2.1: E) = move _3; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 -- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16 -- (_2.1: E) = move _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:26 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:25: +2:26 -- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:26: +2:27 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- discriminant(_1) = 1; // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- Deinit(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- discriminant(_3) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- Deinit(_2); // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- (_2.1: E) = move _3; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 +- (_2.1: E) = move _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:26 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:25: +2:26 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:26: +2:27 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff index 204a1bffc81ab..c707b0da07e06 100644 --- a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff @@ -2,20 +2,20 @@ + // MIR for `expose_addr` after SimplifyLocals fn expose_addr(_1: *const usize) -> () { - debug p => _1; // in scope 0 at $DIR/simplify-locals.rs:+0:16: +0:17 - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:33: +0:33 - let _2: usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 - let mut _3: *const usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 + debug p => _1; // in scope 0 at $DIR/simplify_locals.rs:+0:16: +0:17 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:33: +0:33 + let _2: usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + let mut _3: *const usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 - StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 - _3 = _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 - _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 - StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 - StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:33: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 + _3 = _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:33: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff index 329e2a65a0d0f..ff6eb2cff5e94 100644 --- a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff @@ -2,12 +2,12 @@ + // MIR for `r` after SimplifyLocals fn r() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8 - let mut _1: i32; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 -- let mut _2: &i32; // in scope 0 at $DIR/simplify-locals.rs:+3:13: +3:15 -- let mut _3: &mut i32; // in scope 0 at $DIR/simplify-locals.rs:+4:13: +4:19 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 + let mut _1: i32; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 +- let mut _2: &i32; // in scope 0 at $DIR/simplify_locals.rs:+3:13: +3:15 +- let mut _3: &mut i32; // in scope 0 at $DIR/simplify_locals.rs:+4:13: +4:19 scope 1 { - debug a => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14 + debug a => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 scope 2 { scope 3 { } @@ -15,17 +15,17 @@ } bb0: { - StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 - _1 = const 1_i32; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:18 -- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15 -- _2 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15 -- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:15: +3:16 -- StorageLive(_3); // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19 -- _3 = &mut _1; // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19 -- StorageDead(_3); // scope 2 at $DIR/simplify-locals.rs:+4:19: +4:20 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +5:2 - StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+5:1: +5:2 - return; // scope 0 at $DIR/simplify-locals.rs:+5:2: +5:2 + StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 + _1 = const 1_i32; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:18 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 +- _2 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 +- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:15: +3:16 +- StorageLive(_3); // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 +- _3 = &mut _1; // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 +- StorageDead(_3); // scope 2 at $DIR/simplify_locals.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +5:2 + StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_locals.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/simplify-locals.rs b/src/test/mir-opt/simplify_locals.rs similarity index 100% rename from src/test/mir-opt/simplify-locals.rs rename to src/test/mir-opt/simplify_locals.rs diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff index b31156ad6977e..49db77479638d 100644 --- a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff @@ -2,21 +2,21 @@ + // MIR for `t1` after SimplifyLocals fn t1() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 -- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 -- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 scope 1 { } bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 -- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 -- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 -- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 -- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff index 66b6d8d648647..e3f4ae3701b04 100644 --- a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff @@ -2,21 +2,21 @@ + // MIR for `t2` after SimplifyLocals fn t2() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 -- let _1: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:20 -- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:19: +2:20 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:20 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:19: +2:20 scope 1 { } bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:22 -- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20 -- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20 -- _1 = &mut (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:20 -- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:22 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 +- _1 = &mut (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:20 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff index f6b6b78cdfbeb..f1ce7778e1915 100644 --- a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff @@ -2,25 +2,25 @@ + // MIR for `t3` after SimplifyLocals fn t3() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 -- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:21 -- let mut _2: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:15: +2:21 -- let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:20: +2:21 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:21 +- let mut _2: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:15: +2:21 +- let mut _3: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:20: +2:21 scope 1 { } bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:23 -- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21 -- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21 -- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21 -- _2 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21 -- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:21 -- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 -- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 - _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:23 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 +- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 +- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 +- _2 = &mut (*_3); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 +- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:21 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff index 1c1da29aa678f..71cf9594b9eb2 100644 --- a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff @@ -2,21 +2,21 @@ + // MIR for `t4` after SimplifyLocals fn t4() -> u32 { - let mut _0: u32; // return place in scope 0 at $DIR/simplify-locals.rs:+0:12: +0:15 - let mut _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 - let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + let mut _0: u32; // return place in scope 0 at $DIR/simplify_locals.rs:+0:12: +0:15 + let mut _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 scope 1 { } bb0: { - StorageLive(_1); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 - StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 - _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 - _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 - _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:19 - StorageDead(_1); // scope 1 at $DIR/simplify-locals.rs:+2:18: +2:19 - StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+3:1: +3:2 - return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + StorageLive(_1); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:19 + StorageDead(_1); // scope 1 at $DIR/simplify_locals.rs:+2:18: +2:19 + StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+3:1: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 } } diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff index ac7a47ba58f7b..8feddcef2ceef 100644 --- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff @@ -2,61 +2,61 @@ + // MIR for `foo` after SimplifyLocals fn foo() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+0:13: +0:13 - let mut _1: (std::option::Option, std::option::Option); // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 - let mut _2: std::option::Option; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 - let mut _3: std::option::Option; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 - let mut _4: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:22: +1:26 - let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:13: +1:20 -- let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 -- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+0:13: +0:13 + let mut _1: (std::option::Option, std::option::Option); // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + let mut _2: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + let mut _3: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + let mut _4: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:22: +1:26 + let mut _5: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:13: +1:20 +- let mut _7: bool; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- let mut _8: u8; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 scope 1 { - debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 - let _6: u8; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 + debug a => _6; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + let _6: u8; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 } bb0: { - StorageLive(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 - StorageLive(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 - Deinit(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 - discriminant(_2) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 - StorageLive(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 - Deinit(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 - discriminant(_3) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 - Deinit(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 - (_1.0: std::option::Option) = move _2; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 - (_1.1: std::option::Option) = move _3; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 - StorageDead(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69 - StorageDead(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69 - _5 = discriminant((_1.0: std::option::Option)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 - switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + StorageLive(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageLive(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + Deinit(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + discriminant(_2) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + StorageLive(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + Deinit(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + discriminant(_3) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + Deinit(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + (_1.0: std::option::Option) = move _2; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + (_1.1: std::option::Option) = move _3; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + _5 = discriminant((_1.0: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 } bb1: { - _4 = discriminant((_1.1: std::option::Option)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 - switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + _4 = discriminant((_1.1: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 } bb2: { - StorageLive(_6); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 - _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 -- StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 -- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 -- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 -- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 -- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:19: +2:20 -- StorageDead(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+4:9: +4:10 - StorageDead(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+5:5: +5:6 - goto -> bb3; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:5: +5:6 + StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 +- StorageLive(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- StorageLive(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 +- _8 = _6; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 +- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- StorageDead(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:19: +2:20 +- StorageDead(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+4:9: +4:10 + StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6 + goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6 } bb3: { - drop(_1) -> bb4; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2 + drop(_1) -> bb4; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 } bb4: { - StorageDead(_1); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:2: +6:2 + StorageDead(_1); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:2: +6:2 } } diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify_locals_fixedpoint.rs similarity index 100% rename from src/test/mir-opt/simplify-locals-fixedpoint.rs rename to src/test/mir-opt/simplify_locals_fixedpoint.rs diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff index b41527ba02de5..78272272b0704 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff @@ -2,108 +2,108 @@ + // MIR for `main` after SimplifyLocals fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +0:11 -- let mut _1: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 -- let mut _2: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23 -- let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27 -- let _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 -- let mut _5: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -- let mut _6: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -- let mut _7: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -- let _8: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 -- let mut _9: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -- let mut _10: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -- let mut _11: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -+ let _1: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 -+ let mut _2: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -+ let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -+ let mut _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -+ let _5: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 -+ let mut _6: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -+ let mut _7: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -+ let mut _8: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +0:11 +- let mut _1: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- let mut _2: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- let _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- let mut _5: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- let mut _6: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- let mut _7: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- let _8: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- let mut _9: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- let mut _10: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- let mut _11: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ let _1: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 scope 1 { } bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 -- StorageLive(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23 -- Deinit(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23 -- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27 -- Deinit(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27 -- Deinit(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 -- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 -- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 -- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28 -- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28 -- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:28: +1:29 -- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 -- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -- Deinit(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -- StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -- Deinit(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -- Deinit(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 -- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 -- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 -+ StorageLive(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 -+ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -+ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -+ Deinit(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 -+ StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -+ Deinit(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 -+ Deinit(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -+ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -+ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 -+ StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 -+ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 -+ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 +- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- Deinit(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29 +- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- Deinit(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 // mir::Constant - // + span: $DIR/simplify-locals-removes-unused-consts.rs:15:5: 15:12 + // + span: $DIR/simplify_locals_removes_unused_consts.rs:15:5: 15:12 // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value() } } bb1: { -- StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22 -- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23 -- StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 -- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -- Deinit(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -- _10 = (_11.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34 -- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 -+ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22 -+ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23 -+ StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 -+ StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -+ StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -+ StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -+ Deinit(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -+ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 -+ _7 = (_8.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 -+ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 -+ StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34 -+ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 +- StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 +- StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 +- StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- StorageLive(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageLive(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- StorageLive(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 +- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 ++ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 ++ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 ++ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 // mir::Constant - // + span: $DIR/simplify-locals-removes-unused-consts.rs:17:5: 17:11 + // + span: $DIR/simplify_locals_removes_unused_consts.rs:17:5: 17:11 // + literal: Const { ty: fn(u8) {use_u8}, val: Value() } } bb2: { -- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35 -- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 -+ StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35 - StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 -+ StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 - _0 = const (); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +5:2 - return; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+5:2: +5:2 +- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 +- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 + StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 + _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify_locals_removes_unused_consts.rs similarity index 100% rename from src/test/mir-opt/simplify-locals-removes-unused-consts.rs rename to src/test/mir-opt/simplify_locals_removes_unused_consts.rs diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff index 51d26b08b2a1c..6e7294003afae 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff @@ -2,51 +2,51 @@ + // MIR for `map` after SimplifyLocals fn map(_1: Option>) -> Option> { - debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9 - let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46 - let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13 - let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 - let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26 -- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 -- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 -- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 + debug x => _1; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:8: +0:9 + let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:31: +0:46 + let mut _2: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:9: +2:13 + let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 +- let mut _5: bool; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 +- let mut _6: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 +- let mut _7: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 scope 1 { - debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 + debug x => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 } bb0: { -- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 -- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 - _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12 +- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 +- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 } bb1: { - StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 - _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 - StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26 - _4 = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26 - Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 - ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 - discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 - StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27 - StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27 - goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27 + StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 } bb2: { - unreachable; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 + unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 } bb3: { - Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 - discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 - goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + Deinit(_0); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 } bb4: { -- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 - return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2 +- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs similarity index 100% rename from src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs rename to src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice_drop_shim.rs similarity index 100% rename from src/test/mir-opt/slice-drop-shim.rs rename to src/test/mir-opt/slice_drop_shim.rs diff --git a/src/test/mir-opt/spanview_block.main.built.after.html b/src/test/mir-opt/spanview_block.main.built.after.html index fbf751d6d30b4..b962d80c59e52 100644 --- a/src/test/mir-opt/spanview_block.main.built.after.html +++ b/src/test/mir-opt/spanview_block.main.built.after.html @@ -59,7 +59,7 @@ -
fn main() fn main() 0⦊{}⦉0
diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview_block.rs similarity index 100% rename from src/test/mir-opt/spanview-block.rs rename to src/test/mir-opt/spanview_block.rs diff --git a/src/test/mir-opt/spanview_statement.main.built.after.html b/src/test/mir-opt/spanview_statement.main.built.after.html index 02b2720feefc9..43bff7d096e21 100644 --- a/src/test/mir-opt/spanview_statement.main.built.after.html +++ b/src/test/mir-opt/spanview_statement.main.built.after.html @@ -59,8 +59,8 @@ -
fn main() 0[0]⦊{}⦉0[0]fn main() 0[0]⦊{}⦉0[0]0:Return⦊⦉0:Return
diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview_statement.rs similarity index 100% rename from src/test/mir-opt/spanview-statement.rs rename to src/test/mir-opt/spanview_statement.rs diff --git a/src/test/mir-opt/spanview_terminator.main.built.after.html b/src/test/mir-opt/spanview_terminator.main.built.after.html index a4cda7dd67ec6..aa7e44c157161 100644 --- a/src/test/mir-opt/spanview_terminator.main.built.after.html +++ b/src/test/mir-opt/spanview_terminator.main.built.after.html @@ -59,7 +59,7 @@ -
fn main() {}fn main() {}0:Return⦊⦉0:Return
diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview_terminator.rs similarity index 100% rename from src/test/mir-opt/spanview-terminator.rs rename to src/test/mir-opt/spanview_terminator.rs diff --git a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir index b6c36be2bbe4c..09453b8ba9c3a 100644 --- a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir +++ b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir @@ -1,28 +1,28 @@ // MIR for `main` after PreCodegen fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/tls-access.rs:+0:11: +0:11 - let _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:+2:18: +2:21 - let mut _3: *mut u8; // in scope 0 at $DIR/tls-access.rs:+3:9: +3:12 + let mut _0: (); // return place in scope 0 at $DIR/tls_access.rs:+0:11: +0:11 + let _2: *mut u8; // in scope 0 at $DIR/tls_access.rs:+2:18: +2:21 + let mut _3: *mut u8; // in scope 0 at $DIR/tls_access.rs:+3:9: +3:12 scope 1 { - let _1: &u8; // in scope 1 at $DIR/tls-access.rs:+2:13: +2:14 + let _1: &u8; // in scope 1 at $DIR/tls_access.rs:+2:13: +2:14 scope 2 { - debug a => _1; // in scope 2 at $DIR/tls-access.rs:+2:13: +2:14 + debug a => _1; // in scope 2 at $DIR/tls_access.rs:+2:13: +2:14 } } bb0: { - StorageLive(_1); // scope 1 at $DIR/tls-access.rs:+2:13: +2:14 - StorageLive(_2); // scope 1 at $DIR/tls-access.rs:+2:18: +2:21 - _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls-access.rs:+2:18: +2:21 - _1 = &(*_2); // scope 1 at $DIR/tls-access.rs:+2:17: +2:21 - StorageLive(_3); // scope 2 at $DIR/tls-access.rs:+3:9: +3:12 - _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:+3:9: +3:12 - (*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:+3:9: +3:17 - StorageDead(_3); // scope 2 at $DIR/tls-access.rs:+3:17: +3:18 - _0 = const (); // scope 1 at $DIR/tls-access.rs:+1:5: +4:6 - StorageDead(_2); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6 - StorageDead(_1); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6 - return; // scope 0 at $DIR/tls-access.rs:+5:2: +5:2 + StorageLive(_1); // scope 1 at $DIR/tls_access.rs:+2:13: +2:14 + StorageLive(_2); // scope 1 at $DIR/tls_access.rs:+2:18: +2:21 + _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls_access.rs:+2:18: +2:21 + _1 = &(*_2); // scope 1 at $DIR/tls_access.rs:+2:17: +2:21 + StorageLive(_3); // scope 2 at $DIR/tls_access.rs:+3:9: +3:12 + _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls_access.rs:+3:9: +3:12 + (*_3) = const 42_u8; // scope 2 at $DIR/tls_access.rs:+3:9: +3:17 + StorageDead(_3); // scope 2 at $DIR/tls_access.rs:+3:17: +3:18 + _0 = const (); // scope 1 at $DIR/tls_access.rs:+1:5: +4:6 + StorageDead(_2); // scope 1 at $DIR/tls_access.rs:+4:5: +4:6 + StorageDead(_1); // scope 1 at $DIR/tls_access.rs:+4:5: +4:6 + return; // scope 0 at $DIR/tls_access.rs:+5:2: +5:2 } } diff --git a/src/test/mir-opt/tls-access.rs b/src/test/mir-opt/tls_access.rs similarity index 100% rename from src/test/mir-opt/tls-access.rs rename to src/test/mir-opt/tls_access.rs diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir index 6ed53643f4bf0..2c0fcc6621a3e 100644 --- a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir @@ -1,16 +1,16 @@ // MIR for `process_never` after SimplifyLocals fn process_never(_1: *const !) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:22: +0:27 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:39: +0:39 - let _2: &!; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:22: +0:27 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:39: +0:39 + let _2: &!; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 } scope 2 { } bb0: { - unreachable; // scope 0 at $DIR/uninhabited-enum.rs:+0:39: +2:2 + unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2 } } diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir index bbb81724ccfd8..ae341a7b97b66 100644 --- a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir @@ -1,18 +1,18 @@ // MIR for `process_void` after SimplifyLocals fn process_void(_1: *const Void) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:21: +0:26 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:41: +0:41 - let _2: &Void; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41 + let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 } scope 2 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 - StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:+4:1: +4:2 - return; // scope 0 at $DIR/uninhabited-enum.rs:+4:2: +4:2 + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2 + return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited_enum.rs similarity index 100% rename from src/test/mir-opt/uninhabited-enum.rs rename to src/test/mir-opt/uninhabited_enum.rs diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir index c8b0f8e41b77c..5257491f0d494 100644 --- a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir +++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir @@ -1,10 +1,10 @@ // MIR for `E::V::{constant#0}` after built E::V::{constant#0}: isize = { - let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + let mut _0: isize; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10 bb0: { - _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 - return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + _0 = const 5_isize; // scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10 + return; // scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10 } } diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir index a46e60173774e..ee029676311bf 100644 --- a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir +++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir @@ -1,12 +1,12 @@ // MIR for `Test::X` after built fn Test::X(_1: usize) -> Test { - let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + let mut _0: Test; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6 bb0: { - Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 - ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 - discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 - return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + Deinit(_0); // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6 + ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6 + discriminant(_0) = 0; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6 + return; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6 } } diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual_item_types.rs similarity index 100% rename from src/test/mir-opt/unusual-item-types.rs rename to src/test/mir-opt/unusual_item_types.rs diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir index 7cb9050bc4bc6..90444b481221f 100644 --- a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir +++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir @@ -1,10 +1,10 @@ -// MIR for `::ASSOCIATED_CONSTANT` after built +// MIR for `::ASSOCIATED_CONSTANT` after built -const ::ASSOCIATED_CONSTANT: i32 = { - let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35 +const ::ASSOCIATED_CONSTANT: i32 = { + let mut _0: i32; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:32: +0:35 bb0: { - _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39 - return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:40 + _0 = const 2_i32; // scope 0 at $DIR/unusual_item_types.rs:+0:38: +0:39 + return; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:40 } } diff --git a/src/test/mir-opt/while-storage.rs b/src/test/mir-opt/while_storage.rs similarity index 100% rename from src/test/mir-opt/while-storage.rs rename to src/test/mir-opt/while_storage.rs diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir index a5e7d6afdf36d..68aa3e5db3298 100644 --- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -1,56 +1,56 @@ // MIR for `while_loop` after PreCodegen fn while_loop(_1: bool) -> () { - debug c => _1; // in scope 0 at $DIR/while-storage.rs:+0:15: +0:16 - let mut _0: (); // return place in scope 0 at $DIR/while-storage.rs:+0:24: +0:24 - let mut _2: bool; // in scope 0 at $DIR/while-storage.rs:+1:11: +1:22 - let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:+1:20: +1:21 - let mut _4: bool; // in scope 0 at $DIR/while-storage.rs:+2:12: +2:23 - let mut _5: bool; // in scope 0 at $DIR/while-storage.rs:+2:21: +2:22 + debug c => _1; // in scope 0 at $DIR/while_storage.rs:+0:15: +0:16 + let mut _0: (); // return place in scope 0 at $DIR/while_storage.rs:+0:24: +0:24 + let mut _2: bool; // in scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + let mut _3: bool; // in scope 0 at $DIR/while_storage.rs:+1:20: +1:21 + let mut _4: bool; // in scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + let mut _5: bool; // in scope 0 at $DIR/while_storage.rs:+2:21: +2:22 bb0: { - goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6 + goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6 } bb1: { - StorageLive(_2); // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 - StorageLive(_3); // scope 0 at $DIR/while-storage.rs:+1:20: +1:21 - _3 = _1; // scope 0 at $DIR/while-storage.rs:+1:20: +1:21 - _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + StorageLive(_2); // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + StorageLive(_3); // scope 0 at $DIR/while_storage.rs:+1:20: +1:21 + _3 = _1; // scope 0 at $DIR/while_storage.rs:+1:20: +1:21 + _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 // mir::Constant - // + span: $DIR/while-storage.rs:10:11: 10:19 + // + span: $DIR/while_storage.rs:10:11: 10:19 // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value() } } bb2: { - StorageDead(_3); // scope 0 at $DIR/while-storage.rs:+1:21: +1:22 - switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + StorageDead(_3); // scope 0 at $DIR/while_storage.rs:+1:21: +1:22 + switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 } bb3: { - StorageLive(_4); // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 - StorageLive(_5); // scope 0 at $DIR/while-storage.rs:+2:21: +2:22 - _5 = _1; // scope 0 at $DIR/while-storage.rs:+2:21: +2:22 - _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + StorageLive(_4); // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + StorageLive(_5); // scope 0 at $DIR/while_storage.rs:+2:21: +2:22 + _5 = _1; // scope 0 at $DIR/while_storage.rs:+2:21: +2:22 + _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 // mir::Constant - // + span: $DIR/while-storage.rs:11:12: 11:20 + // + span: $DIR/while_storage.rs:11:12: 11:20 // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value() } } bb4: { - StorageDead(_5); // scope 0 at $DIR/while-storage.rs:+2:22: +2:23 - switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + StorageDead(_5); // scope 0 at $DIR/while_storage.rs:+2:22: +2:23 + switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 } bb5: { - StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10 + StorageDead(_4); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10 goto -> bb8; // scope 0 at no-location } bb6: { - StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10 - StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6 - goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6 + StorageDead(_4); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10 + StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6 + goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6 } bb7: { @@ -58,7 +58,7 @@ fn while_loop(_1: bool) -> () { } bb8: { - StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6 - return; // scope 0 at $DIR/while-storage.rs:+6:2: +6:2 + StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6 + return; // scope 0 at $DIR/while_storage.rs:+6:2: +6:2 } } diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index ee883777c31d9..b0b11cafca5a8 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -31,6 +31,7 @@ fn main() { let args: Vec = env::args().skip(1).collect(); let verbose = args.iter().any(|s| *s == "--verbose"); + let bless = args.iter().any(|s| *s == "--bless"); let bad = std::sync::Arc::new(AtomicBool::new(false)); @@ -64,7 +65,7 @@ fn main() { // Checks over tests. check!(debug_artifacts, &src_path); check!(ui_tests, &src_path); - check!(mir_opt_tests, &src_path); + check!(mir_opt_tests, &src_path, bless); // Checks that only make sense for the compiler. check!(errors, &compiler_path); diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index f9e8b55497b58..ea24fa4513832 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -1,9 +1,9 @@ -//! Tidy check to ensure that mir opt directories do not have stale files. +//! Tidy check to ensure that mir opt directories do not have stale files or dashes in file names use std::collections::HashSet; use std::path::{Path, PathBuf}; -pub fn check(path: &Path, bad: &mut bool) { +fn check_unused_files(path: &Path, bad: &mut bool) { let mut rs_files = Vec::::new(); let mut output_files = HashSet::::new(); let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter(); @@ -35,3 +35,36 @@ pub fn check(path: &Path, bad: &mut bool) { } } } + +fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) { + for file in walkdir::WalkDir::new(&path.join("test/mir-opt")) + .into_iter() + .filter_map(Result::ok) + .filter(|e| e.file_type().is_file()) + { + let path = file.path(); + if path.extension() == Some("rs".as_ref()) { + if let Some(name) = path.file_name().and_then(|s| s.to_str()) { + if name.contains('-') { + if !bless { + tidy_error!( + bad, + "mir-opt test files should not have dashes in them: {}", + path.display() + ); + } else { + let new_name = name.replace('-', "_"); + let mut new_path = path.to_owned(); + new_path.set_file_name(new_name); + let _ = std::fs::rename(path, new_path); + } + } + } + } + } +} + +pub fn check(path: &Path, bless: bool, bad: &mut bool) { + check_unused_files(path, bad); + check_dash_files(path, bless, bad); +} From d3ab3cec036b48bb4a83c81cd74fd510e48eb6e2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 3 Nov 2022 08:37:45 -0400 Subject: [PATCH 069/482] Revert "Update cargo" This reverts commit 331aa4509315f670803b7e232486be84d84ea686. This Cargo upgrade introduced a regression into dependency resolution, so reverting the upgrade until we can fix that. --- Cargo.lock | 8 ++++---- src/tools/cargo | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2b460d9a857e..33b1299976f3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f" dependencies = [ "curl-sys", "libc", @@ -1051,9 +1051,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.59+curl-7.86.0" +version = "0.4.55+curl-7.83.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407" +checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" dependencies = [ "cc", "libc", diff --git a/src/tools/cargo b/src/tools/cargo index 810cbad9a123a..7e484fc1a766f 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 810cbad9a123ad4ee0a55a96171b8f8478ff1c03 +Subproject commit 7e484fc1a766f56dbc95380f45719698e0c82749 From f43bd021753c3322a0d436f2bde9aa50f33eee91 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Sep 2022 00:18:35 +0000 Subject: [PATCH 070/482] Make obligations_for_self_ty only return an obligation --- compiler/rustc_hir_typeck/src/closure.rs | 59 +++++++----- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 96 ++++++++++--------- 2 files changed, 84 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index a5a45f75e0e24..cc1191d32458f 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -225,33 +225,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, expected_vid: ty::TyVid, ) -> (Option>, Option) { - let expected_sig = - self.obligations_for_self_ty(expected_vid).find_map(|(_, obligation)| { - debug!(?obligation.predicate); - - let bound_predicate = obligation.predicate.kind(); - if let ty::PredicateKind::Projection(proj_predicate) = - obligation.predicate.kind().skip_binder() - { - // Given a Projection predicate, we can potentially infer - // the complete signature. - self.deduce_sig_from_projection( - Some(obligation.cause.span), - bound_predicate.rebind(proj_predicate), - ) - } else { - None - } - }); - + let mut expected_sig = None; // Even if we can't infer the full signature, we may be able to // infer the kind. This can occur when we elaborate a predicate // like `F : Fn
`. Note that due to subtyping we could encounter // many viable options, so pick the most restrictive. - let expected_kind = self - .obligations_for_self_ty(expected_vid) - .filter_map(|(tr, _)| self.tcx.fn_trait_kind_from_lang_item(tr.def_id())) - .fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur)))); + let mut expected_kind = None; + + for obligation in self.obligations_for_self_ty(expected_vid) { + debug!(?obligation.predicate); + let bound_predicate = obligation.predicate.kind(); + + if expected_sig.is_none() + && let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() + { + // Given a Projection predicate, we can potentially infer + // the complete signature. + expected_sig = self.deduce_sig_from_projection( + Some(obligation.cause.span), + bound_predicate.rebind(proj_predicate), + ); + } + + let trait_def_id = match bound_predicate.skip_binder() { + ty::PredicateKind::Projection(data) => { + Some(data.projection_ty.trait_def_id(self.tcx)) + } + ty::PredicateKind::Trait(data) => Some(data.def_id()), + _ => None, + }; + if let Some(closure_kind) = + trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_lang_item(def_id)) + { + expected_kind = Some( + expected_kind + .map_or_else(|| closure_kind, |current| cmp::min(current, closure_kind)), + ); + } + } (expected_sig, expected_kind) } @@ -689,7 +700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let output_ty = match *ret_ty.kind() { ty::Infer(ty::TyVar(ret_vid)) => { - self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| { + self.obligations_for_self_ty(ret_vid).find_map(|obligation| { get_future_output(obligation.predicate, obligation.cause.span) })? } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 6a1cffe3e6025..d2962a3836fae 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -21,8 +21,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMut use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPolyTraitRef, - ToPredicate, Ty, UserType, + self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, + UserType, }; use rustc_middle::ty::{GenericArgKind, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts}; use rustc_session::lint; @@ -650,12 +650,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn self_type_matches_expected_vid( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - expected_vid: ty::TyVid, - ) -> bool { - let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty()); + fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool { + let self_ty = self.shallow_resolve(self_ty); debug!(?self_ty); match *self_ty.kind() { @@ -674,54 +670,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn obligations_for_self_ty<'b>( &'b self, self_ty: ty::TyVid, - ) -> impl Iterator, traits::PredicateObligation<'tcx>)> - + Captures<'tcx> - + 'b { + ) -> impl Iterator> + Captures<'tcx> + 'b { // FIXME: consider using `sub_root_var` here so we // can see through subtyping. let ty_var_root = self.root_var(self_ty); trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations()); - self.fulfillment_cx - .borrow() - .pending_obligations() - .into_iter() - .filter_map(move |obligation| { - let bound_predicate = obligation.predicate.kind(); - match bound_predicate.skip_binder() { - ty::PredicateKind::Projection(data) => Some(( - bound_predicate.rebind(data).required_poly_trait_ref(self.tcx), - obligation, - )), - ty::PredicateKind::Trait(data) => { - Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation)) - } - ty::PredicateKind::Subtype(..) => None, - ty::PredicateKind::Coerce(..) => None, - ty::PredicateKind::RegionOutlives(..) => None, - ty::PredicateKind::TypeOutlives(..) => None, - ty::PredicateKind::WellFormed(..) => None, - ty::PredicateKind::ObjectSafe(..) => None, - ty::PredicateKind::ConstEvaluatable(..) => None, - ty::PredicateKind::ConstEquate(..) => None, - // N.B., this predicate is created by breaking down a - // `ClosureType: FnFoo()` predicate, where - // `ClosureType` represents some `Closure`. It can't - // possibly be referring to the current closure, - // because we haven't produced the `Closure` for - // this closure yet; this is exactly why the other - // code is looking for a self type of an unresolved - // inference variable. - ty::PredicateKind::ClosureKind(..) => None, - ty::PredicateKind::TypeWellFormedFromEnv(..) => None, + self.fulfillment_cx.borrow().pending_obligations().into_iter().filter_map( + move |obligation| match &obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Projection(data) + if self.self_type_matches_expected_vid( + data.projection_ty.self_ty(), + ty_var_root, + ) => + { + Some(obligation) } - }) - .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root)) + ty::PredicateKind::Trait(data) + if self.self_type_matches_expected_vid(data.self_ty(), ty_var_root) => + { + Some(obligation) + } + + ty::PredicateKind::Trait(..) + | ty::PredicateKind::Projection(..) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::RegionOutlives(..) + | ty::PredicateKind::TypeOutlives(..) + | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::ObjectSafe(..) + | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::ConstEquate(..) + // N.B., this predicate is created by breaking down a + // `ClosureType: FnFoo()` predicate, where + // `ClosureType` represents some `Closure`. It can't + // possibly be referring to the current closure, + // because we haven't produced the `Closure` for + // this closure yet; this is exactly why the other + // code is looking for a self type of an unresolved + // inference variable. + | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, + }, + ) } pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool { - self.obligations_for_self_ty(self_ty) - .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait()) + let sized_did = self.tcx.lang_items().sized_trait(); + self.obligations_for_self_ty(self_ty).any(|obligation| { + match obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(data) => Some(data.def_id()) == sized_did, + _ => false, + } + }) } pub(in super::super) fn err_args(&self, len: usize) -> Vec> { From a81a93843135f4bde8cce3639c090cae85d474b9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Sep 2022 00:35:23 +0000 Subject: [PATCH 071/482] Elaborate supertrait obligations when deducing closure signature --- compiler/rustc_hir_typeck/src/closure.rs | 18 +++++++----- ...ue-23012-supertrait-signature-inference.rs | 29 +++++++++++++++++++ .../issue-57611-trait-alias.rs | 3 +- .../issue-57611-trait-alias.stderr | 26 ----------------- 4 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 src/test/ui/closures/issue-23012-supertrait-signature-inference.rs delete mode 100644 src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index cc1191d32458f..4f8ac45d5a630 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -15,6 +15,7 @@ use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Span; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::ArgKind; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use std::cmp; @@ -226,27 +227,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_vid: ty::TyVid, ) -> (Option>, Option) { let mut expected_sig = None; - // Even if we can't infer the full signature, we may be able to - // infer the kind. This can occur when we elaborate a predicate - // like `F : Fn`. Note that due to subtyping we could encounter - // many viable options, so pick the most restrictive. let mut expected_kind = None; - for obligation in self.obligations_for_self_ty(expected_vid) { + for obligation in traits::elaborate_obligations( + self.tcx, + self.obligations_for_self_ty(expected_vid).collect(), + ) { debug!(?obligation.predicate); let bound_predicate = obligation.predicate.kind(); + // Given a Projection predicate, we can potentially infer + // the complete signature. if expected_sig.is_none() && let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() { - // Given a Projection predicate, we can potentially infer - // the complete signature. expected_sig = self.deduce_sig_from_projection( Some(obligation.cause.span), bound_predicate.rebind(proj_predicate), ); } + // Even if we can't infer the full signature, we may be able to + // infer the kind. This can occur when we elaborate a predicate + // like `F : Fn`. Note that due to subtyping we could encounter + // many viable options, so pick the most restrictive. let trait_def_id = match bound_predicate.skip_binder() { ty::PredicateKind::Projection(data) => { Some(data.projection_ty.trait_def_id(self.tcx)) diff --git a/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs b/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs new file mode 100644 index 0000000000000..5899b703e7c13 --- /dev/null +++ b/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs @@ -0,0 +1,29 @@ +// check-pass +// Checks that we can infer a closure signature even if the `FnOnce` bound is +// a supertrait of the obligations we have currently registered for the Ty var. + +pub trait Receive: FnOnce(Result) { + fn receive(self, res: Result); +} + +impl)> Receive for F { + fn receive(self, res: Result) { + self(res) + } +} + +pub trait Async { + fn receive>(self, f: F); +} + +impl Async for Result { + fn receive>(self, f: F) { + f(self) + } +} + +pub fn main() { + Ok::(123).receive(|res| { + res.unwrap(); + }); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index 067ed7ea1e585..cad3e0f66774d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -1,7 +1,6 @@ +// check-pass // Regression test for issue #57611 // Ensures that we don't ICE -// FIXME: This should compile, but it currently doesn't -// known-bug: unknown #![feature(trait_alias)] #![feature(type_alias_impl_trait)] diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr deleted file mode 100644 index 6344f114a9131..0000000000000 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:21:9 - | -LL | |x| x - | ^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> Fn<(&'a X,)>` - found trait `Fn<(&X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:21:9 - | -LL | |x| x - | ^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:21:9 - | -LL | |x| x - | ^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. From 68ea9017ac0cd5160bc3b764fd71ee4deec9a78c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 15 Oct 2022 18:48:13 +0000 Subject: [PATCH 072/482] reverse obligations for better diagnostics on multiple conflicting fn bounds --- compiler/rustc_hir_typeck/src/closure.rs | 5 ++++- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 4f8ac45d5a630..14f6e7d36be2c 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -231,7 +231,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for obligation in traits::elaborate_obligations( self.tcx, - self.obligations_for_self_ty(expected_vid).collect(), + // Reverse the obligations here, since `elaborate_*` uses a stack, + // and we want to keep inference generally in the same order of + // the registered obligations. + self.obligations_for_self_ty(expected_vid).rev().collect(), ) { debug!(?obligation.predicate); let bound_predicate = obligation.predicate.kind(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d2962a3836fae..7c22eaf18f855 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -670,7 +670,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn obligations_for_self_ty<'b>( &'b self, self_ty: ty::TyVid, - ) -> impl Iterator> + Captures<'tcx> + 'b { + ) -> impl DoubleEndedIterator> + Captures<'tcx> + 'b + { // FIXME: consider using `sub_root_var` here so we // can see through subtyping. let ty_var_root = self.root_var(self_ty); From 1bf777b300cd40f6e7a584160c082b7157d6cb8b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 11 Oct 2022 10:00:01 -0700 Subject: [PATCH 073/482] rustdoc: use ThinVec for cleaned generics --- Cargo.lock | 4 +- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_ast_lowering/Cargo.toml | 2 +- compiler/rustc_builtin_macros/Cargo.toml | 2 +- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_middle/Cargo.toml | 2 +- compiler/rustc_query_impl/Cargo.toml | 2 +- compiler/rustc_query_system/Cargo.toml | 2 +- compiler/rustc_serialize/Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/clean/auto_trait.rs | 11 +-- src/librustdoc/clean/mod.rs | 96 +++++++++++------------ src/librustdoc/clean/simplify.rs | 5 +- src/librustdoc/clean/types.rs | 4 +- 14 files changed, 67 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33b1299976f3e..1a91898be4e3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4887,9 +4887,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thin-vec" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104c2cb3180b6fb6d5b2278768e9b88b578d32ba751ea6e8d026688a40d7ed87" +checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b" [[package]] name = "thiserror" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index fcbf968182504..9253b7e6891a2 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index ce1c8d4997d74..6a59b9e6151ce 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 6469d0d7b88a6..467fa932a1567 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 9daa21ef6b11d..5152d5ab0465c 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -25,7 +25,7 @@ smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dang stable_deref_trait = "1.0.0" stacker = "0.1.14" tempfile = "3.2" -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [dependencies.parking_lot] diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index de916ea8c4973..8e7d0cf2ab1b0 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -32,7 +32,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index e7f12caaf33e5..b2111a1262a3c 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -21,7 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index faddad7417109..028756b5a0a18 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -22,7 +22,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" [features] diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 3b0b3144f2cd7..db0ef73544faa 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] indexmap = "1.9.1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" [dev-dependencies] rustc_macros = { path = "../rustc_macros" } diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 7bc35c7d5516f..0da69202e679f 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -20,7 +20,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } smallvec = "1.8.1" tempfile = "3" -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" tracing-tree = "0.2.0" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 00bdbe41ee419..84e77e69ecff3 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; +use thin_vec::ThinVec; use std::fmt::Debug; @@ -110,7 +111,7 @@ where ); let params = raw_generics.params; - Generics { params, where_predicates: Vec::new() } + Generics { params, where_predicates: ThinVec::new() } } AutoTraitResult::ExplicitImpl => return None, }; @@ -183,7 +184,7 @@ where fn handle_lifetimes<'cx>( regions: &RegionConstraintData<'cx>, names_map: &FxHashMap, - ) -> Vec { + ) -> ThinVec { // Our goal is to 'flatten' the list of constraints by eliminating // all intermediate RegionVids. At the end, all constraints should // be between Regions (aka region variables). This gives us the information @@ -429,7 +430,7 @@ where &mut self, item_def_id: DefId, param_env: ty::ParamEnv<'tcx>, - mut existing_predicates: Vec, + mut existing_predicates: ThinVec, vid_to_region: FxHashMap>, ) -> Generics { debug!( @@ -663,7 +664,7 @@ where /// both for visual consistency between 'rustdoc' runs, and to /// make writing tests much easier #[inline] - fn sort_where_predicates(&self, predicates: &mut Vec) { + fn sort_where_predicates(&self, predicates: &mut [WherePredicate]) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. @@ -710,7 +711,7 @@ where /// approach is probably somewhat slower, but the small number of items /// involved (impls rarely have more than a few bounds) means that it /// shouldn't matter in practice. - fn unstable_debug_sort(&self, vec: &mut Vec) { + fn unstable_debug_sort(&self, vec: &mut [T]) { vec.sort_by_cached_key(|x| format!("{:?}", x)) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ad4ad4104e104..1fbcc53953318 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -601,7 +601,7 @@ pub(crate) fn clean_generics<'tcx>( }) .collect::>(); - let mut params = Vec::with_capacity(gens.params.len()); + let mut params = ThinVec::with_capacity(gens.params.len()); for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { let p = clean_generic_param(cx, Some(gens), p); params.push(p); @@ -675,7 +675,7 @@ fn clean_ty_generics<'tcx>( } ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)), }) - .collect::>(); + .collect::>(); // param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)] let mut impl_trait_proj = @@ -1211,56 +1211,47 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( tcx.generics_of(assoc_item.def_id), ty::GenericPredicates { parent: None, predicates }, ); - // Move bounds that are (likely) directly attached to the associated type - // from the where clause to the associated type. - // There is no guarantee that this is what the user actually wrote but we have - // no way of knowing. - let mut bounds = generics - .where_predicates - .drain_filter(|pred| match *pred { - WherePredicate::BoundPredicate { - ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), - .. - } => { - if assoc.name != my_name { - return false; - } - if trait_.def_id() != assoc_item.container_id(tcx) { - return false; - } - match *self_type { - Generic(ref s) if *s == kw::SelfUpper => {} - _ => return false, - } - match &assoc.args { - GenericArgs::AngleBracketed { args, bindings } => { - if !bindings.is_empty() - || generics - .params - .iter() - .zip(args.iter()) - .any(|(param, arg)| !param_eq_arg(param, arg)) - { - return false; - } - } - GenericArgs::Parenthesized { .. } => { - // The only time this happens is if we're inside the rustdoc for Fn(), - // which only has one associated type, which is not a GAT, so whatever. + // Filter out the bounds that are (likely?) directly attached to the associated type, + // as opposed to being located in the where clause. + let mut bounds: Vec = Vec::new(); + generics.where_predicates.retain_mut(|pred| match *pred { + WherePredicate::BoundPredicate { + ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), + bounds: ref mut pred_bounds, + .. + } => { + if assoc.name != my_name { + return true; + } + if trait_.def_id() != assoc_item.container_id(tcx) { + return true; + } + match *self_type { + Generic(ref s) if *s == kw::SelfUpper => {} + _ => return true, + } + match &assoc.args { + GenericArgs::AngleBracketed { args, bindings } => { + if !bindings.is_empty() + || generics + .params + .iter() + .zip(args.iter()) + .any(|(param, arg)| !param_eq_arg(param, arg)) + { + return true; } } - true - } - _ => false, - }) - .flat_map(|pred| { - if let WherePredicate::BoundPredicate { bounds, .. } = pred { - bounds - } else { - unreachable!() + GenericArgs::Parenthesized { .. } => { + // The only time this happens is if we're inside the rustdoc for Fn(), + // which only has one associated type, which is not a GAT, so whatever. + } } - }) - .collect::>(); + bounds.extend(mem::replace(pred_bounds, Vec::new())); + false + } + _ => true, + }); // Our Sized/?Sized bound didn't get handled when creating the generics // because we didn't actually get our whole set of bounds until just now // (some of them may have come from the trait). If we do have a sized @@ -1276,7 +1267,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( // (generic) associated type from the where clause to the respective parameter. // There is no guarantee that this is what the user actually wrote but we have // no way of knowing. - let mut where_predicates = Vec::new(); + let mut where_predicates = ThinVec::new(); for mut pred in generics.where_predicates { if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred && let Some(GenericParamDef { @@ -1317,7 +1308,10 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( cx, Some(assoc_item.def_id), ), - generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + generics: Generics { + params: ThinVec::new(), + where_predicates: ThinVec::new(), + }, item_type: None, }), Vec::new(), diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 1bcb9fcd5a45f..1c184f9b2695c 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -14,13 +14,14 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use rustc_middle::ty; +use thin_vec::ThinVec; use crate::clean; use crate::clean::GenericArgs as PP; use crate::clean::WherePredicate as WP; use crate::core::DocContext; -pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { +pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec { // First, partition the where clause into its separate components. // // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to @@ -59,7 +60,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { }); // And finally, let's reassemble everything - let mut clauses = Vec::new(); + let mut clauses = ThinVec::with_capacity(lifetimes.len() + tybounds.len() + equalities.len()); clauses.extend( lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }), ); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 439311f064029..e4a8b5c9d189f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1462,8 +1462,8 @@ impl GenericParamDef { // maybe use a Generic enum and use Vec? #[derive(Clone, Debug, Default)] pub(crate) struct Generics { - pub(crate) params: Vec, - pub(crate) where_predicates: Vec, + pub(crate) params: ThinVec, + pub(crate) where_predicates: ThinVec, } impl Generics { From a686f6f6ce32b678ea3120588dd3c934877488f6 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 12 Oct 2022 10:51:10 -0700 Subject: [PATCH 074/482] rustdoc: remove unneeded Box from ItemKind --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/json/conversions.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1fbcc53953318..ae9ebc51d11de 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1080,7 +1080,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Type(bounds, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); - TyAssocTypeItem(Box::new(generics), bounds) + TyAssocTypeItem(generics, bounds) } }; Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) @@ -1297,7 +1297,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( bounds, ) } else { - TyAssocTypeItem(Box::new(generics), bounds) + TyAssocTypeItem(generics, bounds) } } else { // FIXME: when could this happen? Associated items in inherent impls? diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e4a8b5c9d189f..8b71274bbabde 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -795,7 +795,7 @@ pub(crate) enum ItemKind { /// A required associated type in a trait declaration. /// /// The bounds may be non-empty if there is a `where` clause. - TyAssocTypeItem(Box, Vec), + TyAssocTypeItem(Generics, Vec), /// An associated type in a trait impl or a provided one in a trait declaration. AssocTypeItem(Box, Vec), /// An item that has been stripped by a rustdoc pass diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 4962eb8f8e176..4889ac25acb84 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -284,7 +284,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) } } TyAssocTypeItem(g, b) => ItemEnum::AssocType { - generics: (*g).into_tcx(tcx), + generics: g.into_tcx(tcx), bounds: b.into_tcx(tcx), default: None, }, From 427ac2d41145f246bcbb522ed541fe5f94501643 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 12 Oct 2022 14:29:32 -0700 Subject: [PATCH 075/482] rustdoc: add size tracking for `Generics` --- src/librustdoc/clean/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8b71274bbabde..b667411187af7 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2594,6 +2594,7 @@ mod size_asserts { static_assert_size!(GenericArg, 48); static_assert_size!(GenericArgs, 32); static_assert_size!(GenericParamDef, 56); + static_assert_size!(Generics, 16); static_assert_size!(Item, 56); static_assert_size!(ItemKind, 88); static_assert_size!(PathSegment, 40); From 105bceac72b41d79620ec34f5a6b93876dabb4e7 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 31 Oct 2022 20:55:03 -0400 Subject: [PATCH 076/482] Remove let_underscore_must_use from list of uplifted lints --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index a3df56f1d2afc..ad550260c8bcf 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Language - [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/) - [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/) - [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/) -- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/) +- [Add lints `let_underscore_drop` and `let_underscore_lock` from Clippy](https://github.com/rust-lang/rust/pull/97739/) - [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/) - [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/). Usage of `MaybeUninit` is the correct way to work with uninitialized memory. From 0653c3869696cee0d49b33d9898fac304cd60bba Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 26 Oct 2022 14:40:34 -0300 Subject: [PATCH 077/482] Add visit_fn_ret_ty to hir intravisit --- compiler/rustc_hir/src/intravisit.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d852893ad5dc6..3ef58d7d70570 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -358,6 +358,9 @@ pub trait Visitor<'v>: Sized { fn visit_where_predicate(&mut self, predicate: &'v WherePredicate<'v>) { walk_where_predicate(self, predicate) } + fn visit_fn_ret_ty(&mut self, ret_ty: &'v FnRetTy<'v>) { + walk_fn_ret_ty(self, ret_ty) + } fn visit_fn_decl(&mut self, fd: &'v FnDecl<'v>) { walk_fn_decl(self, fd) } @@ -903,7 +906,7 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & for ty in function_declaration.inputs { visitor.visit_ty(ty) } - walk_fn_ret_ty(visitor, &function_declaration.output) + visitor.visit_fn_ret_ty(&function_declaration.output) } pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) { From b313d8a571ad16b085fb722762057a9044ab4f59 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 17:33:25 +0000 Subject: [PATCH 078/482] Properly render asyncness for traits without default body --- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/mod.rs | 32 +++++++++++++++++------------ src/librustdoc/clean/types.rs | 5 +---- src/test/rustdoc/async-trait-sig.rs | 14 +++++++++++++ 4 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 src/test/rustdoc/async-trait-sig.rs diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 3eebb4ace477f..99d3bda6ebfff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -413,7 +413,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { let node = tcx.hir().get_by_def_id(def_id.expect_local()); - if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync } + node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness) } /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ae9ebc51d11de..c5abf42c09678 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -880,7 +880,7 @@ fn clean_fn_or_proc_macro<'tcx>( ProcMacroItem(ProcMacro { kind, helpers }) } None => { - let mut func = clean_function(cx, sig, generics, body_id); + let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id)); clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } @@ -917,16 +917,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib } } +enum FunctionArgs<'tcx> { + Body(hir::BodyId), + Names(&'tcx [Ident]), +} + fn clean_function<'tcx>( cx: &mut DocContext<'tcx>, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'tcx>, - body_id: hir::BodyId, + args: FunctionArgs<'tcx>, ) -> Box { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = clean_generics(generics, cx); - let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id); + let args = match args { + FunctionArgs::Body(body_id) => { + clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id) + } + FunctionArgs::Names(names) => { + clean_args_from_types_and_names(cx, sig.decl.inputs, names) + } + }; let mut decl = clean_fn_decl_with_args(cx, sig.decl, args); if sig.header.is_async() { decl.output = decl.sugared_async_return_type(); @@ -1051,18 +1063,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext ), hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)), hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, trait_item.generics, body); + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = clean_generics(trait_item.generics, cx); - let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names); - let decl = clean_fn_decl_with_args(cx, sig.decl, args); - (generics, decl) - }); - TyMethodItem(Box::new(Function { decl, generics })) + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); + TyMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); @@ -1099,7 +1105,7 @@ pub(crate) fn clean_impl_item<'tcx>( AssocConstItem(clean_ty(ty, cx), default) } hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, impl_.generics, body); + let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); let defaultness = cx.tcx.impl_defaultness(impl_.owner_id); MethodItem(m, Some(defaultness)) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b667411187af7..3a4bfc1a7405d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -694,13 +694,10 @@ impl Item { asyncness: hir::IsAsync::NotAsync, } } - ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => { + ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { let def_id = self.item_id.as_def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } - ItemKind::TyMethodItem(_) => { - build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync) - } _ => return None, }; Some(header) diff --git a/src/test/rustdoc/async-trait-sig.rs b/src/test/rustdoc/async-trait-sig.rs new file mode 100644 index 0000000000000..2578bc8f7a166 --- /dev/null +++ b/src/test/rustdoc/async-trait-sig.rs @@ -0,0 +1,14 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +pub trait Foo { + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32" + async fn bar() -> i32; + + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32" + async fn baz() -> i32 { + 1 + } +} From 2276348049fdac47442dc9b7869964aafa8a1aad Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 2 Nov 2022 15:33:36 -0700 Subject: [PATCH 079/482] rustdoc: remove redundant mobile CSS `.sidebar-elems { background }` The exact same background is already set for its parent, the `nav.sidebar`. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d6f2b02afd8f8..772e057ddb0ca 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1796,7 +1796,6 @@ in storage.js .sidebar-elems { margin-top: 1em; - background-color: var(--sidebar-background-color); } .content { From 567c19359235862663ed92dae8ab04a61c973bb8 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Thu, 3 Nov 2022 09:19:47 +0100 Subject: [PATCH 080/482] Add howto for adding new targets --- src/doc/rustc/src/target-tier-policy.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index 53d0470fa8135..df9131ce84afd 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -3,6 +3,7 @@ ## Table of Contents * [General](#general) +* [Adding a new target](#adding-a-new-target) * [Tier 3 target policy](#tier-3-target-policy) * [Tier 2 target policy](#tier-2-target-policy) * [Tier 2 with host tools](#tier-2-with-host-tools) @@ -104,6 +105,30 @@ indicates something entirely optional, and does not indicate guidance or recommendations. This language is based on [IETF RFC 2119](https://tools.ietf.org/html/rfc2119). +## Adding a new target + +New targets typically start as Tier 3 and then can be promoted later. +To propose addition of a new target, open a pull request on [`rust-lang/rust`]: + +- Copy the [Tier 3 target policy](#tier-3-target-policy) to the description + and fill it out, see [example][tier3example]. +- Add a new description for the target in `src/doc/rustc/src/platform-support` + using the [template][platform_template]. +- Add the target to the [SUMMARY.md][summary] (allows wildcards) and + [platform-support.md][platformsupport] (must name all targets verbatim). + Link to the created description page. +- Ensure the pull request is assigned to a member of the [Rust compiler team][rust_compiler_team] by commenting: + ```text + r? compiler-team + ``` + +[tier3example]: https://github.com/rust-lang/rust/pull/94872 +[platform_template]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/TEMPLATE.md +[summary]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/SUMMARY.md +[platformsupport]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support.md +[rust_compiler_team]: https://www.rust-lang.org/governance/teams/compiler +[`rust-lang/rust`]: https://github.com/rust-lang/rust + ## Tier 3 target policy At this tier, the Rust project provides no official support for a target, so we From 9778508b61b9400d7fc7ec93e8abf012c9b46c37 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 2 Nov 2022 23:15:49 +0800 Subject: [PATCH 081/482] deprecate DelaySpanBugEmitted and use ErrorGuaranteed directly --- .../rustc_const_eval/src/interpret/operand.rs | 4 ++-- compiler/rustc_middle/src/ty/abstract_const.rs | 4 ++-- compiler/rustc_middle/src/ty/consts/kind.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 15 +++------------ compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/structural_impls.rs | 1 - compiler/rustc_type_ir/src/lib.rs | 2 +- compiler/rustc_type_ir/src/sty.rs | 10 ++++------ 8 files changed, 14 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 0c212cf59e17f..dd00678aa0cea 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -4,7 +4,7 @@ use rustc_hir::def::Namespace; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; -use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty}; +use rustc_middle::ty::{ConstInt, Ty}; use rustc_middle::{mir, ty}; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; @@ -567,7 +567,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(..) => { throw_inval!(TooGeneric) } - ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { + ty::ConstKind::Error(reported) => { throw_inval!(AlreadyReported(reported)) } ty::ConstKind::Unevaluated(uv) => { diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 1aa4df7780084..e5bcd5fb27aa7 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -1,7 +1,7 @@ //! A subset of a mir body used for const evaluatability checking. use crate::mir; use crate::ty::visit::TypeVisitable; -use crate::ty::{self, DelaySpanBugEmitted, EarlyBinder, SubstsRef, Ty, TyCtxt}; +use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use std::cmp; @@ -43,7 +43,7 @@ impl<'tcx> AbstractConst<'tcx> { ) -> Result>, ErrorGuaranteed> { match ct.kind() { ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv), - ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), + ty::ConstKind::Error(reported) => Err(reported), _ => Ok(None), } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 4ab761e0715cd..c1c613f6c602e 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -69,7 +69,7 @@ pub enum ConstKind<'tcx> { /// A placeholder for a const which could not be computed; this is /// propagated to avoid useless error messages. - Error(ty::DelaySpanBugEmitted), + Error(ErrorGuaranteed), } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8e24f4813a7e8..11237a45f366d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -117,7 +117,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type BoundTy = ty::BoundTy; type PlaceholderType = ty::PlaceholderType; type InferTy = InferTy; - type DelaySpanBugEmitted = DelaySpanBugEmitted; + type ErrorGuaranteed = ErrorGuaranteed; type PredicateKind = ty::PredicateKind<'tcx>; type AllocId = crate::mir::interpret::AllocId; @@ -128,15 +128,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type PlaceholderRegion = ty::PlaceholderRegion; } -/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s -/// except through the error-reporting functions on a [`tcx`][TyCtxt]. -#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] -#[derive(TyEncodable, TyDecodable, HashStable)] -pub struct DelaySpanBugEmitted { - pub reported: ErrorGuaranteed, - _priv: (), -} - type InternedSet<'tcx, T> = ShardedHashMap, ()>; pub struct CtxtInterners<'tcx> { @@ -1303,7 +1294,7 @@ impl<'tcx> TyCtxt<'tcx> { #[track_caller] pub fn ty_error_with_message>(self, span: S, msg: &str) -> Ty<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () })) + self.mk_ty(Error(reported)) } /// Like [TyCtxt::ty_error] but for constants. @@ -1326,7 +1317,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Const<'tcx> { let reported = self.sess.delay_span_bug(span, msg); self.mk_const(ty::ConstS { - kind: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }), + kind: ty::ConstKind::Error(reported), ty, }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a42d05706137c..27090c62d21ed 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -80,7 +80,7 @@ pub use self::consts::{ }; pub use self::context::{ tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, - CtxtInterners, DeducedParamAttrs, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData, + CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GeneratorDiagnosticData, GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex, }; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 2cad333e3f52a..23cd93d6af40c 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -240,7 +240,6 @@ TrivialTypeTraversalAndLiftImpls! { Field, interpret::Scalar, rustc_target::abi::Size, - ty::DelaySpanBugEmitted, rustc_type_ir::DebruijnIndex, ty::BoundVar, ty::Placeholder, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7fbe78aa52353..7c3eb4efbc984 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -45,7 +45,7 @@ pub trait Interner { type BoundTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type PlaceholderType: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type InferTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type DelaySpanBugEmitted: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type ErrorGuaranteed: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type PredicateKind: Clone + Debug + Hash + PartialEq + Eq; type AllocId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index a4fb1480fa448..02cbb2e858f80 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -217,7 +217,7 @@ pub enum TyKind { /// A placeholder for a type which could not be computed; this is /// propagated to avoid useless error messages. - Error(I::DelaySpanBugEmitted), + Error(I::ErrorGuaranteed), } impl TyKind { @@ -626,7 +626,7 @@ impl fmt::Debug for TyKind { // This is manually implemented because a derive would require `I: Encodable` impl Encodable for TyKind where - I::DelaySpanBugEmitted: Encodable, + I::ErrorGuaranteed: Encodable, I::AdtDef: Encodable, I::SubstsRef: Encodable, I::DefId: Encodable, @@ -645,7 +645,6 @@ where I::BoundTy: Encodable, I::PlaceholderType: Encodable, I::InferTy: Encodable, - I::DelaySpanBugEmitted: Encodable, I::PredicateKind: Encodable, I::AllocId: Encodable, { @@ -744,7 +743,7 @@ where // This is manually implemented because a derive would require `I: Decodable` impl> Decodable for TyKind where - I::DelaySpanBugEmitted: Decodable, + I::ErrorGuaranteed: Decodable, I::AdtDef: Decodable, I::SubstsRef: Decodable, I::DefId: Decodable, @@ -763,7 +762,6 @@ where I::BoundTy: Decodable, I::PlaceholderType: Decodable, I::InferTy: Decodable, - I::DelaySpanBugEmitted: Decodable, I::PredicateKind: Decodable, I::AllocId: Decodable, { @@ -829,7 +827,7 @@ where I::ParamTy: HashStable, I::PlaceholderType: HashStable, I::InferTy: HashStable, - I::DelaySpanBugEmitted: HashStable, + I::ErrorGuaranteed: HashStable, { #[inline] fn hash_stable( From 7ee4ecabd706356cfabab1439ed589ae1003f0f5 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 3 Nov 2022 04:57:44 +0800 Subject: [PATCH 082/482] change error_reported to use Result instead of an option --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../rustc_hir_analysis/src/coherence/orphan.rs | 4 +--- compiler/rustc_hir_typeck/src/cast.rs | 16 +++++++--------- .../src/traits/specialization_graph.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 +---- compiler/rustc_middle/src/ty/visit.rs | 6 +++--- compiler/rustc_transmute/src/lib.rs | 2 +- 7 files changed, 15 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 9dd9bf05540fb..7747ae14a24b2 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1979,7 +1979,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } err.emit() - } else if let Some(reported) = qself_ty.error_reported() { + } else if let Err(reported) = qself_ty.error_reported() { reported } else { // Don't print `TyErr` to the user. diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index bb45c3823d839..71c932d747bca 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -23,9 +23,7 @@ pub(crate) fn orphan_check_impl( impl_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); - if let Some(err) = trait_ref.error_reported() { - return Err(err); - } + trait_ref.error_reported()?; let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id); if tcx.trait_is_auto(trait_ref.def_id) { diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index d1dab0540be95..0749c01878d24 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -94,10 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("pointer_kind({:?}, {:?})", t, span); let t = self.resolve_vars_if_possible(t); - - if let Some(reported) = t.error_reported() { - return Err(reported); - } + t.error_reported()?; if self.type_is_sized_modulo_regions(self.param_env, t, span) { return Ok(Some(PointerKind::Thin)); @@ -223,7 +220,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { match cast_ty.kind() { ty::Dynamic(_, _, ty::Dyn) | ty::Slice(..) => { let reported = check.report_cast_to_unsized_type(fcx); - Err(reported) + return Err(reported); } _ => Ok(check), } @@ -614,10 +611,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { } fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) -> ErrorGuaranteed { - if let Some(reported) = - self.cast_ty.error_reported().or_else(|| self.expr_ty.error_reported()) - { - return reported; + if let Err(err) = self.cast_ty.error_reported() { + return err; + } + if let Err(err) = self.expr_ty.error_reported() { + return err; } let tstr = fcx.ty_to_string(self.cast_ty); diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index f1c2158826189..cccedc9ec6ea9 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -262,7 +262,7 @@ pub fn ancestors<'tcx>( if let Some(reported) = specialization_graph.has_errored { Err(reported) - } else if let Some(reported) = tcx.type_of(start_from_impl).error_reported() { + } else if let Err(reported) = tcx.type_of(start_from_impl).error_reported() { Err(reported) } else { Ok(Ancestors { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 11237a45f366d..fc3b071684999 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1316,10 +1316,7 @@ impl<'tcx> TyCtxt<'tcx> { msg: &str, ) -> Const<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - self.mk_const(ty::ConstS { - kind: ty::ConstKind::Error(reported), - ty, - }) + self.mk_const(ty::ConstS { kind: ty::ConstKind::Error(reported), ty }) } pub fn consider_optimizing String>(self, msg: T) -> bool { diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index c09f71f9a6d09..f0e9f990a8115 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -95,11 +95,11 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } - fn error_reported(&self) -> Option { + fn error_reported(&self) -> Result<(), ErrorGuaranteed> { if self.references_error() { - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) } else { - None + Ok(()) } } fn has_non_region_param(&self) -> bool { diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index f7cc94e53146a..384d03106b1e8 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -122,7 +122,7 @@ mod rustc { let c = c.eval(tcx, param_env); - if let Some(err) = c.error_reported() { + if let Err(err) = c.error_reported() { return Some(Self { alignment: true, lifetimes: true, From 0c28225b8feef0f6267b36565c365778b987a020 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 3 Nov 2022 09:22:08 +0800 Subject: [PATCH 083/482] remove 'delay_span_bug' following 'references_error' --- compiler/rustc_const_eval/src/transform/promote_consts.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f3ae16da43bd1..f48bcd9080966 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -45,11 +45,10 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> { // There's not really any point in promoting errorful MIR. // // This does not include MIR that failed const-checking, which we still try to promote. - if body.return_ty().references_error() { - tcx.sess.delay_span_bug(body.span, "PromoteTemps: MIR had errors"); + if let Err(_) = body.return_ty().error_reported() { + debug!("PromoteTemps: MIR had errors"); return; } - if body.source.promoted.is_some() { return; } From 96fd733d3793e77ee6485bd4eefe6495d429edec Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 3 Nov 2022 09:42:34 +0800 Subject: [PATCH 084/482] code cleanup --- compiler/rustc_hir_typeck/src/cast.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 0749c01878d24..7d3129f7ea730 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -219,8 +219,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // inference is more completely known. match cast_ty.kind() { ty::Dynamic(_, _, ty::Dyn) | ty::Slice(..) => { - let reported = check.report_cast_to_unsized_type(fcx); - return Err(reported); + Err(check.report_cast_to_unsized_type(fcx)) } _ => Ok(check), } From 84bc834b92e0686469f706e1c84b78d20b40bfb0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 3 Nov 2022 15:41:01 +0000 Subject: [PATCH 085/482] Move some tests from `src/test/ui` to more reasonable places --- src/test/ui/{ => macros}/attr-from-macro.rs | 0 src/test/ui/{ => macros}/auxiliary/attr-from-macro.rs | 0 src/test/ui/{ => repr}/align-with-extern-c-fn.rs | 0 src/test/ui/{ => repr}/aligned_enum_cast.rs | 0 src/test/ui/{ => repr}/repr_c_int_align.rs | 0 src/test/ui/{rfc1623.rs => rfcs/rfc1623-2.rs} | 0 src/test/ui/{rfc1623.stderr => rfcs/rfc1623-2.stderr} | 8 ++++---- src/test/ui/{rfc1623-2.rs => rfcs/rfc1623-3.rs} | 0 src/test/ui/{rfc1623-2.stderr => rfcs/rfc1623-3.stderr} | 6 +++--- src/tools/tidy/src/ui_tests.rs | 2 +- 10 files changed, 8 insertions(+), 8 deletions(-) rename src/test/ui/{ => macros}/attr-from-macro.rs (100%) rename src/test/ui/{ => macros}/auxiliary/attr-from-macro.rs (100%) rename src/test/ui/{ => repr}/align-with-extern-c-fn.rs (100%) rename src/test/ui/{ => repr}/aligned_enum_cast.rs (100%) rename src/test/ui/{ => repr}/repr_c_int_align.rs (100%) rename src/test/ui/{rfc1623.rs => rfcs/rfc1623-2.rs} (100%) rename src/test/ui/{rfc1623.stderr => rfcs/rfc1623-2.stderr} (91%) rename src/test/ui/{rfc1623-2.rs => rfcs/rfc1623-3.rs} (100%) rename src/test/ui/{rfc1623-2.stderr => rfcs/rfc1623-3.stderr} (94%) diff --git a/src/test/ui/attr-from-macro.rs b/src/test/ui/macros/attr-from-macro.rs similarity index 100% rename from src/test/ui/attr-from-macro.rs rename to src/test/ui/macros/attr-from-macro.rs diff --git a/src/test/ui/auxiliary/attr-from-macro.rs b/src/test/ui/macros/auxiliary/attr-from-macro.rs similarity index 100% rename from src/test/ui/auxiliary/attr-from-macro.rs rename to src/test/ui/macros/auxiliary/attr-from-macro.rs diff --git a/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/repr/align-with-extern-c-fn.rs similarity index 100% rename from src/test/ui/align-with-extern-c-fn.rs rename to src/test/ui/repr/align-with-extern-c-fn.rs diff --git a/src/test/ui/aligned_enum_cast.rs b/src/test/ui/repr/aligned_enum_cast.rs similarity index 100% rename from src/test/ui/aligned_enum_cast.rs rename to src/test/ui/repr/aligned_enum_cast.rs diff --git a/src/test/ui/repr_c_int_align.rs b/src/test/ui/repr/repr_c_int_align.rs similarity index 100% rename from src/test/ui/repr_c_int_align.rs rename to src/test/ui/repr/repr_c_int_align.rs diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfcs/rfc1623-2.rs similarity index 100% rename from src/test/ui/rfc1623.rs rename to src/test/ui/rfcs/rfc1623-2.rs diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfcs/rfc1623-2.stderr similarity index 91% rename from src/test/ui/rfc1623.stderr rename to src/test/ui/rfcs/rfc1623-2.stderr index b15a4cb110b73..d183eaaa6236e 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfcs/rfc1623-2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/rfc1623.rs:28:8 + --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, | ^^^ one type is more general than the other @@ -8,7 +8,7 @@ LL | f: &id, found trait `Fn<(&Foo<'_>,)>` error[E0308]: mismatched types - --> $DIR/rfc1623.rs:28:8 + --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, | ^^^ one type is more general than the other @@ -17,7 +17,7 @@ LL | f: &id, found trait `Fn<(&Foo<'_>,)>` error: implementation of `FnOnce` is not general enough - --> $DIR/rfc1623.rs:28:8 + --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, | ^^^ implementation of `FnOnce` is not general enough @@ -26,7 +26,7 @@ LL | f: &id, = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough - --> $DIR/rfc1623.rs:28:8 + --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, | ^^^ implementation of `FnOnce` is not general enough diff --git a/src/test/ui/rfc1623-2.rs b/src/test/ui/rfcs/rfc1623-3.rs similarity index 100% rename from src/test/ui/rfc1623-2.rs rename to src/test/ui/rfcs/rfc1623-3.rs diff --git a/src/test/ui/rfc1623-2.stderr b/src/test/ui/rfcs/rfc1623-3.stderr similarity index 94% rename from src/test/ui/rfc1623-2.stderr rename to src/test/ui/rfcs/rfc1623-3.stderr index 945c6533c797b..77fc3f0412ebf 100644 --- a/src/test/ui/rfc1623-2.stderr +++ b/src/test/ui/rfcs/rfc1623-3.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/rfc1623-2.rs:8:42 + --> $DIR/rfc1623-3.rs:8:42 | LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = | --- --- ^ expected named lifetime parameter @@ -12,7 +12,7 @@ LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = | +++++++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/rfc1623-2.rs:10:39 + --> $DIR/rfc1623-3.rs:10:39 | LL | &(non_elidable as fn(&u8, &u8) -> &u8); | --- --- ^ expected named lifetime parameter @@ -24,7 +24,7 @@ LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); | +++++++ ++ ++ ++ error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8` - --> $DIR/rfc1623-2.rs:10:6 + --> $DIR/rfc1623-3.rs:10:6 | LL | &(non_elidable as fn(&u8, &u8) -> &u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index c600f99c2c4bf..6bf7d8206a576 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,7 +7,7 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 948; +const ROOT_ENTRY_LIMIT: usize = 941; const ISSUES_ENTRY_LIMIT: usize = 2117; fn check_entries(path: &Path, bad: &mut bool) { From 99960c04eeed94cef0677105d56e374435f4fb89 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 3 Nov 2022 11:44:50 -0400 Subject: [PATCH 086/482] Add note to RELEASES.md regarding issue 102754. --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index ad550260c8bcf..5c1990bb6c97b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -87,6 +87,9 @@ Compatibility Notes This strengthens the forward compatibility lint deprecated_cfg_attr_crate_type_name to deny. - [`llvm-has-rust-patches` allows setting the build system to treat the LLVM as having Rust-specific patches](https://github.com/rust-lang/rust/pull/101072) This option may need to be set for distributions that are building Rust with a patched LLVM via `llvm-config`, not the built-in LLVM. +- Combining three or more languages (e.g. Objective C, C++ and Rust) into one binary may hit linker limitations when using `lld`. For more information, see [issue 102754][102754]. + +[102754]: https://github.com/rust-lang/rust/issues/102754 Internal Changes ---------------- From bf39751600c00161af25680766462cdcec597536 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 3 Nov 2022 12:29:17 -0700 Subject: [PATCH 087/482] rustdoc: clean up hardcoded CSS border color on search results Hardcoded colors in rustdoc.css should usually be avoided. --- src/librustdoc/html/static/css/rustdoc.css | 3 +-- src/test/rustdoc-gui/search-result-color.goml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 772e057ddb0ca..01f2c14b98d52 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -894,7 +894,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ /* A little margin ensures the browser's outlining of focused links has room to display. */ margin-left: 2px; margin-right: 2px; - border-bottom: 1px solid #aaa3; + border-bottom: 1px solid var(--border-color); } .search-results > a > div { @@ -1874,7 +1874,6 @@ in storage.js /* Display an alternating layout on tablets and phones */ .search-results > a { - border-bottom: 1px solid #aaa9; padding: 5px 0px; } .search-results .result-name, .search-results div.desc { diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 69bb30df954bd..37d7b03a09958 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -75,6 +75,12 @@ assert-css: ( {"color": "rgb(0, 150, 207)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgb(92, 103, 115)"} +) + // Checking the color of "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", @@ -181,6 +187,12 @@ assert-css: ( {"color": "rgb(221, 221, 221)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgb(224, 224, 224)"} +) + // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", @@ -272,6 +284,12 @@ assert-css: ( {"color": "rgb(0, 0, 0)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgb(224, 224, 224)"} +) + // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", From fc0e9acff185473946dc6c0edfa9413a7cdc2143 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 3 Nov 2022 13:22:54 -0700 Subject: [PATCH 088/482] rustdoc: remove no-op CSS `#main-content > .item-info { margin-top: 0 }` When this line was added in 04b4c40682c01cad8f9bc8d5b3907be91d6f81d4, it overrode a negative `margin-top` that was set on it by default. https://github.com/rust-lang/rust/blob/04b4c40682c01cad8f9bc8d5b3907be91d6f81d4/src/librustdoc/html/static/rustdoc.css#L500-L516 That negative top margin was removed in 593d6d1cb15c55c88319470dabb40126c7b7f1e2. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 01f2c14b98d52..54f6e1ed4d515 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -677,7 +677,6 @@ pre, .rustdoc.source .example-wrap { } #main-content > .item-info { - margin-top: 0; margin-left: 0; } From cd1722977a881a227ae8a9e36ac72b75b0ea1c30 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 15 Oct 2022 22:46:59 +0100 Subject: [PATCH 089/482] asm: Match clang behavior for inlateout fixed register operands We have 2 options for representing LLVM constraints for `inlateout` operands on a fixed register (e.g. `r0`): `={r0},0` or `={r0},{r0}`. This PR changes the behavior to the latter, which matches the behavior of Clang since https://reviews.llvm.org/D87279. --- compiler/rustc_codegen_llvm/src/asm.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 017513721b75b..88a4f62d93dfb 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -130,7 +130,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { op_idx.insert(idx, constraints.len()); constraints.push(reg_to_llvm(reg, Some(&value.layout))); } - InlineAsmOperandRef::InOut { reg, late: _, in_value, out_place: _ } => { + InlineAsmOperandRef::InOut { reg, late, in_value, out_place: _ } => { let value = llvm_fixup_input( self, in_value.immediate(), @@ -138,7 +138,16 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { &in_value.layout, ); inputs.push(value); - constraints.push(format!("{}", op_idx[&idx])); + + // In the case of fixed registers, we have the choice of + // either using a tied operand or duplicating the constraint. + // We prefer the latter because it matches the behavior of + // Clang. + if late && matches!(reg, InlineAsmRegOrRegClass::Reg(_)) { + constraints.push(format!("{}", reg_to_llvm(reg, Some(&in_value.layout)))); + } else { + constraints.push(format!("{}", op_idx[&idx])); + } } InlineAsmOperandRef::SymFn { instance } => { inputs.push(self.cx.get_fn(instance)); From d7e719109d5f43d708769cc27cc16907a2ce023f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Oct 2022 10:24:14 +0200 Subject: [PATCH 090/482] CStr: add some doc links --- library/core/src/ffi/c_str.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 8923f548adf72..15dd9ea7e8036 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -13,9 +13,9 @@ use crate::str; /// array of bytes. It can be constructed safely from a &[[u8]] /// slice, or unsafely from a raw `*const c_char`. It can then be /// converted to a Rust &[str] by performing UTF-8 validation, or -/// into an owned `CString`. +/// into an owned [`CString`]. /// -/// `&CStr` is to `CString` as &[str] is to `String`: the former +/// `&CStr` is to [`CString`] as &[str] is to [`String`]: the former /// in each pair are borrowed references; the latter are owned /// strings. /// @@ -24,6 +24,9 @@ use crate::str; /// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide /// a safe interface to other consumers. /// +/// [`CString`]: ../../std/ffi/struct.CString.html +/// [`String`]: ../../std/string/struct.String.html +/// /// # Examples /// /// Inspecting a foreign C string: From bd0fdcf33843a44d81d2af0481802c9ad76c5cbd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 30 Oct 2022 20:51:01 +0000 Subject: [PATCH 091/482] Free late-bound lifetimes in closures as well --- compiler/rustc_hir_analysis/src/collect/lifetimes.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 3f263a6de24ea..3d07f3fbc674d 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1377,11 +1377,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } else if let Some(body_id) = outermost_body { let fn_id = self.tcx.hir().body_owner(body_id); match self.tcx.hir().get(fn_id) { - Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. }) - | Node::TraitItem(&hir::TraitItem { + Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }) + | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) - | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => { + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) + | Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { let scope = self.tcx.hir().local_def_id(fn_id); def = Region::Free(scope.to_def_id(), def.id().unwrap()); } From 4bfb5008fe4b1c524104c64e0339e6e8041ab3fc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 30 Oct 2022 20:51:15 +0000 Subject: [PATCH 092/482] Create NLL infer vars for late-bound regions from closures --- .../rustc_borrowck/src/universal_regions.rs | 62 +++++++++++-------- compiler/rustc_middle/src/ty/context.rs | 4 +- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 2beb5e0ab5d20..51439dec44091 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId}; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt, +}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use std::iter; @@ -421,13 +423,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { first_extern_index } else { // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing - // function are actually external regions to us. For example, here, 'a is not local + // function/closures are actually external regions to us. For example, here, 'a is not local // to the closure c (although it is local to the fn foo): // fn foo<'a>() { // let c = || { let x: &'a u32 = ...; } // } - self.infcx - .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); + self.infcx.replace_late_bound_regions_with_nll_infer_vars( + self.infcx.tcx.local_parent(self.mir_def.did), + &mut indices, + ); // Any regions created during the execution of `defining_ty` or during the above // late-bound region replacement are all considered 'extern' regions self.infcx.num_region_vars() @@ -444,12 +448,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { bound_inputs_and_output, &mut indices, ); - // Converse of above, if this is a function then the late-bound regions declared on its - // signature are local to the fn. - if self.mir_def.did.to_def_id() == typeck_root_def_id { - self.infcx - .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); - } + // Converse of above, if this is a function/closure then the late-bound regions declared on its + // signature are local. + self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); let (unnormalized_output_ty, mut unnormalized_input_tys) = inputs_and_output.split_last().unwrap(); @@ -748,18 +749,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { #[instrument(skip(self, indices))] fn replace_late_bound_regions_with_nll_infer_vars( &self, - mir_def_id: LocalDefId, + mut mir_def_id: LocalDefId, indices: &mut UniversalRegionIndices<'tcx>, ) { let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id()); - for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| { - debug!(?r); - if !indices.indices.contains_key(&r) { - let region_vid = self.next_nll_region_var(FR); - debug!(?region_vid); - indices.insert_late_bound_region(r, region_vid.to_region_vid()); + + // Walk up the tree, collecting late-bound regions until we hit the typeck root + loop { + for_each_late_bound_region_defined_on(self.tcx, mir_def_id.to_def_id(), |r| { + debug!(?r); + if !indices.indices.contains_key(&r) { + let region_vid = self.next_nll_region_var(FR); + debug!(?region_vid); + indices.insert_late_bound_region(r, region_vid.to_region_vid()); + } + }); + + if mir_def_id.to_def_id() == typeck_root_def_id { + break; + } else { + mir_def_id = self.tcx.parent(mir_def_id.to_def_id()).expect_local(); } - }); + } } } @@ -810,14 +821,11 @@ fn for_each_late_bound_region_defined_on<'tcx>( fn_def_id: DefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) { - for ®ion_def_id in late_bounds.iter() { - let name = tcx.item_name(region_def_id.to_def_id()); - let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: fn_def_id, - bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name), - })); - f(liberated_region); - } + for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(fn_def_id.expect_local())) + { + let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; + let liberated_region = + tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region })); + f(liberated_region); } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fc3b071684999..aa4221d11fb37 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2883,9 +2883,7 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_bound_variable_kinds( self.late_bound_vars_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) - .unwrap_or_else(|| { - bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id) - }) + .unwrap_or_default() .iter(), ) } From 3758104a76bc20e77d14140a0aa63c1e1dd322a6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 30 Oct 2022 20:51:30 +0000 Subject: [PATCH 093/482] tests --- src/test/ui/closures/binder/late-bound-in-body.rs | 9 +++++++++ src/test/ui/closures/binder/nested-closures.rs | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 src/test/ui/closures/binder/late-bound-in-body.rs create mode 100644 src/test/ui/closures/binder/nested-closures.rs diff --git a/src/test/ui/closures/binder/late-bound-in-body.rs b/src/test/ui/closures/binder/late-bound-in-body.rs new file mode 100644 index 0000000000000..bb5c7552fdaa8 --- /dev/null +++ b/src/test/ui/closures/binder/late-bound-in-body.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(closure_lifetime_binder)] + +fn main() { + let _ = for<'a> || -> () { + let _: &'a bool = &true; + }; +} diff --git a/src/test/ui/closures/binder/nested-closures.rs b/src/test/ui/closures/binder/nested-closures.rs new file mode 100644 index 0000000000000..b3c36e7eebb7a --- /dev/null +++ b/src/test/ui/closures/binder/nested-closures.rs @@ -0,0 +1,7 @@ +// check-pass + +#![feature(closure_lifetime_binder)] + +fn main() { + for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; +} From c028e8a3eeee3c1c39155661d7e0df9cee917131 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 31 Oct 2022 03:28:05 +0000 Subject: [PATCH 094/482] Collect late-bound regions from all closure parents in `closure_mapping` --- .../rustc_borrowck/src/region_infer/mod.rs | 2 +- .../rustc_borrowck/src/universal_regions.rs | 82 ++++++++++--------- .../binder/nested-closures-regions.rs | 9 ++ .../binder/nested-closures-regions.stderr | 38 +++++++++ 4 files changed, 91 insertions(+), 40 deletions(-) create mode 100644 src/test/ui/closures/binder/nested-closures-regions.rs create mode 100644 src/test/ui/closures/binder/nested-closures-regions.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 8b63294fbab0e..0e7f243bcf36c 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2314,7 +2314,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx tcx, closure_substs, self.num_external_vids, - tcx.typeck_root_def_id(closure_def_id), + closure_def_id.expect_local(), ); debug!("apply_requirements: closure_mapping={:?}", closure_mapping); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 51439dec44091..0f300564c2086 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -243,7 +243,7 @@ impl<'tcx> UniversalRegions<'tcx> { tcx: TyCtxt<'tcx>, closure_substs: SubstsRef<'tcx>, expected_num_vars: usize, - typeck_root_def_id: DefId, + closure_def_id: LocalDefId, ) -> IndexVec> { let mut region_mapping = IndexVec::with_capacity(expected_num_vars); region_mapping.push(tcx.lifetimes.re_static); @@ -251,9 +251,13 @@ impl<'tcx> UniversalRegions<'tcx> { region_mapping.push(fr); }); - for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { - region_mapping.push(r); - }); + for_each_late_bound_region_in_scope( + tcx, + tcx.local_parent(closure_def_id), + |r| { + region_mapping.push(r); + }, + ); assert_eq!( region_mapping.len(), @@ -341,9 +345,8 @@ impl<'tcx> UniversalRegions<'tcx> { // tests, and the resulting print-outs include def-ids // and other things that are not stable across tests! // So we just include the region-vid. Annoying. - let typeck_root_def_id = tcx.typeck_root_def_id(def_id); - for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { - err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),)); + for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| { + err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); }); } DefiningTy::Generator(def_id, substs, _) => { @@ -356,9 +359,8 @@ impl<'tcx> UniversalRegions<'tcx> { // FIXME: As above, we'd like to print out the region // `r` but doing so is not stable across architectures // and so forth. - let typeck_root_def_id = tcx.typeck_root_def_id(def_id); - for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| { - err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),)); + for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| { + err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); }); } DefiningTy::FnDef(def_id, substs) => { @@ -749,28 +751,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { #[instrument(skip(self, indices))] fn replace_late_bound_regions_with_nll_infer_vars( &self, - mut mir_def_id: LocalDefId, + mir_def_id: LocalDefId, indices: &mut UniversalRegionIndices<'tcx>, ) { - let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id()); - - // Walk up the tree, collecting late-bound regions until we hit the typeck root - loop { - for_each_late_bound_region_defined_on(self.tcx, mir_def_id.to_def_id(), |r| { - debug!(?r); - if !indices.indices.contains_key(&r) { - let region_vid = self.next_nll_region_var(FR); - debug!(?region_vid); - indices.insert_late_bound_region(r, region_vid.to_region_vid()); - } - }); - - if mir_def_id.to_def_id() == typeck_root_def_id { - break; - } else { - mir_def_id = self.tcx.parent(mir_def_id.to_def_id()).expect_local(); + for_each_late_bound_region_in_scope(self.tcx, mir_def_id, |r| { + debug!(?r); + if !indices.indices.contains_key(&r) { + let region_vid = self.next_nll_region_var(FR); + debug!(?region_vid); + indices.insert_late_bound_region(r, region_vid.to_region_vid()); } - } + }); } } @@ -814,18 +805,31 @@ impl<'tcx> UniversalRegionIndices<'tcx> { } } -/// Iterates over the late-bound regions defined on fn_def_id and -/// invokes `f` with the liberated form of each one. -fn for_each_late_bound_region_defined_on<'tcx>( +/// Iterates over the late-bound regions defined on fn_def_id and all of its +/// parents, up to the typeck root, and invokes `f` with the liberated form +/// of each one. +fn for_each_late_bound_region_in_scope<'tcx>( tcx: TyCtxt<'tcx>, - fn_def_id: DefId, + mut mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(fn_def_id.expect_local())) - { - let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; - let liberated_region = - tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region })); - f(liberated_region); + let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id()); + + // Walk up the tree, collecting late-bound regions until we hit the typeck root + loop { + for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) { + let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; + let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { + scope: mir_def_id.to_def_id(), + bound_region, + })); + f(liberated_region); + } + + if mir_def_id.to_def_id() == typeck_root_def_id { + break; + } else { + mir_def_id = tcx.local_parent(mir_def_id); + } } } diff --git a/src/test/ui/closures/binder/nested-closures-regions.rs b/src/test/ui/closures/binder/nested-closures-regions.rs new file mode 100644 index 0000000000000..6bfc6c80b7882 --- /dev/null +++ b/src/test/ui/closures/binder/nested-closures-regions.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(closure_lifetime_binder)] +#![feature(rustc_attrs)] + +#[rustc_regions] +fn main() { + for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; +} diff --git a/src/test/ui/closures/binder/nested-closures-regions.stderr b/src/test/ui/closures/binder/nested-closures-regions.stderr new file mode 100644 index 0000000000000..b385e0ed6e0a5 --- /dev/null +++ b/src/test/ui/closures/binder/nested-closures-regions.stderr @@ -0,0 +1,38 @@ +note: external requirements + --> $DIR/nested-closures-regions.rs:8:24 + | +LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: main::{closure#0}::{closure#0} with closure substs [ + i8, + extern "rust-call" fn((&(),)), + (), + ] + = note: late-bound region is '_#4r + = note: late-bound region is '_#2r + = note: number of external vids: 3 + = note: where '_#1r: '_#2r + = note: where '_#2r: '_#1r + +note: no external requirements + --> $DIR/nested-closures-regions.rs:8:5 + | +LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; + | ^^^^^^^^^^^^^^^^ + | + = note: defining type: main::{closure#0} with closure substs [ + i8, + extern "rust-call" fn(()), + (), + ] + = note: late-bound region is '_#2r + +note: no external requirements + --> $DIR/nested-closures-regions.rs:7:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = note: defining type: main + From b2155c19204c8fb8393e0304ba5120cfb02ccf5e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 31 Oct 2022 21:18:17 +0000 Subject: [PATCH 095/482] Make external/local late-bound region registration more explicit --- .../rustc_borrowck/src/universal_regions.rs | 93 ++++++++++++++----- 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 0f300564c2086..482e10d520b76 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -251,13 +251,9 @@ impl<'tcx> UniversalRegions<'tcx> { region_mapping.push(fr); }); - for_each_late_bound_region_in_scope( - tcx, - tcx.local_parent(closure_def_id), - |r| { - region_mapping.push(r); - }, - ); + for_each_late_bound_region_in_recursive_scope(tcx, tcx.local_parent(closure_def_id), |r| { + region_mapping.push(r); + }); assert_eq!( region_mapping.len(), @@ -345,7 +341,7 @@ impl<'tcx> UniversalRegions<'tcx> { // tests, and the resulting print-outs include def-ids // and other things that are not stable across tests! // So we just include the region-vid. Annoying. - for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| { + for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); }); } @@ -359,7 +355,7 @@ impl<'tcx> UniversalRegions<'tcx> { // FIXME: As above, we'd like to print out the region // `r` but doing so is not stable across architectures // and so forth. - for_each_late_bound_region_in_scope(tcx, def_id.expect_local(), |r| { + for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| { err.note(&format!("late-bound region is {:?}", self.to_region_vid(r))); }); } @@ -430,10 +426,19 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // fn foo<'a>() { // let c = || { let x: &'a u32 = ...; } // } - self.infcx.replace_late_bound_regions_with_nll_infer_vars( + for_each_late_bound_region_in_recursive_scope( + self.infcx.tcx, self.infcx.tcx.local_parent(self.mir_def.did), - &mut indices, + |r| { + debug!(?r); + if !indices.indices.contains_key(&r) { + let region_vid = self.infcx.next_nll_region_var(FR); + debug!(?region_vid); + indices.insert_late_bound_region(r, region_vid.to_region_vid()); + } + }, ); + // Any regions created during the execution of `defining_ty` or during the above // late-bound region replacement are all considered 'extern' regions self.infcx.num_region_vars() @@ -452,7 +457,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { ); // Converse of above, if this is a function/closure then the late-bound regions declared on its // signature are local. - self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); + for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| { + debug!(?r); + if !indices.indices.contains_key(&r) { + let region_vid = self.infcx.next_nll_region_var(FR); + debug!(?region_vid); + indices.insert_late_bound_region(r, region_vid.to_region_vid()); + } + }); let (unnormalized_output_ty, mut unnormalized_input_tys) = inputs_and_output.split_last().unwrap(); @@ -695,7 +707,13 @@ trait InferCtxtExt<'tcx> { where T: TypeFoldable<'tcx>; - fn replace_late_bound_regions_with_nll_infer_vars( + fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope( + &self, + mir_def_id: LocalDefId, + indices: &mut UniversalRegionIndices<'tcx>, + ); + + fn replace_late_bound_regions_with_nll_infer_vars_in_item( &self, mir_def_id: LocalDefId, indices: &mut UniversalRegionIndices<'tcx>, @@ -749,12 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { /// set of late-bound regions and checks for any that we have not yet seen, adding them to the /// inputs vector. #[instrument(skip(self, indices))] - fn replace_late_bound_regions_with_nll_infer_vars( + fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope( &self, mir_def_id: LocalDefId, indices: &mut UniversalRegionIndices<'tcx>, ) { - for_each_late_bound_region_in_scope(self.tcx, mir_def_id, |r| { + for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| { + debug!(?r); + if !indices.indices.contains_key(&r) { + let region_vid = self.next_nll_region_var(FR); + debug!(?region_vid); + indices.insert_late_bound_region(r, region_vid.to_region_vid()); + } + }); + } + + #[instrument(skip(self, indices))] + fn replace_late_bound_regions_with_nll_infer_vars_in_item( + &self, + mir_def_id: LocalDefId, + indices: &mut UniversalRegionIndices<'tcx>, + ) { + for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = self.next_nll_region_var(FR); @@ -805,10 +839,10 @@ impl<'tcx> UniversalRegionIndices<'tcx> { } } -/// Iterates over the late-bound regions defined on fn_def_id and all of its +/// Iterates over the late-bound regions defined on `mir_def_id` and all of its /// parents, up to the typeck root, and invokes `f` with the liberated form /// of each one. -fn for_each_late_bound_region_in_scope<'tcx>( +fn for_each_late_bound_region_in_recursive_scope<'tcx>( tcx: TyCtxt<'tcx>, mut mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), @@ -817,14 +851,7 @@ fn for_each_late_bound_region_in_scope<'tcx>( // Walk up the tree, collecting late-bound regions until we hit the typeck root loop { - for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) { - let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; - let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: mir_def_id.to_def_id(), - bound_region, - })); - f(liberated_region); - } + for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f); if mir_def_id.to_def_id() == typeck_root_def_id { break; @@ -833,3 +860,19 @@ fn for_each_late_bound_region_in_scope<'tcx>( } } } + +/// Iterates over the late-bound regions defined on `mir_def_id` and all of its +/// parents, up to the typeck root, and invokes `f` with the liberated form +/// of each one. +fn for_each_late_bound_region_in_item<'tcx>( + tcx: TyCtxt<'tcx>, + mir_def_id: LocalDefId, + mut f: impl FnMut(ty::Region<'tcx>), +) { + for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) { + let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; + let liberated_region = tcx + .mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region })); + f(liberated_region); + } +} From 9baf09d02b8db6b408af8302d5566bb22e654737 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 31 Oct 2022 21:24:39 +0000 Subject: [PATCH 096/482] Add bug! back to late_bound_vars query --- compiler/rustc_borrowck/src/universal_regions.rs | 4 ++++ compiler/rustc_middle/src/ty/context.rs | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 482e10d520b76..618da9e325325 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -869,6 +869,10 @@ fn for_each_late_bound_region_in_item<'tcx>( mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { + if !tcx.def_kind(mir_def_id).is_fn_like() { + return; + } + for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) { let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; }; let liberated_region = tcx diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aa4221d11fb37..fc3b071684999 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2883,7 +2883,9 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_bound_variable_kinds( self.late_bound_vars_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) - .unwrap_or_default() + .unwrap_or_else(|| { + bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id) + }) .iter(), ) } From 06ccc1fca6b0ac882df34531bf21cf281b9515ee Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 1 Nov 2022 12:24:51 -0500 Subject: [PATCH 097/482] Add track_caller to some Lock methods --- compiler/rustc_data_structures/src/sync.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 9c0fb8265cff7..c550f246e094a 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -410,6 +410,7 @@ impl Lock { #[cfg(parallel_compiler)] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { if ERROR_CHECKING { self.0.try_lock().expect("lock was already held") @@ -420,21 +421,25 @@ impl Lock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { self.0.borrow_mut() } #[inline(always)] + #[track_caller] pub fn with_lock R, R>(&self, f: F) -> R { f(&mut *self.lock()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> LockGuard<'_, T> { self.lock() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> LockGuard<'_, T> { self.lock() } @@ -476,6 +481,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn read(&self) -> ReadGuard<'_, T> { self.0.borrow() } @@ -491,6 +497,7 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_read_lock R, R>(&self, f: F) -> R { f(&*self.read()) } @@ -509,6 +516,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn write(&self) -> WriteGuard<'_, T> { self.0.borrow_mut() } @@ -524,16 +532,19 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_write_lock R, R>(&self, f: F) -> R { f(&mut *self.write()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> WriteGuard<'_, T> { self.write() } From 7741e39d692d9e2c0550344882f14bc58c77b69e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 3 Nov 2022 18:15:24 +0100 Subject: [PATCH 098/482] Remove rustdoc clean::Visibility type --- src/librustdoc/clean/inline.rs | 5 +- src/librustdoc/clean/mod.rs | 9 +- src/librustdoc/clean/types.rs | 40 ++---- src/librustdoc/clean/utils.rs | 9 +- src/librustdoc/html/format.rs | 151 +++++++++++------------ src/librustdoc/html/render/mod.rs | 8 +- src/librustdoc/html/render/print_item.rs | 41 +++--- src/librustdoc/json/conversions.rs | 11 +- src/librustdoc/passes/stripper.rs | 8 +- 9 files changed, 129 insertions(+), 153 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ec93eefb7d1ee..841c4f9d53005 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -19,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, - clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt, - ImplKind, ItemId, Type, + clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -654,7 +653,7 @@ fn build_macro( match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) { LoadedMacro::MacroDef(item_def, _) => { if let ast::ItemKind::MacroDef(ref def) = item_def.kind { - let vis = clean_visibility(cx.tcx.visibility(import_def_id.unwrap_or(def_id))); + let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id)); clean::MacroItem(clean::Macro { source: utils::display_macro_source(cx, name, def, def_id, vis), }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c5abf42c09678..8d38f2df0d85c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1799,13 +1799,6 @@ pub(crate) fn clean_field_with_def_id( Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx) } -pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { - match vis { - ty::Visibility::Public => Visibility::Public, - ty::Visibility::Restricted(module) => Visibility::Restricted(module), - } -} - pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item { let kind = match variant.ctor_kind { CtorKind::Const => Variant::CLike(match variant.discr { @@ -1962,7 +1955,7 @@ fn clean_maybe_renamed_item<'tcx>( clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } ItemKind::Macro(ref macro_def, _) => { - let ty_vis = clean_visibility(cx.tcx.visibility(def_id)); + let ty_vis = cx.tcx.visibility(def_id); MacroItem(Macro { source: display_macro_source(cx, name, macro_def, def_id, ty_vis), }) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3a4bfc1a7405d..fea3690e50a21 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability}; use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety; use rustc_index::vec::IndexVec; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::{self, DefIdTree, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility}; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; @@ -34,7 +34,6 @@ use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; use crate::clean::cfg::Cfg; -use crate::clean::clean_visibility; use crate::clean::external_path; use crate::clean::inline::{self, print_inlined_const}; use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const}; @@ -51,7 +50,6 @@ pub(crate) use self::Type::{ Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath, RawPointer, Slice, Tuple, }; -pub(crate) use self::Visibility::{Inherited, Public}; #[cfg(test)] mod tests; @@ -703,26 +701,28 @@ impl Item { Some(header) } - pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + /// Returns the visibility of the current item. If the visibility is "inherited", then `None` + /// is returned. + pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Option> { let def_id = match self.item_id { // Anything but DefId *shouldn't* matter, but return a reasonable value anyway. - ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited, + ItemId::Auto { .. } | ItemId::Blanket { .. } => return None, // Primitives and Keywords are written in the source code as private modules. // The modules need to be private so that nobody actually uses them, but the // keywords and primitives that they are documenting are public. - ItemId::Primitive(..) => return Visibility::Public, + ItemId::Primitive(..) => return Some(Visibility::Public), ItemId::DefId(def_id) => def_id, }; match *self.kind { // Explication on `ItemId::Primitive` just above. - ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Visibility::Public, + ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public), // Variant fields inherit their enum's visibility. StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => { - return Visibility::Inherited; + return None; } // Variants always inherit visibility - VariantItem(..) => return Visibility::Inherited, + VariantItem(..) => return None, // Trait items inherit the trait's visibility AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) | TyMethodItem(..) | MethodItem(..) => { @@ -736,7 +736,7 @@ impl Item { } }; if is_trait_item { - return Visibility::Inherited; + return None; } } _ => {} @@ -745,7 +745,7 @@ impl Item { Some(inlined) => inlined, None => def_id, }; - clean_visibility(tcx.visibility(def_id)) + Some(tcx.visibility(def_id)) } } @@ -2075,24 +2075,6 @@ impl From for PrimitiveType { } } -#[derive(Copy, Clone, Debug)] -pub(crate) enum Visibility { - /// `pub` - Public, - /// Visibility inherited from parent. - /// - /// For example, this is the visibility of private items and of enum variants. - Inherited, - /// `pub(crate)`, `pub(super)`, or `pub(in path::to::somewhere)` - Restricted(DefId), -} - -impl Visibility { - pub(crate) fn is_public(&self) -> bool { - matches!(self, Visibility::Public) - } -} - #[derive(Clone, Debug)] pub(crate) struct Struct { pub(crate) struct_type: CtorKind, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 518e320235ff1..df20dc3fc3f7e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -4,9 +4,10 @@ use crate::clean::render_macro_matchers::render_macro_matcher; use crate::clean::{ clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, - PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility, + PathSegment, Primitive, PrimitiveType, Type, TypeBinding, }; use crate::core::DocContext; +use crate::html::format::visibility_to_src_with_space; use rustc_ast as ast; use rustc_ast::tokenstream::TokenTree; @@ -583,7 +584,7 @@ pub(super) fn display_macro_source( name: Symbol, def: &ast::MacroDef, def_id: DefId, - vis: Visibility, + vis: ty::Visibility, ) -> String { let tts: Vec<_> = def.body.inner_tokens().into_trees().collect(); // Extract the spans of all matchers. They represent the "interface" of the macro. @@ -595,14 +596,14 @@ pub(super) fn display_macro_source( if matchers.len() <= 1 { format!( "{}macro {}{} {{\n ...\n}}", - vis.to_src_with_space(cx.tcx, def_id), + visibility_to_src_with_space(Some(vis), cx.tcx, def_id), name, matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::(), ) } else { format!( "{}macro {} {{\n{}}}", - vis.to_src_with_space(cx.tcx, def_id), + visibility_to_src_with_space(Some(vis), cx.tcx, def_id), name, render_macro_arms(cx.tcx, matchers, ","), ) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 37202f786ed80..06db3fb0ec400 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1420,87 +1420,84 @@ impl clean::FnDecl { } } -impl clean::Visibility { - pub(crate) fn print_with_space<'a, 'tcx: 'a>( - self, - item_did: ItemId, - cx: &'a Context<'tcx>, - ) -> impl fmt::Display + 'a + Captures<'tcx> { - use std::fmt::Write as _; - - let to_print: Cow<'static, str> = match self { - clean::Public => "pub ".into(), - clean::Inherited => "".into(), - clean::Visibility::Restricted(vis_did) => { - // FIXME(camelid): This may not work correctly if `item_did` is a module. - // However, rustdoc currently never displays a module's - // visibility, so it shouldn't matter. - let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id()); - - if vis_did.is_crate_root() { - "pub(crate) ".into() - } else if parent_module == Some(vis_did) { - // `pub(in foo)` where `foo` is the parent module - // is the same as no visibility modifier - "".into() - } else if parent_module - .and_then(|parent| find_nearest_parent_module(cx.tcx(), parent)) - == Some(vis_did) - { - "pub(super) ".into() - } else { - let path = cx.tcx().def_path(vis_did); - debug!("path={:?}", path); - // modified from `resolved_path()` to work with `DefPathData` - let last_name = path.data.last().unwrap().data.get_opt_name().unwrap(); - let anchor = anchor(vis_did, last_name, cx).to_string(); - - let mut s = "pub(in ".to_owned(); - for seg in &path.data[..path.data.len() - 1] { - let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap()); - } - let _ = write!(s, "{}) ", anchor); - s.into() +pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( + visibility: Option>, + item_did: ItemId, + cx: &'a Context<'tcx>, +) -> impl fmt::Display + 'a + Captures<'tcx> { + use std::fmt::Write as _; + + let to_print: Cow<'static, str> = match visibility { + None => "".into(), + Some(ty::Visibility::Public) => "pub ".into(), + Some(ty::Visibility::Restricted(vis_did)) => { + // FIXME(camelid): This may not work correctly if `item_did` is a module. + // However, rustdoc currently never displays a module's + // visibility, so it shouldn't matter. + let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id()); + + if vis_did.is_crate_root() { + "pub(crate) ".into() + } else if parent_module == Some(vis_did) { + // `pub(in foo)` where `foo` is the parent module + // is the same as no visibility modifier + "".into() + } else if parent_module.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent)) + == Some(vis_did) + { + "pub(super) ".into() + } else { + let path = cx.tcx().def_path(vis_did); + debug!("path={:?}", path); + // modified from `resolved_path()` to work with `DefPathData` + let last_name = path.data.last().unwrap().data.get_opt_name().unwrap(); + let anchor = anchor(vis_did, last_name, cx).to_string(); + + let mut s = "pub(in ".to_owned(); + for seg in &path.data[..path.data.len() - 1] { + let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap()); } + let _ = write!(s, "{}) ", anchor); + s.into() } - }; - display_fn(move |f| write!(f, "{}", to_print)) - } + } + }; + display_fn(move |f| write!(f, "{}", to_print)) +} - /// This function is the same as print_with_space, except that it renders no links. - /// It's used for macros' rendered source view, which is syntax highlighted and cannot have - /// any HTML in it. - pub(crate) fn to_src_with_space<'a, 'tcx: 'a>( - self, - tcx: TyCtxt<'tcx>, - item_did: DefId, - ) -> impl fmt::Display + 'a + Captures<'tcx> { - let to_print = match self { - clean::Public => "pub ".to_owned(), - clean::Inherited => String::new(), - clean::Visibility::Restricted(vis_did) => { - // FIXME(camelid): This may not work correctly if `item_did` is a module. - // However, rustdoc currently never displays a module's - // visibility, so it shouldn't matter. - let parent_module = find_nearest_parent_module(tcx, item_did); - - if vis_did.is_crate_root() { - "pub(crate) ".to_owned() - } else if parent_module == Some(vis_did) { - // `pub(in foo)` where `foo` is the parent module - // is the same as no visibility modifier - String::new() - } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent)) - == Some(vis_did) - { - "pub(super) ".to_owned() - } else { - format!("pub(in {}) ", tcx.def_path_str(vis_did)) - } +/// This function is the same as print_with_space, except that it renders no links. +/// It's used for macros' rendered source view, which is syntax highlighted and cannot have +/// any HTML in it. +pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>( + visibility: Option>, + tcx: TyCtxt<'tcx>, + item_did: DefId, +) -> impl fmt::Display + 'a + Captures<'tcx> { + let to_print = match visibility { + None => String::new(), + Some(ty::Visibility::Public) => "pub ".to_owned(), + Some(ty::Visibility::Restricted(vis_did)) => { + // FIXME(camelid): This may not work correctly if `item_did` is a module. + // However, rustdoc currently never displays a module's + // visibility, so it shouldn't matter. + let parent_module = find_nearest_parent_module(tcx, item_did); + + if vis_did.is_crate_root() { + "pub(crate) ".to_owned() + } else if parent_module == Some(vis_did) { + // `pub(in foo)` where `foo` is the parent module + // is the same as no visibility modifier + String::new() + } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent)) + == Some(vis_did) + { + "pub(super) ".to_owned() + } else { + format!("pub(in {}) ", tcx.def_path_str(vis_did)) } - }; - display_fn(move |f| f.write_str(&to_print)) - } + } + }; + display_fn(move |f| f.write_str(&to_print)) } pub(crate) trait PrintWithSpace { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index adf501a024031..3a041ae15d618 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -70,8 +70,8 @@ use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{ href, join_with_double_colon, print_abi_with_space, print_constness_with_space, - print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError, - PrintWithSpace, + print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space, + Buffer, Ending, HrefError, PrintWithSpace, }; use crate::html::highlight; use crate::html::markdown::{ @@ -752,7 +752,7 @@ fn assoc_const( w, "{extra}{vis}const {name}: {ty}", extra = extra, - vis = it.visibility(tcx).print_with_space(it.item_id, cx), + vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), ty = ty.print(cx), @@ -809,7 +809,7 @@ fn assoc_method( let tcx = cx.tcx(); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let vis = meth.visibility(tcx).print_with_space(meth.item_id, cx).to_string(); + let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. let constness = match render_mode { diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 13df08280b5a8..3225ddabe2e75 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::middle::stability; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{Adt, TyCtxt}; +use rustc_middle::ty::{self, Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants}; @@ -28,7 +28,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{ join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause, - Buffer, Ending, PrintWithSpace, + visibility_print_with_space, Buffer, Ending, PrintWithSpace, }; use crate::html::highlight; use crate::html::layout::Page; @@ -328,14 +328,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: Some(src) => write!( w, "
{}extern crate {} as {};", - myitem.visibility(tcx).print_with_space(myitem.item_id, cx), + visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), src, cx), myitem.name.unwrap(), ), None => write!( w, "
{}extern crate {};", - myitem.visibility(tcx).print_with_space(myitem.item_id, cx), + visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), ), } @@ -385,7 +385,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
\ {stab_tags_before}{stab_tags}{stab_tags_after}", stab = stab.unwrap_or_default(), - vis = myitem.visibility(tcx).print_with_space(myitem.item_id, cx), + vis = visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx), imp = import.print(cx), ); w.write_str(ITEM_TABLE_ROW_CLOSE); @@ -410,7 +410,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: let add = if stab.is_some() { " " } else { "" }; let visibility_emoji = match myitem.visibility(tcx) { - clean::Visibility::Restricted(_) => { + Some(ty::Visibility::Restricted(_)) => { " 🔒 " } _ => "", @@ -503,7 +503,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle let unsafety = header.unsafety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); - let visibility = it.visibility(tcx).print_with_space(it.item_id, cx).to_string(); + let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string(); let name = it.name.unwrap(); let generics_len = format!("{:#}", f.generics.print(cx)).len(); @@ -561,7 +561,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: write!( w, "{}{}{}trait {}{}{}", - it.visibility(tcx).print_with_space(it.item_id, cx), + visibility_print_with_space(it.visibility(tcx), it.item_id, cx), t.unsafety(tcx).print_with_space(), if t.is_auto(tcx) { "auto " } else { "" }, it.name.unwrap(), @@ -1086,7 +1086,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); - write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.item_id, cx)); + write!(w, "{}", visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx)); write!( w, "type {}{}{where_clause} = {type_};", @@ -1183,7 +1183,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!( w, "{}enum {}{}", - it.visibility(tcx).print_with_space(it.item_id, cx), + visibility_print_with_space(it.visibility(tcx), it.item_id, cx), it.name.unwrap(), e.generics.print(cx), ); @@ -1398,7 +1398,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle write!( w, "{vis}const {name}: {typ}", - vis = it.visibility(tcx).print_with_space(it.item_id, cx), + vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), name = it.name.unwrap(), typ = c.type_.print(cx), ); @@ -1499,7 +1499,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean write!( w, "{vis}static {mutability}{name}: {typ}", - vis = it.visibility(cx.tcx()).print_with_space(it.item_id, cx), + vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) @@ -1517,7 +1517,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { write!( w, " {}type {};\n}}", - it.visibility(cx.tcx()).print_with_space(it.item_id, cx), + visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), it.name.unwrap(), ); }); @@ -1671,7 +1671,12 @@ fn render_union( cx: &Context<'_>, ) { let tcx = cx.tcx(); - write!(w, "{}union {}", it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(),); + write!( + w, + "{}union {}", + visibility_print_with_space(it.visibility(tcx), it.item_id, cx), + it.name.unwrap(), + ); let where_displayed = g .map(|g| { @@ -1698,7 +1703,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility(tcx).print_with_space(field.item_id, cx), + visibility_print_with_space(field.visibility(tcx), field.item_id, cx), field.name.unwrap(), ty.print(cx), tab @@ -1729,7 +1734,7 @@ fn render_struct( write!( w, "{}{}{}", - it.visibility(tcx).print_with_space(it.item_id, cx), + visibility_print_with_space(it.visibility(tcx), it.item_id, cx), if structhead { "struct " } else { "" }, it.name.unwrap() ); @@ -1759,7 +1764,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility(tcx).print_with_space(field.item_id, cx), + visibility_print_with_space(field.visibility(tcx), field.item_id, cx), field.name.unwrap(), ty.print(cx), ); @@ -1791,7 +1796,7 @@ fn render_struct( write!( w, "{}{}", - field.visibility(tcx).print_with_space(field.item_id, cx), + visibility_print_with_space(field.visibility(tcx), field.item_id, cx), ty.print(cx), ) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 4889ac25acb84..cb8b7c18029f0 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -100,13 +100,12 @@ impl JsonRenderer<'_> { } } - fn convert_visibility(&self, v: clean::Visibility) -> Visibility { - use clean::Visibility::*; + fn convert_visibility(&self, v: Option>) -> Visibility { match v { - Public => Visibility::Public, - Inherited => Visibility::Default, - Restricted(did) if did.is_crate_root() => Visibility::Crate, - Restricted(did) => Visibility::Restricted { + None => Visibility::Default, + Some(ty::Visibility::Public) => Visibility::Public, + Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate, + Some(ty::Visibility::Restricted(did)) => Visibility::Restricted { parent: from_item_id(did.into(), self.tcx), path: self.tcx.def_path(did).to_string_no_crate_verbose(), }, diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index b2047360ccd9a..995fb5dcc1c86 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -1,6 +1,6 @@ //! A collection of utility functions for the `strip_*` passes. use rustc_hir::def_id::DefId; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{TyCtxt, Visibility}; use rustc_span::symbol::sym; use std::mem; @@ -81,13 +81,13 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { } clean::StructFieldItem(..) => { - if !i.visibility(self.tcx).is_public() { + if i.visibility(self.tcx) != Some(Visibility::Public) { return Some(strip_item(i)); } } clean::ModuleItem(..) => { - if i.item_id.is_local() && !i.visibility(self.tcx).is_public() { + if i.item_id.is_local() && i.visibility(self.tcx) != Some(Visibility::Public) { debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = strip_item(self.fold_item_recur(i)); @@ -246,7 +246,7 @@ impl<'tcx> DocFolder for ImportStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { clean::ExternCrateItem { .. } | clean::ImportItem(..) - if !i.visibility(self.tcx).is_public() => + if i.visibility(self.tcx) != Some(Visibility::Public) => { None } From b7eb4fbfb2c69a92e226ce1ea29a06d208b09b64 Mon Sep 17 00:00:00 2001 From: Douwe Schulte Date: Thu, 3 Nov 2022 21:19:02 +0000 Subject: [PATCH 099/482] Fixed typos Fixed a typo that has been found on two locations in comments. --- library/alloc/src/vec/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index bbbdc3aa2a2d3..834c8f58cb2a9 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2588,7 +2588,7 @@ impl ExtendFromWithinSpec for Vec { let (this, spare, len) = unsafe { self.split_at_spare_mut_with_len() }; // SAFETY: - // - caller guaratees that src is a valid index + // - caller guarantees that src is a valid index let to_clone = unsafe { this.get_unchecked(src) }; iter::zip(to_clone, spare) @@ -2607,7 +2607,7 @@ impl ExtendFromWithinSpec for Vec { let (init, spare) = self.split_at_spare_mut(); // SAFETY: - // - caller guaratees that `src` is a valid index + // - caller guarantees that `src` is a valid index let source = unsafe { init.get_unchecked(src) }; // SAFETY: From aab436b329c7853dadd00aee7c8f294c59ece8b8 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Fri, 4 Nov 2022 03:08:28 +0000 Subject: [PATCH 100/482] Fix ICE when negative impl is collected during eager mono --- compiler/rustc_monomorphize/src/collector.rs | 4 ++++ src/test/ui/traits/negative-impls/eager-mono.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/test/ui/traits/negative-impls/eager-mono.rs diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 3cfddd75462c0..58ddb807059ae 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1336,6 +1336,10 @@ fn create_mono_items_for_default_impls<'tcx>( ) { match item.kind { hir::ItemKind::Impl(ref impl_) => { + if matches!(impl_.polarity, hir::ImplPolarity::Negative(_)) { + return; + } + for param in impl_.generics.params { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} diff --git a/src/test/ui/traits/negative-impls/eager-mono.rs b/src/test/ui/traits/negative-impls/eager-mono.rs new file mode 100644 index 0000000000000..ce770376c0b2f --- /dev/null +++ b/src/test/ui/traits/negative-impls/eager-mono.rs @@ -0,0 +1,12 @@ +// build-pass +// compile-flags:-C link-dead-code=y + +#![feature(negative_impls)] + +trait Foo { + fn foo() {} +} + +impl !Foo for () {} + +fn main() {} From 34c4f19eec02bce0e1405b814008cbce6eab978b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 4 Nov 2022 13:59:04 +0900 Subject: [PATCH 101/482] remove unused argument from `throw_unresolved_import_error` --- compiler/rustc_resolve/src/imports.rs | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index bdb852548b84e..4c899a5ff2d7e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -473,7 +473,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { { // In the case of a new import line, throw a diagnostic message // for the previous line. - self.throw_unresolved_import_error(errors, None); + self.throw_unresolved_import_error(errors); errors = vec![]; } if seen_spans.insert(err.span) { @@ -505,29 +505,21 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !errors.is_empty() { - self.throw_unresolved_import_error(errors, None); + self.throw_unresolved_import_error(errors); } } - fn throw_unresolved_import_error( - &self, - errors: Vec<(String, UnresolvedImportError)>, - span: Option, - ) { + fn throw_unresolved_import_error(&self, errors: Vec<(String, UnresolvedImportError)>) { + if errors.is_empty() { + return; + } + /// Upper limit on the number of `span_label` messages. const MAX_LABEL_COUNT: usize = 10; - let (span, msg) = if errors.is_empty() { - (span.unwrap(), "unresolved import".to_string()) - } else { - let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect()); - - let paths = errors.iter().map(|(path, _)| format!("`{}`", path)).collect::>(); - - let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),); - - (span, msg) - }; + let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect()); + let paths = errors.iter().map(|(path, _)| format!("`{}`", path)).collect::>(); + let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),); let mut diag = struct_span_err!(self.r.session, span, E0432, "{}", &msg); From dcedd599edfea8e39ce4da8894bd6a69c887fb7e Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 11 Sep 2022 18:02:54 -0400 Subject: [PATCH 102/482] Add QEMU test for x86_64-unknown-uefi The UEFI targets don't have std support yet, so the normal tests don't work. However, we can compile a simple no-std program and run it under QEMU to at least check that the target compiles, links, and runs. Tested locally with: src/ci/docker/run.sh test-various --- .../host-x86_64/test-various/Dockerfile | 11 ++- .../test-various/uefi_qemu_test/Cargo.toml | 9 ++ .../test-various/uefi_qemu_test/run.py | 96 +++++++++++++++++++ .../test-various/uefi_qemu_test/src/main.rs | 45 +++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml create mode 100644 src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py create mode 100644 src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index b75e2f085cd3b..b0f35bcb9ccf5 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -16,7 +16,9 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins pkg-config \ xz-utils \ wget \ - patch + patch \ + ovmf \ + qemu-system-x86 RUN curl -sL https://nodejs.org/dist/v15.14.0/node-v15.14.0-linux-x64.tar.xz | \ tar -xJ @@ -64,4 +66,9 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS -ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT +COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test +ENV UEFI_TARGETS=x86_64-unknown-uefi +ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \ + python3 -u /uefi_qemu_test/run.py + +ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml new file mode 100644 index 0000000000000..fa8e5b3d08060 --- /dev/null +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "uefi_qemu_test" +version = "0.0.0" +edition = "2021" + +[workspace] + +[dependencies] +r-efi = "4.1.0" diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py new file mode 100644 index 0000000000000..46793ce3afa15 --- /dev/null +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +import os +import shutil +import subprocess +import sys +import tempfile + +from pathlib import Path + + +def run(*cmd, capture=False, check=True, env=None): + """Print and run a command, optionally capturing the output.""" + cmd = [str(p) for p in cmd] + print(' '.join(cmd)) + return subprocess.run(cmd, + capture_output=capture, + check=check, + env=env, + text=True) + + +def build_and_run(tmp_dir): + host_artifacts = Path('/checkout/obj/build/x86_64-unknown-linux-gnu') + stage0 = host_artifacts / 'stage0/bin' + stage2 = host_artifacts / 'stage2/bin' + + env = dict(os.environ) + env['PATH'] = '{}:{}:{}'.format(stage2, stage0, env['PATH']) + + # Copy the test create into `tmp_dir`. + test_crate = Path(tmp_dir) / 'uefi_qemu_test' + shutil.copytree('/uefi_qemu_test', test_crate) + + # Build the UEFI executable. + target = 'x86_64-unknown-uefi' + run('cargo', + 'build', + '--manifest-path', + test_crate / 'Cargo.toml', + '--target', + target, + env=env) + + # Create a mock EFI System Partition in a subdirectory. + esp = test_crate / 'esp' + boot = esp / 'efi/boot' + os.makedirs(boot, exist_ok=True) + + # Copy the executable into the ESP. + src_exe_path = test_crate / 'target' / target / 'debug/uefi_qemu_test.efi' + shutil.copy(src_exe_path, boot / 'bootx64.efi') + + # Run the executable in QEMU and capture the output. + qemu = 'qemu-system-x86_64' + ovmf_dir = Path('/usr/share/OVMF') + ovmf_code = ovmf_dir / 'OVMF_CODE.fd' + ovmf_vars = ovmf_dir / 'OVMF_VARS.fd' + output = run(qemu, + '-display', + 'none', + '-serial', + 'stdio', + '-drive', + f'if=pflash,format=raw,readonly=on,file={ovmf_code}', + '-drive', + f'if=pflash,format=raw,readonly=on,file={ovmf_vars}', + '-drive', + f'format=raw,file=fat:rw:{esp}', + capture=True, + # Ubuntu 20.04 (which is what the Dockerfile currently + # uses) provides QEMU 4.2.1, which segfaults on + # shutdown under some circumstances. That has been + # fixed in newer versions of QEMU, but for now just + # don't check the exit status. + check=False).stdout + + if 'Hello World!' in output: + print('VM produced expected output') + else: + print('unexpected VM output:') + print('---start---') + print(output) + print('---end---') + sys.exit(1) + + +def main(): + # Create a temporary directory so that we have a writeable + # workspace. + with tempfile.TemporaryDirectory() as tmp_dir: + build_and_run(tmp_dir) + + +if __name__ == "__main__": + main() diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs new file mode 100644 index 0000000000000..2ec554c140b59 --- /dev/null +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs @@ -0,0 +1,45 @@ +// Code is adapted from this hello world example: +// https://doc.rust-lang.org/nightly/rustc/platform-support/unknown-uefi.html + +#![no_main] +#![no_std] + +use core::{panic, ptr}; +use r_efi::efi::{Char16, Handle, Status, SystemTable, RESET_SHUTDOWN}; + +#[panic_handler] +fn panic_handler(_info: &panic::PanicInfo) -> ! { + loop {} +} + +#[export_name = "efi_main"] +pub extern "C" fn main(_h: Handle, st: *mut SystemTable) -> Status { + let s = [ + 0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello" + 0x0020u16, // " " + 0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World" + 0x0021u16, // "!" + 0x000au16, // "\n" + 0x0000u16, // NUL + ]; + + // Print "Hello World!". + let r = unsafe { ((*(*st).con_out).output_string)((*st).con_out, s.as_ptr() as *mut Char16) }; + if r.is_error() { + return r; + } + + // Shut down. + unsafe { + ((*((*st).runtime_services)).reset_system)( + RESET_SHUTDOWN, + Status::SUCCESS, + 0, + ptr::null_mut(), + ); + } + + // This should never be reached because `reset_system` should never + // return, so fail with an error if we get here. + Status::UNSUPPORTED +} From c372a3710a6a1cff1547382cb5b731513d5d70ee Mon Sep 17 00:00:00 2001 From: Collin Baker Date: Fri, 21 Oct 2022 14:38:56 -0400 Subject: [PATCH 103/482] Remove std's transitive dependency on cfg-if 0.1 After rust-lang/rust#101946 this completes the move to cfg-if 1.0 by: * Updating getrandom 0.1.14->0.1.16 * Updating panic_abort, panic_unwind, and unwind to cfg-if 1.0 --- Cargo.lock | 16 ++++++++-------- library/panic_abort/Cargo.toml | 2 +- library/panic_unwind/Cargo.toml | 2 +- library/unwind/Cargo.toml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a91898be4e3f..075c5d4404621 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1526,11 +1526,11 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -2478,7 +2478,7 @@ name = "panic_abort" version = "0.0.0" dependencies = [ "alloc", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "compiler_builtins", "core", "libc", @@ -2489,7 +2489,7 @@ name = "panic_unwind" version = "0.0.0" dependencies = [ "alloc", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "compiler_builtins", "core", "libc", @@ -2817,7 +2817,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14", + "getrandom 0.1.16", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -2861,7 +2861,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14", + "getrandom 0.1.16", ] [[package]] @@ -5357,7 +5357,7 @@ name = "unwind" version = "0.0.0" dependencies = [ "cc", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "compiler_builtins", "core", "libc", diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml index 46183d1ad0066..e6ea2b1849b4c 100644 --- a/library/panic_abort/Cargo.toml +++ b/library/panic_abort/Cargo.toml @@ -13,7 +13,7 @@ doc = false [dependencies] alloc = { path = "../alloc" } -cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] } +cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } core = { path = "../core" } libc = { version = "0.2", default-features = false } compiler_builtins = "0.1.0" diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml index d720cc7bcbdf1..85386976d639a 100644 --- a/library/panic_unwind/Cargo.toml +++ b/library/panic_unwind/Cargo.toml @@ -17,4 +17,4 @@ core = { path = "../core" } libc = { version = "0.2", default-features = false } unwind = { path = "../unwind" } compiler_builtins = "0.1.0" -cfg-if = "0.1.8" +cfg-if = "1.0" diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 69fce8d7795c1..32c4a7eb5c18c 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -17,7 +17,7 @@ doc = false core = { path = "../core" } libc = { version = "0.2.79", features = ['rustc-dep-of-std'], default-features = false } compiler_builtins = "0.1.0" -cfg-if = "0.1.8" +cfg-if = "1.0" [build-dependencies] cc = "1.0.69" From d5c3d57cd97cde8196d4f12328751b4a028b356c Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 22 Oct 2022 18:48:20 +0800 Subject: [PATCH 104/482] Port `dead_code` lints to be translatable. --- .../locales/en-US/passes.ftl | 34 ++++ compiler/rustc_errors/src/diagnostic_impls.rs | 32 ++++ compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_passes/src/dead.rs | 175 +++++++++--------- compiler/rustc_passes/src/errors.rs | 80 +++++++- ...lone-debug-dead-code-in-the-same-struct.rs | 2 +- ...-debug-dead-code-in-the-same-struct.stderr | 2 +- .../multiple-dead-codes-in-the-same-struct.rs | 2 +- ...tiple-dead-codes-in-the-same-struct.stderr | 2 +- .../ui/lint/dead-code/tuple-struct-field.rs | 2 +- .../lint/dead-code/tuple-struct-field.stderr | 2 +- 11 files changed, 236 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index bc5bfe2a24448..2189e4d16b703 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -665,3 +665,37 @@ passes_missing_const_err = attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` .help = make the function or method const .label = attribute specified here + +passes_dead_codes = + { $multiple -> + *[true] multiple {$descr}s are + [false] { $num -> + [one] {$descr} {$name_list} is + *[other] {$descr}s {$name_list} are + } + } never {$participle} + +passes_change_fields_to_be_of_unit_type = + consider changing the { $num -> + [one] field + *[other] fields + } to be of unit type to suppress this warning + while preserving the field numbering, or remove the { $num -> + [one] field + *[other] fields + } + +passes_parent_info = + {$num -> + [one] {$descr} + *[other] {$descr}s + } in this {$parent_descr} + +passes_ignored_derived_impls = + `{$name}` has {$trait_list_len -> + [one] a derived impl + *[other] derived impls + } for the {$trait_list_len -> + [one] trait {$trait_list}, but this is + *[other] traits {$trait_list}, but these are + } intentionally ignored during dead code analysis diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 7640b2919f78b..f6fe9192b45ca 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -11,6 +11,7 @@ use rustc_target::abi::TargetDataLayoutErrors; use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; use std::borrow::Cow; use std::fmt; +use std::fmt::Write; use std::num::ParseIntError; use std::path::{Path, PathBuf}; @@ -170,6 +171,37 @@ impl IntoDiagnosticArg for Level { } } +#[derive(Clone)] +pub struct DiagnosticSymbolList(Vec); + +impl From> for DiagnosticSymbolList { + fn from(v: Vec) -> Self { + DiagnosticSymbolList(v) + } +} + +impl IntoDiagnosticArg for DiagnosticSymbolList { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + // FIXME: replace the logic here with a real list formatter + let symbols = match &self.0[..] { + [symbol] => format!("`{symbol}`"), + [symbol, last] => { + format!("`{symbol}` and `{last}`",) + } + [symbols @ .., last] => { + let mut result = String::new(); + for symbol in symbols { + write!(result, "`{symbol}`, ").unwrap(); + } + write!(result, "and `{last}`").unwrap(); + result + } + [] => unreachable!(), + }; + DiagnosticArgValue::Str(Cow::Owned(symbols)) + } +} + impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> { fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { let mut diag; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f390495b53de4..a8fd1a17a5110 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -376,7 +376,7 @@ pub use diagnostic::{ DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, }; pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted}; -pub use diagnostic_impls::DiagnosticArgFromDisplay; +pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList}; use std::backtrace::Backtrace; /// A handler deals with errors and other compiler output. diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index b779edbc30f75..21b487d8ca1e7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, MultiSpan}; +use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -18,7 +18,10 @@ use rustc_session::lint; use rustc_span::symbol::{sym, Symbol}; use std::mem; -use crate::errors::UselessAssignment; +use crate::errors::{ + ChangeFieldsToBeOfUnitType, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, + UselessAssignment, +}; // Any local node that may call something in its body block should be // explored. For example, if it's a live Node::Item that is a @@ -693,99 +696,89 @@ impl<'tcx> DeadVisitor<'tcx> { parent_item: Option, is_positional: bool, ) { - if let Some(&first_id) = dead_codes.first() { - let tcx = self.tcx; - let names: Vec<_> = dead_codes - .iter() - .map(|&def_id| tcx.item_name(def_id.to_def_id()).to_string()) - .collect(); - let spans: Vec<_> = dead_codes - .iter() - .map(|&def_id| match tcx.def_ident_span(def_id) { - Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()), - None => tcx.def_span(def_id), + let Some(&first_id) = dead_codes.first() else { + return; + }; + let tcx = self.tcx; + let names: Vec<_> = + dead_codes.iter().map(|&def_id| tcx.item_name(def_id.to_def_id())).collect(); + let spans: Vec<_> = dead_codes + .iter() + .map(|&def_id| match tcx.def_ident_span(def_id) { + Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()), + None => tcx.def_span(def_id), + }) + .collect(); + + let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); + let num = dead_codes.len(); + let multiple = num > 6; + let name_list = names.into(); + + let lint = if is_positional { + lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS + } else { + lint::builtin::DEAD_CODE + }; + + let parent_info = if let Some(parent_item) = parent_item { + let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id()); + Some(ParentInfo { + num, + descr, + parent_descr, + span: tcx.def_ident_span(parent_item).unwrap(), + }) + } else { + None + }; + + let encl_def_id = parent_item.unwrap_or(first_id); + let ignored_derived_impls = + if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { + let trait_list = ign_traits + .iter() + .map(|(trait_id, _)| self.tcx.item_name(*trait_id)) + .collect::>(); + let trait_list_len = trait_list.len(); + Some(IgnoredDerivedImpls { + name: self.tcx.item_name(encl_def_id.to_def_id()), + trait_list: trait_list.into(), + trait_list_len, }) - .collect(); - - let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); - let span_len = dead_codes.len(); - let names = match &names[..] { - _ if span_len > 6 => String::new(), - [name] => format!("`{name}` "), - [names @ .., last] => { - format!( - "{} and `{last}` ", - names.iter().map(|name| format!("`{name}`")).join(", ") - ) - } - [] => unreachable!(), + } else { + None }; - let msg = format!( - "{these}{descr}{s} {names}{are} never {participle}", - these = if span_len > 6 { "multiple " } else { "" }, - s = pluralize!(span_len), - are = pluralize!("is", span_len), - ); - - tcx.struct_span_lint_hir( - if is_positional { - lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS - } else { - lint::builtin::DEAD_CODE - }, - tcx.hir().local_def_id_to_hir_id(first_id), - MultiSpan::from_spans(spans.clone()), - msg, - |err| { - if is_positional { - err.multipart_suggestion( - &format!( - "consider changing the field{s} to be of unit type to \ - suppress this warning while preserving the field \ - numbering, or remove the field{s}", - s = pluralize!(span_len) - ), - spans.iter().map(|sp| (*sp, "()".to_string())).collect(), - // "HasPlaceholders" because applying this fix by itself isn't - // enough: All constructor calls have to be adjusted as well - Applicability::HasPlaceholders, - ); - } - if let Some(parent_item) = parent_item { - let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id()); - err.span_label( - tcx.def_ident_span(parent_item).unwrap(), - format!("{descr}{s} in this {parent_descr}", s = pluralize!(span_len)), - ); - } + let diag = if is_positional { + MultipleDeadCodes::UnusedTupleStructFields { + multiple, + num, + descr, + participle, + name_list, + change_fields_suggestion: ChangeFieldsToBeOfUnitType { num, spans: spans.clone() }, + parent_info, + ignored_derived_impls, + } + } else { + MultipleDeadCodes::DeadCodes { + multiple, + num, + descr, + participle, + name_list, + parent_info, + ignored_derived_impls, + } + }; - let encl_def_id = parent_item.unwrap_or(first_id); - if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { - let traits_str = ign_traits - .iter() - .map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id))) - .collect::>() - .join(" and "); - let plural_s = pluralize!(ign_traits.len()); - let article = if ign_traits.len() > 1 { "" } else { "a " }; - let is_are = if ign_traits.len() > 1 { "these are" } else { "this is" }; - let msg = format!( - "`{}` has {}derived impl{} for the trait{} {}, but {} \ - intentionally ignored during dead code analysis", - self.tcx.item_name(encl_def_id.to_def_id()), - article, - plural_s, - plural_s, - traits_str, - is_are - ); - err.note(&msg); - } - err - }, - ); - } + self.tcx.emit_spanned_lint( + lint, + tcx.hir().local_def_id_to_hir_id(first_id), + MultiSpan::from_spans(spans.clone()), + diag, + ); } fn warn_dead_fields_and_variants( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index fb883ae2ed0a7..d019bf64a27d1 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,12 +4,16 @@ use std::{ }; use rustc_ast::Label; -use rustc_errors::{error_code, Applicability, ErrorGuaranteed, IntoDiagnostic, MultiSpan}; +use rustc_errors::{ + error_code, Applicability, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan, +}; use rustc_hir::{self as hir, ExprKind, Target}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_errors::{pluralize, AddToDiagnostic, Diagnostic, SubdiagnosticMessage}; + use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] @@ -1446,3 +1450,77 @@ pub struct MissingConstErr { #[label] pub const_span: Span, } + +#[derive(LintDiagnostic)] +pub enum MultipleDeadCodes<'tcx> { + #[diag(passes_dead_codes)] + DeadCodes { + multiple: bool, + num: usize, + descr: &'tcx str, + participle: &'tcx str, + name_list: DiagnosticSymbolList, + #[subdiagnostic] + parent_info: Option>, + #[subdiagnostic] + ignored_derived_impls: Option, + }, + #[diag(passes_dead_codes)] + UnusedTupleStructFields { + multiple: bool, + num: usize, + descr: &'tcx str, + participle: &'tcx str, + name_list: DiagnosticSymbolList, + #[subdiagnostic] + change_fields_suggestion: ChangeFieldsToBeOfUnitType, + #[subdiagnostic] + parent_info: Option>, + #[subdiagnostic] + ignored_derived_impls: Option, + }, +} + +#[derive(Subdiagnostic)] +#[label(passes_parent_info)] +pub struct ParentInfo<'tcx> { + pub num: usize, + pub descr: &'tcx str, + pub parent_descr: &'tcx str, + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[note(passes_ignored_derived_impls)] +pub struct IgnoredDerivedImpls { + pub name: Symbol, + pub trait_list: DiagnosticSymbolList, + pub trait_list_len: usize, +} + +pub struct ChangeFieldsToBeOfUnitType { + pub num: usize, + pub spans: Vec, +} + +// FIXME: Replace this impl with a derive. +impl AddToDiagnostic for ChangeFieldsToBeOfUnitType { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + diag.multipart_suggestion( + &format!( + "consider changing the field{s} to be of unit type to \ + suppress this warning while preserving the field \ + numbering, or remove the field{s}", + s = pluralize!(self.num) + ), + self.spans.iter().map(|sp| (*sp, "()".to_string())).collect(), + // "HasPlaceholders" because applying this fix by itself isn't + // enough: All constructor calls have to be adjusted as well + Applicability::HasPlaceholders, + ); + } +} diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs index 15d06817577ea..6ab1fb7b039bd 100644 --- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs +++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs @@ -3,7 +3,7 @@ #[derive(Debug)] pub struct Whatever { pub field0: (), - field1: (), //~ ERROR fields `field1`, `field2`, `field3` and `field4` are never read + field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read field2: (), field3: (), field4: (), diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr index 512b870fa4b6c..7f4f78cebc918 100644 --- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr +++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr @@ -1,4 +1,4 @@ -error: fields `field1`, `field2`, `field3` and `field4` are never read +error: fields `field1`, `field2`, `field3`, and `field4` are never read --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5 | LL | pub struct Whatever { diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs index e3935cf9149bb..2003e1e293a58 100644 --- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs +++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs @@ -7,7 +7,7 @@ struct Bar { b: usize, //~ ERROR field `b` is never read #[deny(dead_code)] c: usize, //~ ERROR fields `c` and `e` are never read - d: usize, //~ WARN fields `d`, `f` and `g` are never read + d: usize, //~ WARN fields `d`, `f`, and `g` are never read #[deny(dead_code)] e: usize, f: usize, diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr index c0f1ed38f6de3..0e5c78a716797 100644 --- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr +++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr @@ -1,4 +1,4 @@ -warning: fields `d`, `f` and `g` are never read +warning: fields `d`, `f`, and `g` are never read --> $DIR/multiple-dead-codes-in-the-same-struct.rs:10:5 | LL | struct Bar { diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs index b15d706368633..14fb30be949dc 100644 --- a/src/test/ui/lint/dead-code/tuple-struct-field.rs +++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs @@ -11,7 +11,7 @@ struct SingleUnused(i32, [u8; LEN], String); //~| HELP: consider changing the field to be of unit type struct MultipleUnused(i32, f32, String, u8); -//~^ ERROR: fields `0`, `1`, `2` and `3` are never read +//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read //~| NOTE: fields in this struct //~| HELP: consider changing the fields to be of unit type diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.stderr b/src/test/ui/lint/dead-code/tuple-struct-field.stderr index ca0989f5b987f..b8ad5cbe4e977 100644 --- a/src/test/ui/lint/dead-code/tuple-struct-field.stderr +++ b/src/test/ui/lint/dead-code/tuple-struct-field.stderr @@ -16,7 +16,7 @@ help: consider changing the field to be of unit type to suppress this warning wh LL | struct SingleUnused(i32, (), String); | ~~ -error: fields `0`, `1`, `2` and `3` are never read +error: fields `0`, `1`, `2`, and `3` are never read --> $DIR/tuple-struct-field.rs:13:23 | LL | struct MultipleUnused(i32, f32, String, u8); From 6467ad87721a6982d050ef45652a014e45db2a30 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Fri, 4 Nov 2022 03:02:09 +0800 Subject: [PATCH 105/482] Use `derive(Subdiagnostic)` for `ChangeFieldsToBeOfUnitType`. --- .../locales/en-US/passes.ftl | 3 +-- compiler/rustc_passes/src/errors.rs | 26 +++---------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 2189e4d16b703..88286c15f9ea4 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -679,8 +679,7 @@ passes_change_fields_to_be_of_unit_type = consider changing the { $num -> [one] field *[other] fields - } to be of unit type to suppress this warning - while preserving the field numbering, or remove the { $num -> + } to be of unit type to suppress this warning while preserving the field numbering, or remove the { $num -> [one] field *[other] fields } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index d019bf64a27d1..d8bed700f520a 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -12,8 +12,6 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{Span, Symbol, DUMMY_SP}; -use rustc_errors::{pluralize, AddToDiagnostic, Diagnostic, SubdiagnosticMessage}; - use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] @@ -1499,28 +1497,10 @@ pub struct IgnoredDerivedImpls { pub trait_list_len: usize, } +#[derive(Subdiagnostic)] +#[multipart_suggestion(passes_change_fields_to_be_of_unit_type, applicability = "has-placeholders")] pub struct ChangeFieldsToBeOfUnitType { pub num: usize, + #[suggestion_part(code = "()")] pub spans: Vec, } - -// FIXME: Replace this impl with a derive. -impl AddToDiagnostic for ChangeFieldsToBeOfUnitType { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { - diag.multipart_suggestion( - &format!( - "consider changing the field{s} to be of unit type to \ - suppress this warning while preserving the field \ - numbering, or remove the field{s}", - s = pluralize!(self.num) - ), - self.spans.iter().map(|sp| (*sp, "()".to_string())).collect(), - // "HasPlaceholders" because applying this fix by itself isn't - // enough: All constructor calls have to be adjusted as well - Applicability::HasPlaceholders, - ); - } -} From d834f49fd4de0266ea768e36c4fb7c0346cb5db4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Oct 2022 11:22:33 +0200 Subject: [PATCH 106/482] libtest: run all tests in their own thread, if supported by the host --- library/test/src/lib.rs | 58 +++++++++---------- library/test/src/options.rs | 7 --- library/test/src/tests.rs | 26 +++------ .../libtest-json/output-default.json | 2 +- .../libtest-json/output-stdout-success.json | 4 +- .../test-attrs/test-thread-capture.run.stdout | 2 +- .../test-thread-nocapture.run.stderr | 2 +- 7 files changed, 42 insertions(+), 59 deletions(-) diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index f16d94bbc81c3..27320e8dbc5ad 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -40,7 +40,7 @@ pub mod test { cli::{parse_opts, TestOpts}, filter_tests, helpers::metrics::{Metric, MetricMap}, - options::{Concurrent, Options, RunIgnored, RunStrategy, ShouldPanic}, + options::{Options, RunIgnored, RunStrategy, ShouldPanic}, run_test, test_main, test_main_static, test_result::{TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}, time::{TestExecTime, TestTimeOptions}, @@ -85,7 +85,7 @@ use event::{CompletedTest, TestEvent}; use helpers::concurrency::get_concurrency; use helpers::exit_code::get_exit_code; use helpers::shuffle::{get_shuffle_seed, shuffle_tests}; -use options::{Concurrent, RunStrategy}; +use options::RunStrategy; use test_result::*; use time::TestExecTime; @@ -267,6 +267,19 @@ where join_handle: Option>, } + impl RunningTest { + fn join(self, completed_test: &mut CompletedTest) { + if let Some(join_handle) = self.join_handle { + if let Err(_) = join_handle.join() { + if let TrOk = completed_test.result { + completed_test.result = + TrFailedMsg("panicked after reporting success".to_string()); + } + } + } + } + } + // Use a deterministic hasher type TestMap = HashMap>; @@ -366,10 +379,10 @@ where let (id, test) = remaining.pop_front().unwrap(); let event = TestEvent::TeWait(test.desc.clone()); notify_about_test_event(event)?; - let join_handle = - run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone(), Concurrent::No); - assert!(join_handle.is_none()); - let completed_test = rx.recv().unwrap(); + let join_handle = run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone()); + // Wait for the test to complete. + let mut completed_test = rx.recv().unwrap(); + RunningTest { join_handle }.join(&mut completed_test); let event = TestEvent::TeResult(completed_test); notify_about_test_event(event)?; @@ -383,15 +396,8 @@ where let event = TestEvent::TeWait(desc.clone()); notify_about_test_event(event)?; //here no pad - let join_handle = run_test( - opts, - !opts.run_tests, - id, - test, - run_strategy, - tx.clone(), - Concurrent::Yes, - ); + let join_handle = + run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone()); running_tests.insert(id, RunningTest { join_handle }); timeout_queue.push_back(TimeoutEntry { id, desc, timeout }); pending += 1; @@ -423,14 +429,7 @@ where let mut completed_test = res.unwrap(); let running_test = running_tests.remove(&completed_test.id).unwrap(); - if let Some(join_handle) = running_test.join_handle { - if let Err(_) = join_handle.join() { - if let TrOk = completed_test.result { - completed_test.result = - TrFailedMsg("panicked after reporting success".to_string()); - } - } - } + running_test.join(&mut completed_test); let event = TestEvent::TeResult(completed_test); notify_about_test_event(event)?; @@ -443,8 +442,10 @@ where for (id, b) in filtered.benchs { let event = TestEvent::TeWait(b.desc.clone()); notify_about_test_event(event)?; - run_test(opts, false, id, b, run_strategy, tx.clone(), Concurrent::No); - let completed_test = rx.recv().unwrap(); + let join_handle = run_test(opts, false, id, b, run_strategy, tx.clone()); + // Wait for the test to complete. + let mut completed_test = rx.recv().unwrap(); + RunningTest { join_handle }.join(&mut completed_test); let event = TestEvent::TeResult(completed_test); notify_about_test_event(event)?; @@ -520,7 +521,6 @@ pub fn run_test( test: TestDescAndFn, strategy: RunStrategy, monitor_ch: Sender, - concurrency: Concurrent, ) -> Option> { let TestDescAndFn { desc, testfn } = test; @@ -538,7 +538,6 @@ pub fn run_test( struct TestRunOpts { pub strategy: RunStrategy, pub nocapture: bool, - pub concurrency: Concurrent, pub time: Option, } @@ -549,7 +548,6 @@ pub fn run_test( testfn: Box Result<(), String> + Send>, opts: TestRunOpts, ) -> Option> { - let concurrency = opts.concurrency; let name = desc.name.clone(); let runtest = move || match opts.strategy { @@ -576,7 +574,7 @@ pub fn run_test( // the test synchronously, regardless of the concurrency // level. let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm"); - if concurrency == Concurrent::Yes && supports_threads { + if supports_threads { let cfg = thread::Builder::new().name(name.as_slice().to_owned()); let mut runtest = Arc::new(Mutex::new(Some(runtest))); let runtest2 = runtest.clone(); @@ -597,7 +595,7 @@ pub fn run_test( } let test_run_opts = - TestRunOpts { strategy, nocapture: opts.nocapture, concurrency, time: opts.time_options }; + TestRunOpts { strategy, nocapture: opts.nocapture, time: opts.time_options }; match testfn { DynBenchFn(benchfn) => { diff --git a/library/test/src/options.rs b/library/test/src/options.rs index baf36b5f1d85e..75ec0b616e193 100644 --- a/library/test/src/options.rs +++ b/library/test/src/options.rs @@ -1,12 +1,5 @@ //! Enums denoting options for test execution. -/// Whether to execute tests concurrently or not -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Concurrent { - Yes, - No, -} - /// Number of times to run a benchmarked function #[derive(Clone, PartialEq, Eq)] pub enum BenchMode { diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index b54be64efcfed..7b2e6707f9d11 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -102,7 +102,7 @@ pub fn do_not_run_ignored_tests() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_ne!(result, TrOk); } @@ -125,7 +125,7 @@ pub fn ignored_tests_result_in_ignored() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!(result, TrIgnored); } @@ -150,7 +150,7 @@ fn test_should_panic() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!(result, TrOk); } @@ -175,7 +175,7 @@ fn test_should_panic_good_message() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!(result, TrOk); } @@ -205,7 +205,7 @@ fn test_should_panic_bad_message() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!(result, TrFailedMsg(failed_msg.to_string())); } @@ -239,7 +239,7 @@ fn test_should_panic_non_string_message_type() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!(result, TrFailedMsg(failed_msg)); } @@ -267,15 +267,7 @@ fn test_should_panic_but_succeeds() { testfn: DynTestFn(Box::new(f)), }; let (tx, rx) = channel(); - run_test( - &TestOpts::new(), - false, - TestId(0), - desc, - RunStrategy::InProcess, - tx, - Concurrent::No, - ); + run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; assert_eq!( result, @@ -306,7 +298,7 @@ fn report_time_test_template(report_time: bool) -> Option { let test_opts = TestOpts { time_options, ..TestOpts::new() }; let (tx, rx) = channel(); - run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx); let exec_time = rx.recv().unwrap().exec_time; exec_time } @@ -345,7 +337,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult { let test_opts = TestOpts { time_options: Some(time_options), ..TestOpts::new() }; let (tx, rx) = channel(); - run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); + run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx); let result = rx.recv().unwrap().result; result diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json index 63342abc6ef71..ad22b66eda69f 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-default.json +++ b/src/test/run-make-fulldeps/libtest-json/output-default.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json index 8f19114460e89..ec98172eb1c4e 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json +++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json @@ -2,9 +2,9 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } -{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" } +{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'c' panicked at 'assertion failed: false', f.rs:15:5\n" } { "type": "test", "event": "started", "name": "d" } { "type": "test", "name": "d", "event": "ignored", "message": "msg" } { "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME } diff --git a/src/test/ui/test-attrs/test-thread-capture.run.stdout b/src/test/ui/test-attrs/test-thread-capture.run.stdout index c712a78afb0f1..513c8cf2add00 100644 --- a/src/test/ui/test-attrs/test-thread-capture.run.stdout +++ b/src/test/ui/test-attrs/test-thread-capture.run.stdout @@ -10,7 +10,7 @@ fee fie foe fum -thread 'main' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5 +thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/test-attrs/test-thread-nocapture.run.stderr b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr index 0a12a052819c9..8c905d1af8572 100644 --- a/src/test/ui/test-attrs/test-thread-nocapture.run.stderr +++ b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr @@ -1,2 +1,2 @@ -thread 'main' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5 +thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From 089cf38976d8b637df4e103e3f3d6aa408f02769 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 30 Oct 2022 15:38:37 -0400 Subject: [PATCH 107/482] UPDATE - Complete link.rs migration to new diagnostics infraestructure --- compiler/rustc_codegen_ssa/src/back/link.rs | 123 ++++++----------- compiler/rustc_codegen_ssa/src/errors.rs | 130 ++++++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 51 +++++++ compiler/rustc_errors/src/diagnostic_impls.rs | 4 +- 4 files changed, 227 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 0dc0dee862c74..4c58d0b53f08d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -919,29 +919,17 @@ fn link_natively<'a>( ) .is_some(); - sess.note_without_error("`link.exe` returned an unexpected error"); + sess.emit_note(errors::LinkExeUnexpectedError); if is_vs_installed && has_linker { // the linker is broken - sess.note_without_error( - "the Visual Studio build tools may need to be repaired \ - using the Visual Studio installer", - ); - sess.note_without_error( - "or a necessary component may be missing from the \ - \"C++ build tools\" workload", - ); + sess.emit_note(errors::RepairVSBuildTools); + sess.emit_note(errors::MissingCppBuildToolComponent); } else if is_vs_installed { // the linker is not installed - sess.note_without_error( - "in the Visual Studio installer, ensure the \ - \"C++ build tools\" workload is selected", - ); + sess.emit_note(errors::SelectCppBuildToolWorkload); } else { // visual studio is not installed - sess.note_without_error( - "you may need to install Visual Studio build tools with the \ - \"C++ build tools\" workload", - ); + sess.emit_note(errors::VisualStudioNotInstalled); } } } @@ -954,35 +942,20 @@ fn link_natively<'a>( Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; - let mut linker_error = { - if linker_not_found { - sess.struct_err(&format!("linker `{}` not found", linker_path.display())) - } else { - sess.struct_err(&format!( - "could not exec the linker `{}`", - linker_path.display() - )) - } - }; - - linker_error.note(&e.to_string()); - - if !linker_not_found { - linker_error.note(&format!("{:?}", &cmd)); + if linker_not_found { + sess.emit_err(errors::LinkerNotFound { linker_path, error: e }); + } else { + sess.emit_err(errors::UnableToExeLinker { + linker_path, + error: e, + command_formatted: format!("{:?}", &cmd), + }); } - linker_error.emit(); - if sess.target.is_like_msvc && linker_not_found { - sess.note_without_error( - "the msvc targets depend on the msvc linker \ - but `link.exe` was not found", - ); - sess.note_without_error( - "please ensure that Visual Studio 2017 or later, or Build Tools \ - for Visual Studio were installed with the Visual C++ option.", - ); - sess.note_without_error("VS Code is a different product, and is not sufficient."); + sess.emit_note(errors::MsvcMissingLinker); + sess.emit_note(errors::CheckInstalledVisualStudio); + sess.emit_note(errors::UnsufficientVSCodeProduct); } sess.abort_if_errors(); } @@ -1007,15 +980,13 @@ fn link_natively<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_warn(&format!( - "processing debug info with `dsymutil` failed: {}", - prog.status - )) - .note(&escape_string(&output)) - .emit(); + sess.emit_warning(errors::ProcessingDymutilFailed { + status: prog.status, + output: escape_string(&output), + }); } } - Err(e) => sess.fatal(&format!("unable to run `dsymutil`: {}", e)), + Err(error) => sess.emit_fatal(errors::UnableToRunDsymutil { error }), } } @@ -1092,21 +1063,21 @@ fn strip_symbols_with_external_utility<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_warn(&format!( - "stripping debug info with `{}` failed: {}", - util, prog.status - )) - .note(&escape_string(&output)) - .emit(); + sess.emit_warning(errors::StrippingDebuInfoFailed { + util, + status: prog.status, + output: escape_string(&output), + }); } } - Err(e) => sess.fatal(&format!("unable to run `{}`: {}", util, e)), + Err(error) => sess.emit_fatal(errors::UnableToRun { util, error }), } } fn escape_string(s: &[u8]) -> String { match str::from_utf8(s) { Ok(s) => s.to_owned(), + // FIXME: return a type that can conform to IntoDiagnosticArg Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()), } } @@ -1251,7 +1222,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { )), (Some(linker), None) => { let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker") + sess.emit_fatal(errors::LinkerFileStem); }); let flavor = if stem == "emcc" { @@ -1378,13 +1349,9 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { }) .collect(); if !lib_args.is_empty() { - sess.note_without_error( - "Link against the following native artifacts when linking \ - against this static library. The order and any duplication \ - can be significant on some platforms.", - ); + sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability - sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" "))); + sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") }); } } @@ -1688,14 +1655,14 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty match (crate_type, &sess.target.link_script) { (CrateType::Cdylib | CrateType::Executable, Some(script)) => { if !sess.target.linker_flavor.is_gnu() { - sess.fatal("can only use link script when linking with GNU-like linker"); + sess.emit_fatal(errors::LinkScriptUnavailable); } let file_name = ["rustc", &sess.target.llvm_target, "linkfile.ld"].join("-"); let path = tmpdir.join(file_name); - if let Err(e) = fs::write(&path, script.as_ref()) { - sess.fatal(&format!("failed to write link script to {}: {}", path.display(), e)); + if let Err(error) = fs::write(&path, script.as_ref()) { + sess.emit_fatal(errors::LinkScriptWriteFailure { path, error }); } cmd.arg("--script"); @@ -1841,8 +1808,8 @@ fn add_linked_symbol_object( let path = tmpdir.join("symbols.o"); let result = std::fs::write(&path, file.write().unwrap()); - if let Err(e) = result { - sess.fatal(&format!("failed to write {}: {}", path.display(), e)); + if let Err(error) = result { + sess.emit_fatal(errors::FailedToWrite { path, error }); } cmd.add_object(&path); } @@ -2299,14 +2266,10 @@ fn collect_natvis_visualizers( visualizer_paths.push(visualizer_out_file); } Err(error) => { - sess.warn( - format!( - "Unable to write debugger visualizer file `{}`: {} ", - visualizer_out_file.display(), - error - ) - .as_str(), - ); + sess.emit_warning(errors::UnableToWriteDebuggerVisualizer { + path: visualizer_out_file, + error, + }); } }; } @@ -2641,7 +2604,7 @@ fn add_upstream_rust_crates<'a>( || !codegen_results.crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); - if let Err(e) = archive.add_archive( + if let Err(error) = archive.add_archive( cratepath, Box::new(move |f| { if f == METADATA_FILENAME { @@ -2681,7 +2644,7 @@ fn add_upstream_rust_crates<'a>( false }), ) { - sess.fatal(&format!("failed to build archive from rlib: {}", e)); + sess.emit_fatal(errors::RlibArchiveBuildFailure { error }); } if archive.build(&dst) { link_upstream(&dst); @@ -2919,7 +2882,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { } } } else { - sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc"); + sess.emit_fatal(errors::OptionGccOnly); } } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index ebb531f1c43a5..71fac123725cf 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -354,3 +354,133 @@ impl IntoDiagnostic<'_> for LinkingFailed<'_> { diag } } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_exe_unexpected_error)] +pub struct LinkExeUnexpectedError; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_repair_vs_build_tools)] +pub struct RepairVSBuildTools; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_missing_cpp_build_tool_component)] +pub struct MissingCppBuildToolComponent; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_select_cpp_build_tool_workload)] +pub struct SelectCppBuildToolWorkload; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_visual_studio_not_installed)] +pub struct VisualStudioNotInstalled; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_linker_not_found)] +#[note] +pub struct LinkerNotFound { + pub linker_path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_exe_linker)] +#[note] +#[note(command_note)] +pub struct UnableToExeLinker { + pub linker_path: PathBuf, + pub error: Error, + pub command_formatted: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_msvc_missing_linker)] +pub struct MsvcMissingLinker; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_check_installed_visual_studio)] +pub struct CheckInstalledVisualStudio; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsufficient_vs_code_product)] +pub struct UnsufficientVSCodeProduct; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_processing_dymutil_failed)] +#[note] +pub struct ProcessingDymutilFailed { + pub status: ExitStatus, + pub output: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_run_dsymutil)] +#[note] +pub struct UnableToRunDsymutil { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_stripping_debu_info_failed)] +#[note] +pub struct StrippingDebuInfoFailed<'a> { + pub util: &'a str, + pub status: ExitStatus, + pub output: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_run)] +pub struct UnableToRun<'a> { + pub util: &'a str, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_linker_file_stem)] +pub struct LinkerFileStem; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_static_library_native_artifacts)] +pub struct StaticLibraryNativeArtifacts; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_native_static_libs)] +pub struct NativeStaticLibs { + pub arguments: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_script_unavailable)] +pub struct LinkScriptUnavailable; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_script_write_failure)] +pub struct LinkScriptWriteFailure { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_failed_to_write)] +pub struct FailedToWrite { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_write_debugger_visualizer)] +pub struct UnableToWriteDebuggerVisualizer { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_rlib_archive_build_failure)] +pub struct RlibArchiveBuildFailure { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_option_gcc_only)] +pub struct OptionGccOnly; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 966a421bcf08c..2e5c72ee6452a 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -119,3 +119,54 @@ codegen_ssa_thorin_object_read = {$error} codegen_ssa_thorin_object_write = {$error} codegen_ssa_thorin_gimli_read = {$error} codegen_ssa_thorin_gimli_write = {$error} + +codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error + +codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer + +codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload + +codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected + +codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload + +codegen_ssa_linker_not_found = linker `{$linker_path}` not found + .note = {$error} + +codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}` + .note = {$error} + .command_note = {$command_formatted} + +codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found + +codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. + +codegen_ssa_unsufficient_vs_code_product = VS Code is a different product, and is not sufficient. + +codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} + .note = {$output} + +codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} + +codegen_ssa_stripping_debu_info_failed = stripping debug info with `{$util}` failed: {$status} + .note = {$output} + +codegen_ssa_unable_to_run = unable to run `{$util}`: {$error} + +codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker + +codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. + +codegen_ssa_native_static_libs = native-static-libs: {$arguments} + +codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker + +codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} + +codegen_ssa_failed_to_write = failed to write {$path}: {$error} + +codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error} + +codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error} + +codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index f6fe9192b45ca..6fd27fa59fae7 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -14,6 +14,7 @@ use std::fmt; use std::fmt::Write; use std::num::ParseIntError; use std::path::{Path, PathBuf}; +use std::process::ExitStatus; pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display); @@ -67,7 +68,8 @@ into_diagnostic_arg_using_display!( ParseIntError, StackProtector, &TargetTriple, - SplitDebuginfo + SplitDebuginfo, + ExitStatus, ); impl IntoDiagnosticArg for bool { From 04917d6f6ff7e3675781ba3f480a6f63cbc1929a Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 31 Oct 2022 01:36:32 -0400 Subject: [PATCH 108/482] ADD - ExtractBundledLibsError. Migrated extract_bundled_libs to translatable diagnostics --- .../rustc_codegen_ssa/src/back/archive.rs | 59 +++++++++++++------ compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 48 +++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 8 +++ 4 files changed, 98 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index bb76ca5d2b941..b45fa2476875b 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -6,11 +6,12 @@ use rustc_span::symbol::Symbol; use object::read::archive::ArchiveFile; -use std::fmt::Display; use std::fs::File; use std::io; use std::path::{Path, PathBuf}; +use crate::errors::{ExtractBundledLibsError, ExtractBundledLibsErrorKind::*}; + pub trait ArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box + 'a>; @@ -28,32 +29,54 @@ pub trait ArchiveBuilderBuilder { is_direct_dependency: bool, ) -> PathBuf; - fn extract_bundled_libs( - &self, - rlib: &Path, + fn extract_bundled_libs<'a>( + &'a self, + rlib: &'a Path, outdir: &Path, bundled_lib_file_names: &FxHashSet, - ) -> Result<(), String> { - let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e); + ) -> Result<(), ExtractBundledLibsError<'_>> { let archive_map = unsafe { - Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?) - .map_err(|e| message("failed to mmap file", &e))? + Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError { + kind: OpenFile, + rlib, + error: e.to_string(), + })?) + .map_err(|e| ExtractBundledLibsError { + kind: MmapFile, + rlib, + error: e.to_string(), + })? }; - let archive = ArchiveFile::parse(&*archive_map) - .map_err(|e| message("failed to parse archive", &e))?; + let archive = ArchiveFile::parse(&*archive_map).map_err(|e| ExtractBundledLibsError { + kind: ParseArchive, + rlib, + error: e.to_string(), + })?; for entry in archive.members() { - let entry = entry.map_err(|e| message("failed to read entry", &e))?; - let data = entry - .data(&*archive_map) - .map_err(|e| message("failed to get data from archive member", &e))?; - let name = std::str::from_utf8(entry.name()) - .map_err(|e| message("failed to convert name", &e))?; + let entry = entry.map_err(|e| ExtractBundledLibsError { + kind: ReadEntry, + rlib, + error: e.to_string(), + })?; + let data = entry.data(&*archive_map).map_err(|e| ExtractBundledLibsError { + kind: ArchiveMember, + rlib, + error: e.to_string(), + })?; + let name = std::str::from_utf8(entry.name()).map_err(|e| ExtractBundledLibsError { + kind: ConvertName, + rlib, + error: e.to_string(), + })?; if !bundled_lib_file_names.contains(&Symbol::intern(name)) { continue; // We need to extract only native libraries. } - std::fs::write(&outdir.join(&name), data) - .map_err(|e| message("failed to write file", &e))?; + std::fs::write(&outdir.join(&name), data).map_err(|e| ExtractBundledLibsError { + kind: WriteFile, + rlib, + error: e.to_string(), + })?; } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4c58d0b53f08d..1277294b63419 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2447,7 +2447,7 @@ fn add_upstream_rust_crates<'a>( let rlib = &src.rlib.as_ref().unwrap().0; archive_builder_builder .extract_bundled_libs(rlib, tmpdir, &bundled_libs) - .unwrap_or_else(|e| sess.fatal(e)); + .unwrap_or_else(|e| sess.emit_fatal(e)); } let mut last = (None, NativeLibKind::Unspecified, None); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 71fac123725cf..0a2532ccc470e 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -484,3 +484,51 @@ pub struct RlibArchiveBuildFailure { #[derive(Diagnostic)] #[diag(codegen_ssa_option_gcc_only)] pub struct OptionGccOnly; + +pub struct ExtractBundledLibsError<'a> { + pub kind: ExtractBundledLibsErrorKind, + pub rlib: &'a Path, + pub error: String, +} + +pub enum ExtractBundledLibsErrorKind { + OpenFile, + MmapFile, + ParseArchive, + ReadEntry, + ArchiveMember, + ConvertName, + WriteFile, +} + +impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, !> { + let mut diag = match self.kind { + ExtractBundledLibsErrorKind::OpenFile => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_open_file) + } + ExtractBundledLibsErrorKind::MmapFile => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_mmap_file) + } + ExtractBundledLibsErrorKind::ParseArchive => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_parse_archive) + } + ExtractBundledLibsErrorKind::ReadEntry => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_read_entry) + } + ExtractBundledLibsErrorKind::ArchiveMember => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_archive_member) + } + ExtractBundledLibsErrorKind::ConvertName => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_convert_name) + } + ExtractBundledLibsErrorKind::WriteFile => { + handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_write_file) + } + }; + + diag.set_arg("rlib", self.rlib); + diag.set_arg("error", self.error); + diag + } +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 2e5c72ee6452a..a31e1658f5f00 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -170,3 +170,11 @@ codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visua codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error} codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc + +codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} +codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error} From 73deb4c500d2687ccd268821317e1809baa46758 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Mon, 31 Oct 2022 01:51:58 -0400 Subject: [PATCH 109/482] FIX - Migrate missing errors in link.rs --- compiler/rustc_codegen_ssa/src/back/link.rs | 8 ++++---- compiler/rustc_codegen_ssa/src/errors.rs | 13 +++++++++++++ .../locales/en-US/codegen_ssa.ftl | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1277294b63419..1e6a2b6ecaa6d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2776,14 +2776,14 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { ("arm", "watchos") => "watchos", (_, "macos") => "macosx", _ => { - sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os)); + sess.emit_err(errors::UnsupportedArch { arch, os }); return; } }; let sdk_root = match get_apple_sdk_root(sdk_name) { Ok(s) => s, Err(e) => { - sess.err(&e); + sess.emit_err(e); return; } }; @@ -2799,7 +2799,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { } } -fn get_apple_sdk_root(sdk_name: &str) -> Result { +fn get_apple_sdk_root(sdk_name: &str) -> Result> { // Following what clang does // (https://github.com/llvm/llvm-project/blob/ // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678) @@ -2849,7 +2849,7 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { match res { Ok(output) => Ok(output.trim().to_string()), - Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)), + Err(error) => Err(errors::AppleSdkRootError::SdkPath { sdk_name, error }), } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 0a2532ccc470e..35eae30c4ba9d 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -532,3 +532,16 @@ impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> { diag } } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsupported_arch)] +pub struct UnsupportedArch<'a> { + pub arch: &'a str, + pub os: &'a str, +} + +#[derive(Diagnostic)] +pub enum AppleSdkRootError<'a> { + #[diag(codegen_ssa_apple_sdk_error_sdk_path)] + SdkPath { sdk_name: &'a str, error: Error }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index a31e1658f5f00..ad0d758210175 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -178,3 +178,7 @@ codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$ codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error} + +codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` + +codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error} From 1b3ec2756d490da0fc647c4ce954812dae8e5176 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Thu, 3 Nov 2022 01:53:06 -0400 Subject: [PATCH 110/482] UPDATE - address PR Comments FIX - StrippingDebugInfoFailed typo DELETE - unneeded FIXME comment UPDATE - only declare the error with ExtractBundledLibsError as an enum and use the Diagnostic derive macro --- .../rustc_codegen_ssa/src/back/archive.rs | 56 ++++++---------- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- compiler/rustc_codegen_ssa/src/errors.rs | 64 ++++++------------- 3 files changed, 40 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index b45fa2476875b..9113ddab048ab 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -10,7 +10,7 @@ use std::fs::File; use std::io; use std::path::{Path, PathBuf}; -use crate::errors::{ExtractBundledLibsError, ExtractBundledLibsErrorKind::*}; +use crate::errors::ExtractBundledLibsError; pub trait ArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box + 'a>; @@ -35,48 +35,30 @@ pub trait ArchiveBuilderBuilder { outdir: &Path, bundled_lib_file_names: &FxHashSet, ) -> Result<(), ExtractBundledLibsError<'_>> { - let archive_map = unsafe { - Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError { - kind: OpenFile, - rlib, - error: e.to_string(), - })?) - .map_err(|e| ExtractBundledLibsError { - kind: MmapFile, - rlib, - error: e.to_string(), - })? - }; - let archive = ArchiveFile::parse(&*archive_map).map_err(|e| ExtractBundledLibsError { - kind: ParseArchive, - rlib, - error: e.to_string(), - })?; + let archive_map = + unsafe { + Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError::OpenFile { + rlib, + error: e.to_string(), + })?) + .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: e.to_string() })? + }; + let archive = ArchiveFile::parse(&*archive_map) + .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: e.to_string() })?; for entry in archive.members() { - let entry = entry.map_err(|e| ExtractBundledLibsError { - kind: ReadEntry, - rlib, - error: e.to_string(), - })?; - let data = entry.data(&*archive_map).map_err(|e| ExtractBundledLibsError { - kind: ArchiveMember, - rlib, - error: e.to_string(), - })?; - let name = std::str::from_utf8(entry.name()).map_err(|e| ExtractBundledLibsError { - kind: ConvertName, - rlib, - error: e.to_string(), + let entry = entry + .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: e.to_string() })?; + let data = entry.data(&*archive_map).map_err(|e| { + ExtractBundledLibsError::ArchiveMember { rlib, error: e.to_string() } })?; + let name = std::str::from_utf8(entry.name()) + .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: e.to_string() })?; if !bundled_lib_file_names.contains(&Symbol::intern(name)) { continue; // We need to extract only native libraries. } - std::fs::write(&outdir.join(&name), data).map_err(|e| ExtractBundledLibsError { - kind: WriteFile, - rlib, - error: e.to_string(), - })?; + std::fs::write(&outdir.join(&name), data) + .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: e.to_string() })?; } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1e6a2b6ecaa6d..6f0a8d0a54cba 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1063,7 +1063,7 @@ fn strip_symbols_with_external_utility<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.emit_warning(errors::StrippingDebuInfoFailed { + sess.emit_warning(errors::StrippingDebugInfoFailed { util, status: prog.status, output: escape_string(&output), @@ -1077,7 +1077,6 @@ fn strip_symbols_with_external_utility<'a>( fn escape_string(s: &[u8]) -> String { match str::from_utf8(s) { Ok(s) => s.to_owned(), - // FIXME: return a type that can conform to IntoDiagnosticArg Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()), } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 35eae30c4ba9d..265f466f2ca37 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -423,7 +423,7 @@ pub struct UnableToRunDsymutil { #[derive(Diagnostic)] #[diag(codegen_ssa_stripping_debu_info_failed)] #[note] -pub struct StrippingDebuInfoFailed<'a> { +pub struct StrippingDebugInfoFailed<'a> { pub util: &'a str, pub status: ExitStatus, pub output: String, @@ -485,52 +485,28 @@ pub struct RlibArchiveBuildFailure { #[diag(codegen_ssa_option_gcc_only)] pub struct OptionGccOnly; -pub struct ExtractBundledLibsError<'a> { - pub kind: ExtractBundledLibsErrorKind, - pub rlib: &'a Path, - pub error: String, -} +#[derive(Diagnostic)] +pub enum ExtractBundledLibsError<'a> { + #[diag(codegen_ssa_extract_bundled_libs_open_file)] + OpenFile { rlib: &'a Path, error: String }, -pub enum ExtractBundledLibsErrorKind { - OpenFile, - MmapFile, - ParseArchive, - ReadEntry, - ArchiveMember, - ConvertName, - WriteFile, -} + #[diag(codegen_ssa_extract_bundled_libs_mmap_file)] + MmapFile { rlib: &'a Path, error: String }, -impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, !> { - let mut diag = match self.kind { - ExtractBundledLibsErrorKind::OpenFile => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_open_file) - } - ExtractBundledLibsErrorKind::MmapFile => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_mmap_file) - } - ExtractBundledLibsErrorKind::ParseArchive => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_parse_archive) - } - ExtractBundledLibsErrorKind::ReadEntry => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_read_entry) - } - ExtractBundledLibsErrorKind::ArchiveMember => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_archive_member) - } - ExtractBundledLibsErrorKind::ConvertName => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_convert_name) - } - ExtractBundledLibsErrorKind::WriteFile => { - handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_write_file) - } - }; + #[diag(codegen_ssa_extract_bundled_libs_parse_archive)] + ParseArchive { rlib: &'a Path, error: String }, - diag.set_arg("rlib", self.rlib); - diag.set_arg("error", self.error); - diag - } + #[diag(codegen_ssa_extract_bundled_libs_read_entry)] + ReadEntry { rlib: &'a Path, error: String }, + + #[diag(codegen_ssa_extract_bundled_libs_archive_member)] + ArchiveMember { rlib: &'a Path, error: String }, + + #[diag(codegen_ssa_extract_bundled_libs_convert_name)] + ConvertName { rlib: &'a Path, error: String }, + + #[diag(codegen_ssa_extract_bundled_libs_write_file)] + WriteFile { rlib: &'a Path, error: String }, } #[derive(Diagnostic)] From 81c4f3c70acad3c65e09e2a729846aae9663d9a6 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Fri, 4 Nov 2022 01:16:16 -0400 Subject: [PATCH 111/482] UPDATE - accept dyn error and make Box conform to IntoDiagnosticArg --- .../rustc_codegen_ssa/src/back/archive.rs | 29 +++++++++---------- compiler/rustc_codegen_ssa/src/errors.rs | 14 ++++----- compiler/rustc_errors/src/diagnostic_impls.rs | 1 + 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 9113ddab048ab..18789d00fd3a4 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -35,30 +35,29 @@ pub trait ArchiveBuilderBuilder { outdir: &Path, bundled_lib_file_names: &FxHashSet, ) -> Result<(), ExtractBundledLibsError<'_>> { - let archive_map = - unsafe { - Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError::OpenFile { - rlib, - error: e.to_string(), - })?) - .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: e.to_string() })? - }; + let archive_map = unsafe { + Mmap::map( + File::open(rlib) + .map_err(|e| ExtractBundledLibsError::OpenFile { rlib, error: Box::new(e) })?, + ) + .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: Box::new(e) })? + }; let archive = ArchiveFile::parse(&*archive_map) - .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: Box::new(e) })?; for entry in archive.members() { let entry = entry - .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: e.to_string() })?; - let data = entry.data(&*archive_map).map_err(|e| { - ExtractBundledLibsError::ArchiveMember { rlib, error: e.to_string() } - })?; + .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: Box::new(e) })?; + let data = entry + .data(&*archive_map) + .map_err(|e| ExtractBundledLibsError::ArchiveMember { rlib, error: Box::new(e) })?; let name = std::str::from_utf8(entry.name()) - .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: Box::new(e) })?; if !bundled_lib_file_names.contains(&Symbol::intern(name)) { continue; // We need to extract only native libraries. } std::fs::write(&outdir.join(&name), data) - .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: Box::new(e) })?; } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 265f466f2ca37..36c94462b0b3e 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -488,25 +488,25 @@ pub struct OptionGccOnly; #[derive(Diagnostic)] pub enum ExtractBundledLibsError<'a> { #[diag(codegen_ssa_extract_bundled_libs_open_file)] - OpenFile { rlib: &'a Path, error: String }, + OpenFile { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_mmap_file)] - MmapFile { rlib: &'a Path, error: String }, + MmapFile { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_parse_archive)] - ParseArchive { rlib: &'a Path, error: String }, + ParseArchive { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_read_entry)] - ReadEntry { rlib: &'a Path, error: String }, + ReadEntry { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_archive_member)] - ArchiveMember { rlib: &'a Path, error: String }, + ArchiveMember { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_convert_name)] - ConvertName { rlib: &'a Path, error: String }, + ConvertName { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_write_file)] - WriteFile { rlib: &'a Path, error: String }, + WriteFile { rlib: &'a Path, error: Box }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 6fd27fa59fae7..22f6fc700fad3 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -60,6 +60,7 @@ into_diagnostic_arg_using_display!( i128, u128, std::io::Error, + std::boxed::Box, std::num::NonZeroU32, hir::Target, Edition, From 7656741811c3247cf33a669b67b91b4a0fee1e95 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 2 Nov 2022 18:47:58 +0000 Subject: [PATCH 112/482] asm: Work around LLVM bug on AArch64 Upstream issue: https://github.com/llvm/llvm-project/issues/58384 LLVM gets confused if we assign a 32-bit value to a 64-bit register, so pass the 32-bit register name to LLVM in that case. --- compiler/rustc_codegen_llvm/src/asm.rs | 57 ++++++++++++++++++++++++-- src/test/ui/asm/aarch64/llvm-58384.rs | 16 ++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/asm/aarch64/llvm-58384.rs diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 88a4f62d93dfb..2ef6fd4942bda 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -505,6 +505,44 @@ fn xmm_reg_index(reg: InlineAsmReg) -> Option { } } +/// If the register is an AArch64 integer register then return its index. +fn a64_reg_index(reg: InlineAsmReg) -> Option { + match reg { + InlineAsmReg::AArch64(AArch64InlineAsmReg::x0) => Some(0), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x1) => Some(1), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x2) => Some(2), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x3) => Some(3), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x4) => Some(4), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x5) => Some(5), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x6) => Some(6), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x7) => Some(7), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x8) => Some(8), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x9) => Some(9), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x10) => Some(10), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x11) => Some(11), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x12) => Some(12), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x13) => Some(13), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x14) => Some(14), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x15) => Some(15), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x16) => Some(16), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x17) => Some(17), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x18) => Some(18), + // x19 is reserved + InlineAsmReg::AArch64(AArch64InlineAsmReg::x20) => Some(20), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x21) => Some(21), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x22) => Some(22), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x23) => Some(23), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x24) => Some(24), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x25) => Some(25), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x26) => Some(26), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x27) => Some(27), + InlineAsmReg::AArch64(AArch64InlineAsmReg::x28) => Some(28), + // x29 is reserved + InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) => Some(30), + _ => None, + } +} + /// If the register is an AArch64 vector register then return its index. fn a64_vreg_index(reg: InlineAsmReg) -> Option { match reg { @@ -535,6 +573,22 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> 'x' }; format!("{{{}mm{}}}", class, idx) + } else if let Some(idx) = a64_reg_index(reg) { + let class = if let Some(layout) = layout { + match layout.size.bytes() { + 8 => 'x', + _ => 'w', + } + } else { + // We use i32 as the type for discarded outputs + 'w' + }; + if class == 'x' && reg == InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) { + // LLVM doesn't recognize x30. use lr instead. + "{lr}".to_string() + } else { + format!("{{{}{}}}", class, idx) + } } else if let Some(idx) = a64_vreg_index(reg) { let class = if let Some(layout) = layout { match layout.size.bytes() { @@ -550,9 +604,6 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> 'q' }; format!("{{{}{}}}", class, idx) - } else if reg == InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) { - // LLVM doesn't recognize x30 - "{lr}".to_string() } else if reg == InlineAsmReg::Arm(ArmInlineAsmReg::r14) { // LLVM doesn't recognize r14 "{lr}".to_string() diff --git a/src/test/ui/asm/aarch64/llvm-58384.rs b/src/test/ui/asm/aarch64/llvm-58384.rs new file mode 100644 index 0000000000000..308f789082959 --- /dev/null +++ b/src/test/ui/asm/aarch64/llvm-58384.rs @@ -0,0 +1,16 @@ +// only-aarch64 +// run-pass +// needs-asm-support + +// Test that we properly work around this LLVM issue: +// https://github.com/llvm/llvm-project/issues/58384 + +use std::arch::asm; + +fn main() { + let a: i32; + unsafe { + asm!("", inout("x0") 435 => a); + } + assert_eq!(a, 435); +} From 4b45dc99d6cff5b7a44daafed2e258e7050a9663 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 3 Nov 2022 18:52:08 +0000 Subject: [PATCH 113/482] Cleanups --- compiler/rustc_hir_typeck/src/method/mod.rs | 3 +- compiler/rustc_hir_typeck/src/method/probe.rs | 1 - .../rustc_hir_typeck/src/method/suggest.rs | 136 +++++------------- compiler/rustc_middle/src/traits/mod.rs | 9 +- compiler/rustc_middle/src/ty/sty.rs | 7 + .../src/traits/on_unimplemented.rs | 1 + 6 files changed, 56 insertions(+), 101 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index a1278edefbb71..2c7b3bbf31c20 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -55,8 +55,7 @@ pub enum MethodError<'tcx> { // not-in-scope traits which may work. PrivateMatch(DefKind, DefId, Vec), - // Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have - // forgotten to import a trait. + // Found a `Self: Sized` bound where `Self` is a trait object. IllegalSizedBound(Vec, bool, Span), // Found a match, but the return type is wrong diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28aa2302f882f..e88701685bc6d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1019,7 +1019,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let out_of_scope_traits = match self.pick_core() { Some(Ok(p)) => vec![p.item.container_id(self.tcx)], - //Some(Ok(p)) => p.iter().map(|p| p.item.container().id()).collect(), Some(Err(MethodError::Ambiguity(v))) => v .into_iter() .map(|source| match source { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6c21ed902d007..04ecd2757b427 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match error { MethodError::NoMatch(NoMatchData { - static_candidates: mut static_sources, + mut static_candidates, unsatisfied_predicates, out_of_scope_traits, lev_candidate, @@ -288,9 +288,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if generics.len() > 0 { let mut autoderef = self.autoderef(span, actual); let candidate_found = autoderef.any(|(ty, _)| { - if let ty::Adt(adt_deref, _) = ty.kind() { + if let ty::Adt(adt_def, _) = ty.kind() { self.tcx - .inherent_impls(adt_deref.did()) + .inherent_impls(adt_def.did()) .iter() .filter_map(|def_id| self.associated_value(*def_id, item_name)) .count() @@ -348,15 +348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let ty_span = match actual.kind() { - ty::Param(param_type) => { - let generics = self.tcx.generics_of(self.body_id.owner.to_def_id()); - let type_param = generics.type_param(param_type, self.tcx); - Some(self.tcx.def_span(type_param.def_id)) - } + ty::Param(param_type) => Some( + param_type.span_from_generics(self.tcx, self.body_id.owner.to_def_id()), + ), ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), _ => None, }; - if let Some(span) = ty_span { err.span_label( span, @@ -386,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut custom_span_label = false; - if !static_sources.is_empty() { + if !static_candidates.is_empty() { err.note( "found the following associated functions; to be used as methods, \ functions must have a `self` parameter", @@ -394,9 +391,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(span, "this is an associated function, not a method"); custom_span_label = true; } - if static_sources.len() == 1 { + if static_candidates.len() == 1 { let ty_str = - if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) { + if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. // (#61411) @@ -422,9 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); } - report_candidates(span, &mut err, &mut static_sources, sugg_span); - } else if static_sources.len() > 1 { - report_candidates(span, &mut err, &mut static_sources, sugg_span); + report_candidates(span, &mut err, &mut static_candidates, sugg_span); + } else if static_candidates.len() > 1 { + report_candidates(span, &mut err, &mut static_candidates, sugg_span); } let mut bound_spans = vec![]; @@ -496,24 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (ty::Param(_), ty::PredicateKind::Trait(p)) = (self_ty.kind(), parent_pred.kind().skip_binder()) { + let hir = self.tcx.hir(); let node = match p.trait_ref.self_ty().kind() { ty::Param(_) => { // Account for `fn` items like in `issue-35677.rs` to // suggest restricting its type params. - let did = self.tcx.hir().body_owner_def_id(hir::BodyId { - hir_id: self.body_id, - }); - Some( - self.tcx - .hir() - .get(self.tcx.hir().local_def_id_to_hir_id(did)), - ) + let parent_body = + hir.body_owner(hir::BodyId { hir_id: self.body_id }); + Some(hir.get(parent_body)) + } + ty::Adt(def, _) => { + def.did().as_local().map(|def_id| hir.get_by_def_id(def_id)) } - ty::Adt(def, _) => def.did().as_local().map(|def_id| { - self.tcx - .hir() - .get(self.tcx.hir().local_def_id_to_hir_id(def_id)) - }), _ => None, }; if let Some(hir::Node::Item(hir::Item { kind, .. })) = node { @@ -605,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) .filter_map(|(p, parent, c)| match c.code() { - ObligationCauseCode::ImplDerivedObligation(ref data) => { + ObligationCauseCode::ImplDerivedObligation(data) => { Some((&data.derived, p, parent, data.impl_def_id, data)) } _ => None, @@ -620,22 +611,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.tcx.hir().get_if_local(impl_def_id) { // Unmet obligation comes from a `derive` macro, point at it once to // avoid multiple span labels pointing at the same place. - Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(..), - ident, - .. - })) if matches!( - ident.span.ctxt().outer_expn_data().kind, - ExpnKind::Macro(MacroKind::Derive, _) - ) => - { - let span = ident.span.ctxt().outer_expn_data().call_site; - let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg); - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); - } - Some(Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), .. @@ -659,34 +634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } - // Unmet obligation coming from a `trait`. - Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(..), - ident, - span: item_span, - .. - })) if !matches!( - ident.span.ctxt().outer_expn_data().kind, - ExpnKind::Macro(MacroKind::Derive, _) - ) => - { - if let Some(pred) = parent_p { - // Done to add the "doesn't satisfy" `span_label`. - let _ = format_pred(*pred); - } - skip_list.insert(p); - let mut spans = if cause.span != *item_span { - let mut spans: MultiSpan = cause.span.into(); - spans.push_span_label(cause.span, unsatisfied_msg); - spans - } else { - ident.span.into() - }; - spans.push_span_label(ident.span, "in this trait"); - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); - } - // Unmet obligation coming from an `impl`. Some(Node::Item(hir::Item { kind: @@ -695,19 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }), span: item_span, .. - })) if !matches!( - self_ty.span.ctxt().outer_expn_data().kind, - ExpnKind::Macro(MacroKind::Derive, _) - ) && !matches!( - of_trait.as_ref().map(|t| t - .path - .span - .ctxt() - .outer_expn_data() - .kind), - Some(ExpnKind::Macro(MacroKind::Derive, _)) - ) => - { + })) => { let sized_pred = unsatisfied_predicates.iter().any(|(pred, _, _)| { match pred.kind().skip_binder() { @@ -759,7 +694,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } - _ => {} + Some(_) => unreachable!(), + None => (), } } let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); @@ -863,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .on_unimplemented_note(trait_ref, &obligation); (message, label) }) - .unwrap_or((None, None)) + .unwrap() } else { (None, None) }; @@ -972,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the method name is the name of a field with a function or closure type, // give a helping note that it has to be called as `(x.f)(...)`. if let SelfSource::MethodCall(expr) = source { - if !self.suggest_field_call(span, rcvr_ty, expr, item_name, &mut err) + if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err) && lev_candidate.is_none() && !custom_span_label { @@ -982,10 +918,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { label_span_not_found(&mut err); } - // Don't suggest (for example) `expr.field.method()` if `expr.method()` - // doesn't exist due to unsatisfied predicates. + // Don't suggest (for example) `expr.field.clone()` if `expr.clone()` + // can't be called due to `typeof(expr): Clone` not holding. if unsatisfied_predicates.is_empty() { - self.check_for_field_method(&mut err, source, span, actual, item_name); + self.suggest_calling_method_on_field(&mut err, source, span, actual, item_name); } self.check_for_inner_self(&mut err, source, span, actual, item_name); @@ -1007,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, out_of_scope_traits, &unsatisfied_predicates, - &static_sources, + &static_candidates, unsatisfied_bounds, ); } @@ -1146,7 +1082,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } - fn suggest_field_call( + /// Suggest calling a field with a type that implements the `Fn*` traits instead of a method with + /// the same name as the field i.e. `(a.my_fn_ptr)(10)` instead of `a.my_fn_ptr(10)`. + fn suggest_calling_field_as_fn( &self, span: Span, rcvr_ty: Ty<'tcx>, @@ -1408,7 +1346,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } - fn check_for_field_method( + /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()` + fn suggest_calling_method_on_field( &self, err: &mut Diagnostic, source: SelfSource<'tcx>, @@ -2021,7 +1960,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let mut alt_rcvr_sugg = false; if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { - debug!(?span, ?item_name, ?rcvr_ty, ?rcvr); + debug!( + "suggest_traits_to_import: span={:?}, item_name={:?}, rcvr_ty={:?}, rcvr={:?}", + span, item_name, rcvr_ty, rcvr + ); let skippable = [ self.tcx.lang_items().clone_trait(), self.tcx.lang_items().deref_trait(), @@ -2060,7 +2002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // suggestions are generally misleading (see #94218). break; } - _ => {} + Err(_) => (), } for (rcvr_ty, pre) in &[ diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index e73d44bbb36c3..07ee758b32c1f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -203,13 +203,20 @@ pub struct UnifyReceiverContext<'tcx> { pub substs: SubstsRef<'tcx>, } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, Default)] +#[derive(Clone, PartialEq, Eq, Hash, Lift, Default)] pub struct InternedObligationCauseCode<'tcx> { /// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of /// the time). `Some` otherwise. code: Option>>, } +impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let cause: &ObligationCauseCode<'_> = self; + cause.fmt(f) + } +} + impl<'tcx> ObligationCauseCode<'tcx> { #[inline(always)] fn into(self) -> InternedObligationCauseCode<'tcx> { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index cf420bafeb12f..5f108bf0ef306 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -20,6 +20,7 @@ use rustc_hir::def_id::DefId; use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::Span; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi; use std::borrow::Cow; @@ -1282,6 +1283,12 @@ impl<'tcx> ParamTy { pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { tcx.mk_ty_param(self.index, self.name) } + + pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span { + let generics = tcx.generics_of(item_with_generics); + let type_param = generics.type_param(self, tcx); + tcx.def_span(type_param.def_id) + } } #[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 4a4f34b768059..fb062ea71c4ce 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -27,6 +27,7 @@ pub struct OnUnimplementedDirective { } #[derive(Default)] +/// For the `#[rustc_on_unimplemented]` attribute pub struct OnUnimplementedNote { pub message: Option, pub label: Option, From dd2198363ae117fd05dcbdc6dc682ac51d9edc68 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Nov 2022 16:56:48 +0800 Subject: [PATCH 114/482] test tidy should not count untracked paths towards entries limit --- Cargo.lock | 1 + src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/ui_tests.rs | 59 +++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 075c5d4404621..b73a4d6f2da50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4937,6 +4937,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "cargo_metadata 0.14.0", + "ignore", "lazy_static", "miropt-test-tools", "regex", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 774c97b7777d2..97d038da702d5 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -10,6 +10,7 @@ regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } lazy_static = "1" walkdir = "2" +ignore = "0.4.18" [[bin]] name = "rust-tidy" diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 6bf7d8206a576..aee36f061c5d1 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -2,6 +2,8 @@ //! - the number of entries in each directory must be less than `ENTRY_LIMIT` //! - there are no stray `.stderr` files +use ignore::Walk; +use ignore::WalkBuilder; use std::fs; use std::path::Path; @@ -11,34 +13,39 @@ const ROOT_ENTRY_LIMIT: usize = 941; const ISSUES_ENTRY_LIMIT: usize = 2117; fn check_entries(path: &Path, bad: &mut bool) { - let dirs = walkdir::WalkDir::new(&path.join("test/ui")) - .into_iter() - .filter_entry(|e| e.file_type().is_dir()); - for dir in dirs { - if let Ok(dir) = dir { - let dir_path = dir.path(); + for dir in Walk::new(&path.join("test/ui")) { + if let Ok(entry) = dir { + if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) { + let dir_path = entry.path(); + // Use special values for these dirs. + let is_root = path.join("test/ui") == dir_path; + let is_issues_dir = path.join("test/ui/issues") == dir_path; + let limit = if is_root { + ROOT_ENTRY_LIMIT + } else if is_issues_dir { + ISSUES_ENTRY_LIMIT + } else { + ENTRY_LIMIT + }; - // Use special values for these dirs. - let is_root = path.join("test/ui") == dir_path; - let is_issues_dir = path.join("test/ui/issues") == dir_path; - let limit = if is_root { - ROOT_ENTRY_LIMIT - } else if is_issues_dir { - ISSUES_ENTRY_LIMIT - } else { - ENTRY_LIMIT - }; + let count = WalkBuilder::new(&dir_path) + .max_depth(Some(1)) + .build() + .into_iter() + .collect::>() + .len() + - 1; // remove the dir itself - let count = std::fs::read_dir(dir_path).unwrap().count(); - if count > limit { - tidy_error!( - bad, - "following path contains more than {} entries, \ - you should move the test to some relevant subdirectory (current: {}): {}", - limit, - count, - dir_path.display() - ); + if count > limit { + tidy_error!( + bad, + "following path contains more than {} entries, \ + you should move the test to some relevant subdirectory (current: {}): {}", + limit, + count, + dir_path.display() + ); + } } } } From 60c42c9055f9e2b5f5bac66a70595e1243888882 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 4 Nov 2022 12:25:40 +0000 Subject: [PATCH 115/482] Give a specific lint for unsafety not being inherited --- .../rustc_mir_transform/src/check_unsafety.rs | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 959fcf8d89e86..80e1246ec6bf3 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,3 +1,4 @@ +use hir::{BlockCheckMode, ExprKind, Node}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -517,24 +518,49 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { let (description, note) = details.description_and_note(); - // Report an error. - let unsafe_fn_msg = - if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" }; - match kind { UnsafetyViolationKind::General => { // once - struct_span_err!( + // Mutable statics always require an unsafe block + let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) + && details != UnsafetyViolationDetails::UseOfMutableStatic + { + " function or" + } else { + "" + }; + + let mut err = struct_span_err!( tcx.sess, source_info.span, E0133, "{} is unsafe and requires unsafe{} block", description, unsafe_fn_msg, - ) - .span_label(source_info.span, description) - .note(note) - .emit(); + ); + err.span_label(source_info.span, description).note(note); + let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| { + if let Node::Expr(block) = node + && let ExprKind::Block(block, _) = block.kind + && let BlockCheckMode::UnsafeBlock(_) = block.rules { + true + } + else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + && sig.header.is_unsafe() { + true + } else { + false + } + }); + if let Some((id, _)) = note_non_inherited { + let span = tcx.hir().span(id); + err.span_label( + tcx.sess.source_map().guess_head_span(span), + "items do not inherit unsafety from separate enclosing items", + ); + } + + err.emit(); } UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir( UNSAFE_OP_IN_UNSAFE_FN, From 5c63218c94c2be70144eddb809420b6a8b27be5b Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 4 Nov 2022 12:57:42 +0000 Subject: [PATCH 116/482] Formatting changes + add UI test --- .../rustc_mir_transform/src/check_unsafety.rs | 19 +++++++------- src/test/ui/unsafe/unsafe-not-inherited.rs | 26 +++++++++++++++++++ .../ui/unsafe/unsafe-not-inherited.stderr | 24 +++++++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/unsafe/unsafe-not-inherited.rs create mode 100644 src/test/ui/unsafe/unsafe-not-inherited.stderr diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 80e1246ec6bf3..269d9f3b102c1 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,10 +1,10 @@ -use hir::{BlockCheckMode, ExprKind, Node}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; +use rustc_hir::{BlockCheckMode, ExprKind, Node}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; @@ -521,10 +521,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { match kind { UnsafetyViolationKind::General => { // once - // Mutable statics always require an unsafe block - let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) - && details != UnsafetyViolationDetails::UseOfMutableStatic - { + let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" @@ -542,12 +539,14 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| { if let Node::Expr(block) = node && let ExprKind::Block(block, _) = block.kind - && let BlockCheckMode::UnsafeBlock(_) = block.rules { - true - } + && let BlockCheckMode::UnsafeBlock(_) = block.rules + { + true + } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) - && sig.header.is_unsafe() { - true + && sig.header.is_unsafe() + { + true } else { false } diff --git a/src/test/ui/unsafe/unsafe-not-inherited.rs b/src/test/ui/unsafe/unsafe-not-inherited.rs new file mode 100644 index 0000000000000..6d797caa0f94d --- /dev/null +++ b/src/test/ui/unsafe/unsafe-not-inherited.rs @@ -0,0 +1,26 @@ +#![allow(unused, dead_code)] + +static mut FOO: u64 = 0; + +fn static_mod() { + unsafe {static BAR: u64 = FOO;} + //~^ ERROR: use of mutable static is unsafe + //~| NOTE: use of mutable static + //~| NOTE: mutable statics can be mutated by multiple threads + //~| NOTE: items do not inherit unsafety +} + +unsafe fn unsafe_call() {} +fn foo() { + unsafe { + //~^ NOTE: items do not inherit unsafety + fn bar() { + unsafe_call(); + //~^ ERROR: call to unsafe function + //~| NOTE: call to unsafe function + //~| NOTE: consult the function's documentation + } + } +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-not-inherited.stderr b/src/test/ui/unsafe/unsafe-not-inherited.stderr new file mode 100644 index 0000000000000..3bc5ca5c9d151 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-not-inherited.stderr @@ -0,0 +1,24 @@ +error[E0133]: use of mutable static is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:6:31 + | +LL | unsafe {static BAR: u64 = FOO;} + | ------ ^^^ use of mutable static + | | + | items do not inherit unsafety from separate enclosing items + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:18:13 + | +LL | unsafe { + | ------ items do not inherit unsafety from separate enclosing items +... +LL | unsafe_call(); + | ^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. From 4e7d2c10a357047643a9998e0beb9c146ee941bb Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 20 Oct 2022 11:35:28 +0200 Subject: [PATCH 117/482] ensure that compile-flags arguments are the last in ui tests Before this commit, compiletest would add `-L path/to/aux` at the end of the rustc flags, even after the custom ones set with the compile-flags header comment. This made it impossible to check how rustc would behave when a flag requiring an argument was passed without the argument, because the argument would become `-L`. This PR fixes that by adding the `-L path/to/aux` before the arguments defined in compile-flags, at least for UI tests. Other test suites might either be fixed as well by this change, or still present the old behavior. --- src/tools/compiletest/src/runtest.rs | 60 +++++++++++++++++++--------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index dee144052874f..c78acc91ab0e5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1472,10 +1472,13 @@ impl<'test> TestCx<'test> { _ => AllowUnused::No, }; - let mut rustc = - self.make_compile_args(&self.testpaths.file, output_file, emit_metadata, allow_unused); - - rustc.arg("-L").arg(&self.aux_output_dir_name()); + let rustc = self.make_compile_args( + &self.testpaths.file, + output_file, + emit_metadata, + allow_unused, + LinkToAux::Yes, + ); self.compose_and_run_compiler(rustc, None) } @@ -1702,8 +1705,13 @@ impl<'test> TestCx<'test> { // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); let input_file = &aux_testpaths.file; - let mut aux_rustc = - aux_cx.make_compile_args(input_file, aux_output, EmitMetadata::No, AllowUnused::No); + let mut aux_rustc = aux_cx.make_compile_args( + input_file, + aux_output, + EmitMetadata::No, + AllowUnused::No, + LinkToAux::No, + ); for key in &aux_props.unset_rustc_env { aux_rustc.env_remove(key); @@ -1833,6 +1841,7 @@ impl<'test> TestCx<'test> { output_file: TargetLocation, emit_metadata: EmitMetadata, allow_unused: AllowUnused, + link_to_aux: LinkToAux, ) -> Command { let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary"); let is_rustdoc = self.is_rustdoc() && !is_aux; @@ -2014,6 +2023,10 @@ impl<'test> TestCx<'test> { rustc.arg("-Ctarget-feature=-crt-static"); } + if let LinkToAux::Yes = link_to_aux { + rustc.arg("-L").arg(self.aux_output_dir_name()); + } + rustc.args(&self.props.compile_flags); rustc @@ -2205,13 +2218,16 @@ impl<'test> TestCx<'test> { // codegen tests (using FileCheck) fn compile_test_and_save_ir(&self) -> ProcRes { - let aux_dir = self.aux_output_dir_name(); - let output_file = TargetLocation::ThisDirectory(self.output_base_dir()); let input_file = &self.testpaths.file; - let mut rustc = - self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No); - rustc.arg("-L").arg(aux_dir).arg("--emit=llvm-ir"); + let mut rustc = self.make_compile_args( + input_file, + output_file, + EmitMetadata::No, + AllowUnused::No, + LinkToAux::Yes, + ); + rustc.arg("--emit=llvm-ir"); self.compose_and_run_compiler(rustc, None) } @@ -2223,10 +2239,13 @@ impl<'test> TestCx<'test> { let output_file = TargetLocation::ThisFile(output_path.clone()); let input_file = &self.testpaths.file; - let mut rustc = - self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No); - - rustc.arg("-L").arg(self.aux_output_dir_name()); + let mut rustc = self.make_compile_args( + input_file, + output_file, + EmitMetadata::No, + AllowUnused::No, + LinkToAux::Yes, + ); match self.props.assembly_output.as_ref().map(AsRef::as_ref) { Some("emit-asm") => { @@ -2367,8 +2386,8 @@ impl<'test> TestCx<'test> { output_file, EmitMetadata::No, AllowUnused::Yes, + LinkToAux::Yes, ); - rustc.arg("-L").arg(&new_rustdoc.aux_output_dir_name()); new_rustdoc.build_all_auxiliary(&mut rustc); let proc_res = new_rustdoc.document(&compare_dir); @@ -3312,13 +3331,13 @@ impl<'test> TestCx<'test> { if self.props.run_rustfix && self.config.compare_mode.is_none() { // And finally, compile the fixed code and make sure it both // succeeds and has no diagnostics. - let mut rustc = self.make_compile_args( + let rustc = self.make_compile_args( &self.testpaths.file.with_extension(UI_FIXED), TargetLocation::ThisFile(self.make_exe_name()), emit_metadata, AllowUnused::No, + LinkToAux::Yes, ); - rustc.arg("-L").arg(&self.aux_output_dir_name()); let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); @@ -3852,3 +3871,8 @@ enum AllowUnused { Yes, No, } + +enum LinkToAux { + Yes, + No, +} From fa87f59fc8ab24356617ee6deb6160e469297a4b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 3 Nov 2022 12:00:17 +0100 Subject: [PATCH 118/482] put custom flags as last in codegen and asm tests --- src/tools/compiletest/src/runtest.rs | 74 +++++++++++++++------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c78acc91ab0e5..8d8ca101cd037 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -208,11 +208,13 @@ enum WillExecute { Disabled, } -/// Should `--emit metadata` be used? +/// What value should be passed to `--emit`? #[derive(Copy, Clone)] -enum EmitMetadata { - Yes, - No, +enum Emit { + None, + Metadata, + LlvmIr, + Asm, } impl<'test> TestCx<'test> { @@ -412,7 +414,7 @@ impl<'test> TestCx<'test> { } let should_run = self.run_if_enabled(); - let mut proc_res = self.compile_test(should_run, EmitMetadata::No); + let mut proc_res = self.compile_test(should_run, Emit::None); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -658,7 +660,7 @@ impl<'test> TestCx<'test> { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compile_result = self.compile_test(should_run, EmitMetadata::No); + let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { self.fatal_proc_rec("compilation failed!", &compile_result); } @@ -778,7 +780,7 @@ impl<'test> TestCx<'test> { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compiler_run_result = self.compile_test(should_run, EmitMetadata::No); + let compiler_run_result = self.compile_test(should_run, Emit::None); if !compiler_run_result.status.success() { self.fatal_proc_rec("compilation failed!", &compiler_run_result); } @@ -1010,7 +1012,7 @@ impl<'test> TestCx<'test> { fn run_debuginfo_lldb_test_no_opt(&self) { // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); - let compile_result = self.compile_test(should_run, EmitMetadata::No); + let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { self.fatal_proc_rec("compilation failed!", &compile_result); } @@ -1426,21 +1428,21 @@ impl<'test> TestCx<'test> { } } - fn should_emit_metadata(&self, pm: Option) -> EmitMetadata { + fn should_emit_metadata(&self, pm: Option) -> Emit { match (pm, self.props.fail_mode, self.config.mode) { - (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => EmitMetadata::Yes, - _ => EmitMetadata::No, + (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => Emit::Metadata, + _ => Emit::None, } } - fn compile_test(&self, will_execute: WillExecute, emit_metadata: EmitMetadata) -> ProcRes { - self.compile_test_general(will_execute, emit_metadata, self.props.local_pass_mode()) + fn compile_test(&self, will_execute: WillExecute, emit: Emit) -> ProcRes { + self.compile_test_general(will_execute, emit, self.props.local_pass_mode()) } fn compile_test_general( &self, will_execute: WillExecute, - emit_metadata: EmitMetadata, + emit: Emit, local_pm: Option, ) -> ProcRes { // Only use `make_exe_name` when the test ends up being executed. @@ -1475,7 +1477,7 @@ impl<'test> TestCx<'test> { let rustc = self.make_compile_args( &self.testpaths.file, output_file, - emit_metadata, + emit, allow_unused, LinkToAux::Yes, ); @@ -1708,7 +1710,7 @@ impl<'test> TestCx<'test> { let mut aux_rustc = aux_cx.make_compile_args( input_file, aux_output, - EmitMetadata::No, + Emit::None, AllowUnused::No, LinkToAux::No, ); @@ -1839,7 +1841,7 @@ impl<'test> TestCx<'test> { &self, input_file: &Path, output_file: TargetLocation, - emit_metadata: EmitMetadata, + emit: Emit, allow_unused: AllowUnused, link_to_aux: LinkToAux, ) -> Command { @@ -1956,8 +1958,18 @@ impl<'test> TestCx<'test> { } } - if let (false, EmitMetadata::Yes) = (is_rustdoc, emit_metadata) { - rustc.args(&["--emit", "metadata"]); + match emit { + Emit::None => {} + Emit::Metadata if is_rustdoc => {} + Emit::Metadata => { + rustc.args(&["--emit", "metadata"]); + } + Emit::LlvmIr => { + rustc.args(&["--emit", "llvm-ir"]); + } + Emit::Asm => { + rustc.args(&["--emit", "asm"]); + } } if !is_rustdoc { @@ -2220,14 +2232,13 @@ impl<'test> TestCx<'test> { fn compile_test_and_save_ir(&self) -> ProcRes { let output_file = TargetLocation::ThisDirectory(self.output_base_dir()); let input_file = &self.testpaths.file; - let mut rustc = self.make_compile_args( + let rustc = self.make_compile_args( input_file, output_file, - EmitMetadata::No, + Emit::LlvmIr, AllowUnused::No, LinkToAux::Yes, ); - rustc.arg("--emit=llvm-ir"); self.compose_and_run_compiler(rustc, None) } @@ -2239,17 +2250,11 @@ impl<'test> TestCx<'test> { let output_file = TargetLocation::ThisFile(output_path.clone()); let input_file = &self.testpaths.file; - let mut rustc = self.make_compile_args( - input_file, - output_file, - EmitMetadata::No, - AllowUnused::No, - LinkToAux::Yes, - ); + let mut emit = Emit::None; match self.props.assembly_output.as_ref().map(AsRef::as_ref) { Some("emit-asm") => { - rustc.arg("--emit=asm"); + emit = Emit::Asm; } Some("ptx-linker") => { @@ -2260,6 +2265,9 @@ impl<'test> TestCx<'test> { None => self.fatal("missing 'assembly-output' header"), } + let rustc = + self.make_compile_args(input_file, output_file, emit, AllowUnused::No, LinkToAux::Yes); + (self.compose_and_run_compiler(rustc, None), output_path) } @@ -2384,7 +2392,7 @@ impl<'test> TestCx<'test> { let mut rustc = new_rustdoc.make_compile_args( &new_rustdoc.testpaths.file, output_file, - EmitMetadata::No, + Emit::None, AllowUnused::Yes, LinkToAux::Yes, ); @@ -2660,7 +2668,7 @@ impl<'test> TestCx<'test> { fn run_codegen_units_test(&self) { assert!(self.revision.is_none(), "revisions not relevant here"); - let proc_res = self.compile_test(WillExecute::No, EmitMetadata::No); + let proc_res = self.compile_test(WillExecute::No, Emit::None); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -3173,7 +3181,7 @@ impl<'test> TestCx<'test> { if let Some(FailMode::Build) = self.props.fail_mode { // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck). let pm = Some(PassMode::Check); - let proc_res = self.compile_test_general(WillExecute::No, EmitMetadata::Yes, pm); + let proc_res = self.compile_test_general(WillExecute::No, Emit::Metadata, pm); self.check_if_test_should_compile(&proc_res, pm); } From 7b4d9aeb28c81f8911e609c4ab85e30725a78c4b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 04:09:01 +0000 Subject: [PATCH 119/482] Use TraitEngine less --- .../src/diagnostics/conflict_errors.rs | 9 +--- .../src/region_infer/opaque_types.rs | 53 +++++++++---------- .../src/transform/check_consts/check.rs | 42 ++++++--------- compiler/rustc_hir_typeck/src/op.rs | 6 +-- .../src/for_loops_over_fallibles.rs | 11 +--- .../src/traits/outlives_bounds.rs | 22 ++++---- 6 files changed, 57 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 583bc2e281da4..8987a51757cd5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::TraitEngineExt as _; use crate::borrow_set::TwoPhaseActivation; use crate::borrowck_errors; @@ -613,24 +612,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); - let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); let cause = ObligationCause::new( span, self.mir_hir_id(), rustc_infer::traits::ObligationCauseCode::MiscObligation, ); - fulfill_cx.register_bound( + let errors = rustc_trait_selection::traits::fully_solve_bound( &infcx, + cause, self.param_env, // Erase any region vids from the type, which may not be resolved infcx.tcx.erase_regions(ty), copy_did, - cause, ); - // Select all, including ambiguous predicates - let errors = fulfill_cx.select_all_or_error(&infcx); // Only emit suggestion if all required predicates are on generic let predicates: Result, _> = errors diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 465f353aaa37f..95ea42b584a3a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::{DefiningAnchor, InferCtxt}; -use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine}; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ @@ -12,7 +12,7 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::TraitEngineExt as _; +use rustc_trait_selection::traits::ObligationCtxt; use super::RegionInferenceContext; @@ -252,48 +252,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // type-alias-impl-trait/issue-67844-nested-opaque.rs let infcx = self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); + let ocx = ObligationCtxt::new(&infcx); // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) .to_predicate(infcx.tcx); - let mut fulfillment_cx = >::new(infcx.tcx); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); // Require that the hidden type actually fulfills all the bounds of the opaque type, even without // the bounds that the function supplies. let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs); - match infcx - .at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env) - .eq(opaque_ty, definition_ty) - { - Ok(infer_ok) => { - for obligation in infer_ok.obligations { - fulfillment_cx.register_predicate_obligation(&infcx, obligation); - } - } - Err(err) => { - infcx - .err_ctxt() - .report_mismatched_types( - &ObligationCause::misc(instantiated_ty.span, body_id), - opaque_ty, - definition_ty, - err, - ) - .emit(); - } + if let Err(err) = ocx.eq( + &ObligationCause::misc(instantiated_ty.span, body_id), + param_env, + opaque_ty, + definition_ty, + ) { + infcx + .err_ctxt() + .report_mismatched_types( + &ObligationCause::misc(instantiated_ty.span, body_id), + opaque_ty, + definition_ty, + err, + ) + .emit(); } - fulfillment_cx.register_predicate_obligation( - &infcx, - Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), - ); + ocx.register_obligation(Obligation::misc( + instantiated_ty.span, + body_id, + param_env, + predicate, + )); // Check that all obligations are satisfied by the implementation's // version. - let errors = fulfillment_cx.select_all_or_error(&infcx); + let errors = ocx.select_all_or_error(); // This is still required for many(half of the tests in ui/type-alias-impl-trait) // tests to pass diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 22a61774e8cf7..b1ad22b899e30 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -13,11 +13,8 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; -use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{ - self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt, -}; +use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext}; use std::mem; use std::ops::Deref; @@ -747,35 +744,26 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // "non-const" check. This is required for correctness here. { let infcx = tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); + let ocx = ObligationCtxt::new(&infcx); + let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); let hir_id = tcx .hir() .local_def_id_to_hir_id(self.body.source.def_id().expect_local()); - let cause = || { - ObligationCause::new( - terminator.source_info.span, - hir_id, - ObligationCauseCode::ItemObligation(callee), - ) - }; - let normalized = infcx.partially_normalize_associated_types_in( - cause(), - param_env, - predicates, + let cause = ObligationCause::new( + terminator.source_info.span, + hir_id, + ObligationCauseCode::ItemObligation(callee), ); - - for p in normalized.obligations { - fulfill_cx.register_predicate_obligation(&infcx, p); - } - for obligation in traits::predicates_for_generics( - |_, _| cause(), + let normalized_predicates = + ocx.normalize(cause.clone(), param_env, predicates); + ocx.register_obligations(traits::predicates_for_generics( + |_, _| cause.clone(), self.param_env, - normalized.value, - ) { - fulfill_cx.register_predicate_obligation(&infcx, obligation); - } - let errors = fulfill_cx.select_all_or_error(&infcx); + normalized_predicates, + )); + + let errors = ocx.select_all_or_error(); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 8957399769385..8598369e884b4 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -19,7 +19,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt}; +use rustc_trait_selection::traits::FulfillmentError; use rustc_type_ir::sty::TyKind::*; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -785,9 +785,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { other_ty_expr, expected, ); - let mut fulfill = >::new(self.tcx); - fulfill.register_predicate_obligation(self, obligation); - Err(fulfill.select_where_possible(&self.infcx)) + Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation)) } } } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index ed8d424e0c62d..4187850153ccd 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -3,11 +3,9 @@ use crate::{LateContext, LateLintPass, LintContext}; use hir::{Expr, Pat}; use rustc_errors::{Applicability, DelayDm}; use rustc_hir as hir; -use rustc_infer::traits::TraitEngine; use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause}; use rustc_middle::ty::{self, List}; use rustc_span::{sym, Span}; -use rustc_trait_selection::traits::TraitEngineExt; declare_lint! { /// The `for_loops_over_fallibles` lint checks for `for` loops over `Option` or `Result` values. @@ -160,24 +158,19 @@ fn suggest_question_mark<'tcx>( let ty = substs.type_at(0); let infcx = cx.tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); - let cause = ObligationCause::new( span, body_id.hir_id, rustc_infer::traits::ObligationCauseCode::MiscObligation, ); - fulfill_cx.register_bound( + let errors = rustc_trait_selection::traits::fully_solve_bound( &infcx, + cause, ty::ParamEnv::empty(), // Erase any region vids from the type, which may not be resolved infcx.tcx.erase_regions(ty), into_iterator_did, - cause, ); - // Select all, including ambiguous predicates - let errors = fulfill_cx.select_all_or_error(&infcx); - errors.is_empty() } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 108dae092cfe7..b1a161c353637 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,7 +1,7 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; -use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; +use crate::traits::ObligationCause; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::HirId; @@ -74,20 +74,20 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { debug!(?constraints); // Instantiation may have produced new inference variables and constraints on those // variables. Process these constraints. - let mut fulfill_cx = >::new(self.tcx); let cause = ObligationCause::misc(span, body_id); - for &constraint in &constraints.outlives { - let obligation = self.query_outlives_constraint_to_obligation( - constraint, - cause.clone(), - param_env, - ); - fulfill_cx.register_predicate_obligation(self, obligation); - } + let errors = super::fully_solve_obligations( + self, + constraints.outlives.iter().map(|constraint| { + self.query_outlives_constraint_to_obligation( + *constraint, + cause.clone(), + param_env, + ) + }), + ); if !constraints.member_constraints.is_empty() { span_bug!(span, "{:#?}", constraints.member_constraints); } - let errors = fulfill_cx.select_all_or_error(self); if !errors.is_empty() { self.tcx.sess.delay_span_bug( span, From 620e855d6a7f57afc078b9959ebda3f34174883a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 2 Nov 2022 08:21:21 -0400 Subject: [PATCH 120/482] Fix artifact version/channel detection for stable On stable, our artifacts are uploaded with the raw version number (e.g., 1.65.0), not the channel. This adjusts our detection logic to use the version number from src/version when we detect the stable channel. --- src/bootstrap/config.rs | 55 ++++++++++++++++++++++++++++++----------- src/bootstrap/native.rs | 4 +-- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 34d5504827cfb..21dc11c48081e 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1380,21 +1380,46 @@ impl Config { git } - pub(crate) fn artifact_channel(&self, builder: &Builder<'_>, commit: &str) -> String { - if builder.rust_info.is_managed_git_subrepository() { + /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. + /// Return the version it would have used for the given commit. + pub(crate) fn artifact_version_part(&self, builder: &Builder<'_>, commit: &str) -> String { + let (channel, version) = if builder.rust_info.is_managed_git_subrepository() { let mut channel = self.git(); channel.arg("show").arg(format!("{}:src/ci/channel", commit)); let channel = output(&mut channel); - channel.trim().to_owned() - } else if let Ok(channel) = fs::read_to_string(builder.src.join("src/ci/channel")) { - channel.trim().to_owned() + let mut version = self.git(); + version.arg("show").arg(format!("{}:src/version", commit)); + let version = output(&mut version); + (channel.trim().to_owned(), version.trim().to_owned()) } else { - let src = builder.src.display(); - eprintln!("error: failed to determine artifact channel"); - eprintln!( - "help: either use git or ensure that {src}/src/ci/channel contains the name of the channel to use" - ); - panic!(); + let channel = fs::read_to_string(builder.src.join("src/ci/channel")); + let version = fs::read_to_string(builder.src.join("src/version")); + match (channel, version) { + (Ok(channel), Ok(version)) => { + (channel.trim().to_owned(), version.trim().to_owned()) + } + (channel, version) => { + let src = builder.src.display(); + eprintln!("error: failed to determine artifact channel and/or version"); + eprintln!( + "help: consider using a git checkout or ensure these files are readable" + ); + if let Err(channel) = channel { + eprintln!("reading {}/src/ci/channel failed: {:?}", src, channel); + } + if let Err(version) = version { + eprintln!("reading {}/src/version failed: {:?}", src, version); + } + panic!(); + } + } + }; + + match channel.as_str() { + "stable" => version, + "beta" => channel, + "nightly" => channel, + other => unreachable!("{:?} is not recognized as a valid channel", other), } } @@ -1637,7 +1662,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option { fn download_ci_rustc(builder: &Builder<'_>, commit: &str) { builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})")); - let channel = builder.config.artifact_channel(builder, commit); + let version = builder.config.artifact_version_part(builder, commit); let host = builder.config.build.triple; let bin_root = builder.out.join(host).join("ci-rustc"); let rustc_stamp = bin_root.join(".rustc-stamp"); @@ -1646,13 +1671,13 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) { if bin_root.exists() { t!(fs::remove_dir_all(&bin_root)); } - let filename = format!("rust-std-{channel}-{host}.tar.xz"); + let filename = format!("rust-std-{version}-{host}.tar.xz"); let pattern = format!("rust-std-{host}"); download_ci_component(builder, filename, &pattern, commit); - let filename = format!("rustc-{channel}-{host}.tar.xz"); + let filename = format!("rustc-{version}-{host}.tar.xz"); download_ci_component(builder, filename, "rustc", commit); // download-rustc doesn't need its own cargo, it can just use beta's. - let filename = format!("rustc-dev-{channel}-{host}.tar.xz"); + let filename = format!("rustc-dev-{version}-{host}.tar.xz"); download_ci_component(builder, filename, "rustc-dev", commit); builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc")); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 2f856c2761cf9..94a61b727a32b 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -269,8 +269,8 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) { } else { &builder.config.stage0_metadata.config.artifacts_server }; - let channel = builder.config.artifact_channel(builder, llvm_sha); - let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple); + let version = builder.config.artifact_version_part(builder, llvm_sha); + let filename = format!("rust-dev-{}-{}.tar.xz", version, builder.build.build.triple); let tarball = rustc_cache.join(&filename); if !tarball.exists() { let help_on_error = "error: failed to download llvm from ci From 771557a0a7b839c0a8065e12669f1b4268c49184 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Wed, 2 Nov 2022 12:18:00 -0500 Subject: [PATCH 121/482] Cleanup bind_pattern args --- .../rustc_mir_build/src/build/matches/mod.rs | 51 +++++-------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3f813e0af0da3..dfd8649cb97e7 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -364,12 +364,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arm_block = this.bind_pattern( outer_source_info, candidate, - arm.guard.as_ref(), &fake_borrow_temps, scrutinee_span, - Some(arm.span), - Some(arm.scope), - Some(match_scope), + Some((arm, match_scope)), false, ); @@ -410,12 +407,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, outer_source_info: SourceInfo, candidate: Candidate<'_, 'tcx>, - guard: Option<&Guard<'tcx>>, fake_borrow_temps: &[(Place<'tcx>, Local)], scrutinee_span: Span, - arm_span: Option, - arm_scope: Option, - match_scope: Option, + arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, storages_alive: bool, ) -> BasicBlock { if candidate.subcandidates.is_empty() { @@ -424,11 +418,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_and_guard_matched_candidate( candidate, &[], - guard, fake_borrow_temps, scrutinee_span, - arm_span, - match_scope, + arm_match_scope, true, storages_alive, ) @@ -449,6 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // we lower the guard. let target_block = self.cfg.start_new_block(); let mut schedule_drops = true; + let arm = arm_match_scope.unzip().0; // We keep a stack of all of the bindings and type ascriptions // from the parent candidates that we visit, that also need to // be bound for each candidate. @@ -456,21 +449,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate, &mut Vec::new(), &mut |leaf_candidate, parent_bindings| { - if let Some(arm_scope) = arm_scope { - self.clear_top_scope(arm_scope); + if let Some(arm) = arm { + self.clear_top_scope(arm.scope); } let binding_end = self.bind_and_guard_matched_candidate( leaf_candidate, parent_bindings, - guard, &fake_borrow_temps, scrutinee_span, - arm_span, - match_scope, + arm_match_scope, schedule_drops, storages_alive, ); - if arm_scope.is_none() { + if arm.is_none() { schedule_drops = false; } self.cfg.goto(binding_end, outer_source_info, target_block); @@ -636,12 +627,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, - None, &fake_borrow_temps, irrefutable_pat.span, None, - None, - None, false, ) .unit() @@ -1820,12 +1808,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let post_guard_block = self.bind_pattern( self.source_info(pat.span), guard_candidate, - None, &fake_borrow_temps, expr.span, None, - None, - None, false, ); @@ -1844,11 +1829,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, candidate: Candidate<'pat, 'tcx>, parent_bindings: &[(Vec>, Vec>)], - guard: Option<&Guard<'tcx>>, fake_borrows: &[(Place<'tcx>, Local)], scrutinee_span: Span, - arm_span: Option, - match_scope: Option, + arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, schedule_drops: bool, storages_alive: bool, ) -> BasicBlock { @@ -1960,7 +1943,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // the reference that we create for the arm. // * So we eagerly create the reference for the arm and then take a // reference to that. - if let Some(guard) = guard { + if let Some((arm, match_scope)) = arm_match_scope + && let Some(guard) = &arm.guard + { let tcx = self.tcx; let bindings = parent_bindings .iter() @@ -1981,8 +1966,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow); } - let arm_span = arm_span.unwrap(); - let match_scope = match_scope.unwrap(); let mut guard_span = rustc_span::DUMMY_SP; let (post_guard_block, otherwise_post_guard_block) = @@ -1995,13 +1978,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { e, None, match_scope, - this.source_info(arm_span), + this.source_info(arm.span), ) } Guard::IfLet(ref pat, scrutinee) => { let s = &this.thir[scrutinee]; guard_span = s.span; - this.lower_let_expr(block, s, pat, match_scope, None, arm_span) + this.lower_let_expr(block, s, pat, match_scope, None, arm.span) } }); @@ -2317,24 +2300,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let matching = this.bind_pattern( this.source_info(pattern.span), candidate, - None, &fake_borrow_temps, initializer_span, None, - None, - None, true, ); // This block is for the failure case let failure = this.bind_pattern( this.source_info(else_block_span), wildcard, - None, &fake_borrow_temps, initializer_span, None, - None, - None, true, ); this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span)); From b3d94c2b2c6240c2e87a5feb7b9f229dfaf0a150 Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Thu, 3 Nov 2022 23:19:59 -0700 Subject: [PATCH 122/482] Make mir opt unused file check blessable --- src/tools/tidy/src/mir_opt_tests.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index ea24fa4513832..018573284ea79 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use std::path::{Path, PathBuf}; -fn check_unused_files(path: &Path, bad: &mut bool) { +fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) { let mut rs_files = Vec::::new(); let mut output_files = HashSet::::new(); let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter(); @@ -27,11 +27,15 @@ fn check_unused_files(path: &Path, bad: &mut bool) { for extra in output_files { if extra.file_name() != Some("README.md".as_ref()) { - tidy_error!( - bad, - "the following output file is not associated with any mir-opt test, you can remove it: {}", - extra.display() - ); + if !bless { + tidy_error!( + bad, + "the following output file is not associated with any mir-opt test, you can remove it: {}", + extra.display() + ); + } else { + let _ = std::fs::remove_file(extra); + } } } } @@ -65,6 +69,6 @@ fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) { } pub fn check(path: &Path, bless: bool, bad: &mut bool) { - check_unused_files(path, bad); + check_unused_files(path, bless, bad); check_dash_files(path, bless, bad); } From dd2d8d94f7fc4ace86688db604f3e500dc87b015 Mon Sep 17 00:00:00 2001 From: Tim Neumann Date: Fri, 4 Nov 2022 16:20:42 +0000 Subject: [PATCH 123/482] LLVM 16: Switch to using MemoryEffects --- compiler/rustc_codegen_llvm/src/asm.rs | 6 +-- compiler/rustc_codegen_llvm/src/attributes.rs | 6 +-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 11 ++++- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 7 ++++ .../rustc_llvm/llvm-wrapper/LLVMWrapper.h | 1 - .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 42 ++++++++++++++++++- src/test/codegen/ffi-const.rs | 3 +- src/test/codegen/ffi-pure.rs | 3 +- 8 files changed, 67 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 2ef6fd4942bda..219a4f8fa8959 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -285,13 +285,13 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let mut attrs = SmallVec::<[_; 2]>::new(); if options.contains(InlineAsmOptions::PURE) { if options.contains(InlineAsmOptions::NOMEM) { - attrs.push(llvm::AttributeKind::ReadNone.create_attr(self.cx.llcx)); + attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx)); } else if options.contains(InlineAsmOptions::READONLY) { - attrs.push(llvm::AttributeKind::ReadOnly.create_attr(self.cx.llcx)); + attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx)); } attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx)); } else if options.contains(InlineAsmOptions::NOMEM) { - attrs.push(llvm::AttributeKind::InaccessibleMemOnly.create_attr(self.cx.llcx)); + attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx)); } else { // LLVM doesn't have an attribute to represent ReadOnly + SideEffect } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index eff2436d41cac..d96da5cc11d1f 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -13,7 +13,7 @@ use smallvec::SmallVec; use crate::attributes; use crate::llvm::AttributePlace::Function; -use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace}; +use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; use crate::llvm_util; pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; @@ -303,10 +303,10 @@ pub fn from_fn_attrs<'ll, 'tcx>( to_add.push(AttributeKind::ReturnsTwice.create_attr(cx.llcx)); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) { - to_add.push(AttributeKind::ReadOnly.create_attr(cx.llcx)); + to_add.push(MemoryEffects::ReadOnly.create_attr(cx.llcx)); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_CONST) { - to_add.push(AttributeKind::ReadNone.create_attr(cx.llcx)); + to_add.push(MemoryEffects::None.create_attr(cx.llcx)); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { to_add.push(AttributeKind::Naked.create_attr(cx.llcx)); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 42cb694c0e75a..e2d0390821d1e 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -183,7 +183,6 @@ pub enum AttributeKind { OptimizeNone = 24, ReturnsTwice = 25, ReadNone = 26, - InaccessibleMemOnly = 27, SanitizeHWAddress = 28, WillReturn = 29, StackProtectReq = 30, @@ -590,6 +589,15 @@ pub enum ChecksumKind { SHA256, } +/// LLVMRustMemoryEffects +#[derive(Copy, Clone)] +#[repr(C)] +pub enum MemoryEffects { + None, + ReadOnly, + InaccessibleMemOnly, +} + extern "C" { type Opaque; } @@ -1175,6 +1183,7 @@ extern "C" { pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute; pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute; pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute; + pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute; // Operations on functions pub fn LLVMRustGetOrInsertFunction<'a>( diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 6602a4ab8636c..f820e7523712c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -185,6 +185,13 @@ impl AttributeKind { } } +impl MemoryEffects { + /// Create an LLVM Attribute with these memory effects. + pub fn create_attr(self, llcx: &Context) -> &Attribute { + unsafe { LLVMRustCreateMemoryEffectsAttr(llcx, self) } + } +} + pub fn set_section(llglobal: &Value, section_name: &str) { let section_name_cstr = CString::new(section_name).expect("unexpected CString error"); unsafe { diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index 015c1c52bef77..727cfc4416ee9 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -76,7 +76,6 @@ enum LLVMRustAttribute { OptimizeNone = 24, ReturnsTwice = 25, ReadNone = 26, - InaccessibleMemOnly = 27, SanitizeHWAddress = 28, WillReturn = 29, StackProtectReq = 30, diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6f36281af23cc..0d9b5a57b69a2 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -8,6 +8,9 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/Mangler.h" +#if LLVM_VERSION_GE(16, 0) +#include "llvm/IR/ModRef.h" +#endif #include "llvm/Object/Archive.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ObjectFile.h" @@ -213,8 +216,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::ReturnsTwice; case ReadNone: return Attribute::ReadNone; - case InaccessibleMemOnly: - return Attribute::InaccessibleMemOnly; case SanitizeHWAddress: return Attribute::SanitizeHWAddress; case WillReturn: @@ -379,6 +380,43 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64 #endif } +// Simplified representation of `MemoryEffects` across the FFI boundary. +// +// Each variant corresponds to one of the static factory methods on `MemoryEffects`. +enum class LLVMRustMemoryEffects { + None, + ReadOnly, + InaccessibleMemOnly, +}; + +extern "C" LLVMAttributeRef LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C, + LLVMRustMemoryEffects Effects) { +#if LLVM_VERSION_GE(16, 0) + switch (Effects) { + case LLVMRustMemoryEffects::None: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::none())); + case LLVMRustMemoryEffects::ReadOnly: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::readOnly())); + case LLVMRustMemoryEffects::InaccessibleMemOnly: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), + MemoryEffects::inaccessibleMemOnly())); + default: + report_fatal_error("bad MemoryEffects."); + } +#else + switch (Effects) { + case LLVMRustMemoryEffects::None: + return wrap(Attribute::get(*unwrap(C), Attribute::ReadNone)); + case LLVMRustMemoryEffects::ReadOnly: + return wrap(Attribute::get(*unwrap(C), Attribute::ReadOnly)); + case LLVMRustMemoryEffects::InaccessibleMemOnly: + return wrap(Attribute::get(*unwrap(C), Attribute::InaccessibleMemOnly)); + default: + report_fatal_error("bad MemoryEffects."); + } +#endif +} + // Enable a fast-math flag // // https://llvm.org/docs/LangRef.html#fast-math-flags diff --git a/src/test/codegen/ffi-const.rs b/src/test/codegen/ffi-const.rs index d9cfa5429b5bb..9372050348088 100644 --- a/src/test/codegen/ffi-const.rs +++ b/src/test/codegen/ffi-const.rs @@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] - // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} } + // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0. + // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} } #[ffi_const] pub fn foo(); } diff --git a/src/test/codegen/ffi-pure.rs b/src/test/codegen/ffi-pure.rs index 5bdb2ee912a17..2ed735813582f 100644 --- a/src/test/codegen/ffi-pure.rs +++ b/src/test/codegen/ffi-pure.rs @@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] - // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} } + // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0. + // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} } #[ffi_pure] pub fn foo(); } From 7b92b7fa8c99f44544a07c229643eb58a9465cee Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 4 Nov 2022 12:34:24 -0700 Subject: [PATCH 124/482] rustdoc: simplify search results CSS and DOM There is a layout change caused by this commit, but it's subtle. You won't notice it unless you're looking for it. --- src/librustdoc/html/static/css/rustdoc.css | 20 ++++++------------- src/librustdoc/html/static/js/search.js | 6 ++---- .../rustdoc-gui/search-result-display.goml | 2 +- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 54f6e1ed4d515..227d9ac464bad 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -889,23 +889,17 @@ so that we can apply CSS-filters to change the arrow color in themes */ } .search-results > a { - display: block; + display: flex; /* A little margin ensures the browser's outlining of focused links has room to display. */ margin-left: 2px; margin-right: 2px; border-bottom: 1px solid var(--border-color); + gap: 1em; } .search-results > a > div { - display: flex; - flex-flow: row wrap; -} - -.search-results .result-name, .search-results div.desc { - width: 50%; -} -.search-results .result-name { - padding-right: 1em; + flex: 1; + overflow: hidden; } .search-results a:hover, @@ -1867,7 +1861,8 @@ in storage.js } /* Display an alternating layout on tablets and phones */ - .item-table, .item-row, .item-left, .item-right { + .item-table, .item-row, .item-left, .item-right, + .search-results > a, .search-results > a > div { display: block; } @@ -1875,9 +1870,6 @@ in storage.js .search-results > a { padding: 5px 0px; } - .search-results .result-name, .search-results div.desc { - width: 100%; - } .search-results div.desc, .item-right { padding-left: 2em; } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index d04ec357c40ac..ef3c74f5faa60 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1593,7 +1593,6 @@ function initSearch(rawSearchIndex) { link.className = "result-" + type; link.href = item.href; - const wrapper = document.createElement("div"); const resultName = document.createElement("div"); resultName.className = "result-name"; @@ -1614,7 +1613,7 @@ function initSearch(rawSearchIndex) { resultName.insertAdjacentHTML( "beforeend", item.displayPath + "" + name + extra + ""); - wrapper.appendChild(resultName); + link.appendChild(resultName); const description = document.createElement("div"); description.className = "desc"; @@ -1622,8 +1621,7 @@ function initSearch(rawSearchIndex) { spanDesc.insertAdjacentHTML("beforeend", item.desc); description.appendChild(spanDesc); - wrapper.appendChild(description); - link.appendChild(wrapper); + link.appendChild(description); output.appendChild(link); }); } else if (query.error === null) { diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml index 053bfd8c905d9..b8abd9f906242 100644 --- a/src/test/rustdoc-gui/search-result-display.goml +++ b/src/test/rustdoc-gui/search-result-display.goml @@ -7,7 +7,7 @@ press-key: 'Enter' wait-for: "#crate-search" // The width is returned by "getComputedStyle" which returns the exact number instead of the // CSS rule which is "50%"... -assert-css: (".search-results div.desc", {"width": "318px"}) +assert-css: (".search-results div.desc", {"width": "310px"}) size: (600, 100) // As counter-intuitive as it may seem, in this width, the width is "100%", which is why // when computed it's larger. From 2cadd223c6178876523d8ce37bee6a48cbe1e0e1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 4 Nov 2022 13:19:33 -0700 Subject: [PATCH 125/482] rustdoc: get rid of CSS/DOM `div.desc span`, which isn't really needed --- src/librustdoc/html/static/css/rustdoc.css | 15 +++++++-------- src/librustdoc/html/static/js/search.js | 4 +--- src/test/rustdoc-gui/search-result-color.goml | 8 ++++---- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 227d9ac464bad..7c0dab1c527d1 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -881,13 +881,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ display: block; } -.search-results .desc > span { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - display: block; -} - .search-results > a { display: flex; /* A little margin ensures the browser's outlining of focused links has room to display. */ @@ -899,7 +892,13 @@ so that we can apply CSS-filters to change the arrow color in themes */ .search-results > a > div { flex: 1; +} + +.search-results > a > div.desc { + white-space: nowrap; + text-overflow: ellipsis; overflow: hidden; + display: block; } .search-results a:hover, @@ -1870,7 +1869,7 @@ in storage.js .search-results > a { padding: 5px 0px; } - .search-results div.desc, .item-right { + .search-results > a > div.desc, .item-right { padding-left: 2em; } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index ef3c74f5faa60..dd0531c5e70e4 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1617,10 +1617,8 @@ function initSearch(rawSearchIndex) { const description = document.createElement("div"); description.className = "desc"; - const spanDesc = document.createElement("span"); - spanDesc.insertAdjacentHTML("beforeend", item.desc); + description.insertAdjacentHTML("beforeend", item.desc); - description.appendChild(spanDesc); link.appendChild(description); output.appendChild(link); }); diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 37d7b03a09958..0c3b111907424 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -67,7 +67,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(197, 197, 197)"}, ) assert-css: ( @@ -159,7 +159,7 @@ assert-css: ( ) // Checking color and background on hover. -move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']" +move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']" assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", {"color": "rgb(255, 255, 255)"}, @@ -179,7 +179,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(221, 221, 221)"}, ) assert-css: ( @@ -276,7 +276,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(0, 0, 0)"}, ) assert-css: ( From aa466da767875b3250687fee6f8d8c72a0f50a4d Mon Sep 17 00:00:00 2001 From: Mateusz Date: Fri, 4 Nov 2022 20:33:32 +0000 Subject: [PATCH 126/482] Refactor tcx mk_const parameters. --- .../src/check/compare_method.rs | 11 ++++------ .../src/infer/canonical/canonicalizer.rs | 8 ++++---- .../rustc_infer/src/infer/canonical/mod.rs | 7 +------ compiler/rustc_infer/src/infer/combine.rs | 16 +++++++-------- .../src/infer/higher_ranked/mod.rs | 6 +++--- compiler/rustc_infer/src/infer/mod.rs | 8 ++++---- compiler/rustc_middle/src/infer/canonical.rs | 8 ++++---- compiler/rustc_middle/src/mir/mod.rs | 6 ++---- compiler/rustc_middle/src/ty/codec.rs | 3 ++- compiler/rustc_middle/src/ty/consts.rs | 13 +++++------- compiler/rustc_middle/src/ty/context.rs | 15 +++++++++----- compiler/rustc_middle/src/ty/fold.rs | 12 +++-------- compiler/rustc_middle/src/ty/relate.rs | 8 ++++---- .../rustc_middle/src/ty/structural_impls.rs | 2 +- .../src/build/expr/as_constant.rs | 3 +-- compiler/rustc_symbol_mangling/src/v0.rs | 3 +-- .../src/traits/project.rs | 11 +++------- .../src/traits/select/confirmation.rs | 8 ++++---- compiler/rustc_traits/src/chalk/db.rs | 8 ++++---- compiler/rustc_traits/src/chalk/lowering.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 20 +++++-------------- 21 files changed, 74 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index aeaf7a6cfe1f1..c6b497e9b9fc4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1655,13 +1655,10 @@ pub fn check_type_bounds<'tcx>( GenericParamDefKind::Const { .. } => { let bound_var = ty::BoundVariableKind::Const; bound_vars.push(bound_var); - tcx.mk_const(ty::ConstS { - ty: tcx.type_of(param.def_id), - kind: ty::ConstKind::Bound( - ty::INNERMOST, - ty::BoundVar::from_usize(bound_vars.len() - 1), - ), - }) + tcx.mk_const( + ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)), + tcx.type_of(param.def_id), + ) .into() } }); diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index a3ff703634037..365b4b1fccdb4 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -773,10 +773,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_const(bound_to) } else { let var = self.canonical_var(info, const_var.into()); - self.tcx().mk_const(ty::ConstS { - kind: ty::ConstKind::Bound(self.binder_index, var), - ty: self.fold_ty(const_var.ty()), - }) + self.tcx().mk_const( + ty::ConstKind::Bound(self.binder_index, var), + self.fold_ty(const_var.ty()), + ) } } } diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index cbd6481f9cb81..0794792d8cb37 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -147,12 +147,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, name }, ty) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name }; - self.tcx - .mk_const(ty::ConstS { - kind: ty::ConstKind::Placeholder(placeholder_mapped), - ty, - }) - .into() + self.tcx.mk_const(ty::ConstKind::Placeholder(placeholder_mapped), ty).into() } } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index b5427f639c13c..a973bf54b055e 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -741,10 +741,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { substs, substs, )?; - Ok(self.tcx().mk_const(ty::ConstS { - ty: c.ty(), - kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }), - })) + Ok(self.tcx().mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }), + c.ty(), + )) } _ => relate::super_relate_consts(self, c, c), } @@ -955,10 +955,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { substs, )?; - Ok(self.tcx().mk_const(ty::ConstS { - ty: c.ty(), - kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }), - })) + Ok(self.tcx().mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }), + c.ty(), + )) } _ => relate::super_relate_consts(self, c, c), } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 28c87a1159f34..d739323de77c8 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -94,13 +94,13 @@ impl<'tcx> InferCtxt<'tcx> { })) }, consts: &mut |bound_var: ty::BoundVar, ty| { - self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Placeholder(ty::PlaceholderConst { + self.tcx.mk_const( + ty::ConstKind::Placeholder(ty::PlaceholderConst { universe: next_universe, name: bound_var, }), ty, - }) + ) }, }; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ffb020398b858..c2eecd9e87a38 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -2065,13 +2065,13 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( if ty.has_non_region_param() || ty.has_non_region_infer() { bug!("const `{ct}`'s type should not reference params or types"); } - tcx.mk_const(ty::ConstS { - ty, - kind: ty::ConstKind::Placeholder(ty::PlaceholderConst { + tcx.mk_const( + ty::ConstKind::Placeholder(ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, name: ty::BoundVar::from_usize(idx), }), - }) + ty, + ) .into() } _ => arg, diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index d3cf519b633c7..8d1ed4b2a5228 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -341,10 +341,10 @@ impl<'tcx> CanonicalVarValues<'tcx> { tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() } GenericArgKind::Const(ct) => tcx - .mk_const(ty::ConstS { - ty: ct.ty(), - kind: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), - }) + .mk_const( + ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), + ct.ty(), + ) .into(), }) .collect(), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 068daaadbdac2..0a96d23e3543b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2414,10 +2414,8 @@ impl<'tcx> ConstantKind<'tcx> { let generics = tcx.generics_of(item_def_id.to_def_id()); let index = generics.param_def_id_to_index[&def_id]; let name = tcx.hir().name(hir_id); - let ty_const = tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Param(ty::ParamConst::new(index, name)), - ty, - }); + let ty_const = + tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty); debug!(?ty_const); return Self::Ty(ty_const); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 14ec88b7e0d7e..7263e8306cf09 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -310,7 +310,8 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> impl<'tcx, D: TyDecoder>> Decodable for ty::Const<'tcx> { fn decode(decoder: &mut D) -> Self { - decoder.interner().mk_const(Decodable::decode(decoder)) + let consts: ty::ConstS<'tcx> = Decodable::decode(decoder); + decoder.interner().mk_const(consts.kind, consts.ty) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index f998e6083448f..33fdf1a837094 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -77,13 +77,13 @@ impl<'tcx> Const<'tcx> { match Self::try_eval_lit_or_param(tcx, ty, expr) { Some(v) => v, - None => tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { + None => tcx.mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: def.to_global(), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), }), ty, - }), + ), } } @@ -138,10 +138,7 @@ impl<'tcx> Const<'tcx> { let generics = tcx.generics_of(item_def_id.to_def_id()); let index = generics.param_def_id_to_index[&def_id]; let name = tcx.hir().name(hir_id); - Some(tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Param(ty::ParamConst::new(index, name)), - ty, - })) + Some(tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty)) } _ => None, } @@ -150,7 +147,7 @@ impl<'tcx> Const<'tcx> { /// Interns the given value as a constant. #[inline] pub fn from_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Self { - tcx.mk_const(ConstS { kind: ConstKind::Value(val), ty }) + tcx.mk_const(ConstKind::Value(val), ty) } /// Panics if self.kind != ty::ConstKind::Value diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fc3b071684999..e039436fe0afa 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1316,7 +1316,7 @@ impl<'tcx> TyCtxt<'tcx> { msg: &str, ) -> Const<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - self.mk_const(ty::ConstS { kind: ty::ConstKind::Error(reported), ty }) + self.mk_const(ty::ConstKind::Error(reported), ty) } pub fn consider_optimizing String>(self, msg: T) -> bool { @@ -2231,7 +2231,7 @@ macro_rules! direct_interners { direct_interners! { region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>, - const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>, + const_: mk_const_internal(ConstS<'tcx>): Const -> Const<'tcx>, const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>, adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>, @@ -2569,9 +2569,14 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty_infer(TyVar(v)) } + #[inline] + pub fn mk_const(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { + self.mk_const_internal(ty::ConstS { kind, ty }) + } + #[inline] pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(InferConst::Var(v)), ty }) + self.mk_const(ty::ConstKind::Infer(InferConst::Var(v)), ty) } #[inline] @@ -2591,7 +2596,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(ic), ty }) + self.mk_const(ty::ConstKind::Infer(ic), ty) } #[inline] @@ -2601,7 +2606,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> { - self.mk_const(ty::ConstS { kind: ty::ConstKind::Param(ParamConst { index, name }), ty }) + self.mk_const(ty::ConstKind::Param(ParamConst { index, name }), ty) } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 54f1499eb3d18..a329753726ef2 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -566,10 +566,7 @@ impl<'tcx> TyCtxt<'tcx> { )) }, consts: &mut |c, ty: Ty<'tcx>| { - self.mk_const(ty::ConstS { - kind: ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)), - ty, - }) + self.mk_const(ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)), ty) }, }, ) @@ -648,7 +645,7 @@ impl<'tcx> TyCtxt<'tcx> { let index = entry.index(); let var = ty::BoundVar::from_usize(index); let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const(); - self.tcx.mk_const(ty::ConstS { ty, kind: ty::ConstKind::Bound(ty::INNERMOST, var) }) + self.tcx.mk_const(ty::ConstKind::Bound(ty::INNERMOST, var), ty) } } @@ -732,10 +729,7 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> { ct } else { let debruijn = debruijn.shifted_in(self.amount); - self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Bound(debruijn, bound_ct), - ty: ct.ty(), - }) + self.tcx.mk_const(ty::ConstKind::Bound(debruijn, bound_ct), ct.ty()) } } else { ct.super_fold_with(self) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index b25b4bd4fe363..c083a405e3cfb 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -639,10 +639,10 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( au.substs, bu.substs, )?; - return Ok(tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: au.def, substs }), - ty: a.ty(), - })); + return Ok(tcx.mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: au.def, substs }), + a.ty(), + )); } _ => false, }; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 23cd93d6af40c..f2070869ce0cd 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -805,7 +805,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { let ty = self.ty().try_fold_with(folder)?; let kind = self.kind().try_fold_with(folder)?; if ty != self.ty() || kind != self.kind() { - Ok(folder.tcx().mk_const(ty::ConstS { ty, kind })) + Ok(folder.tcx().mk_const(kind, ty)) } else { Ok(self) } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 37dc1ad9f0d4e..98df9c3f0e8df 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -74,8 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { user_ty, span, literal } } ExprKind::ConstParam { param, def_id: _ } => { - let const_param = - tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Param(param), ty: expr.ty }); + let const_param = tcx.mk_const(ty::ConstKind::Param(param), expr.ty); let literal = ConstantKind::Ty(const_param); Constant { user_ty: None, span, literal } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index ecfe6861e84cb..2109b3c24962e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -654,8 +654,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { .builtin_deref(true) .expect("tried to dereference on non-ptr type") .ty; - let dereferenced_const = - self.tcx.mk_const(ty::ConstS { kind: ct.kind(), ty: pointee_ty }); + let dereferenced_const = self.tcx.mk_const(ct.kind(), pointee_ty); self = dereferenced_const.print(self)?; } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c8276854016f0..daee5dd8f02e6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -831,9 +831,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderConst { universe, name: bound_const }; self.mapped_consts.insert(p, bound_const); - self.infcx - .tcx - .mk_const(ty::ConstS { kind: ty::ConstKind::Placeholder(p), ty: ct.ty() }) + self.infcx.tcx.mk_const(ty::ConstKind::Placeholder(p), ct.ty()) } _ => ct.super_fold_with(self), } @@ -968,10 +966,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_const(ty::ConstS { - kind: ty::ConstKind::Bound(db, *replace_var), - ty: ct.ty(), - }) + self.tcx().mk_const(ty::ConstKind::Bound(db, *replace_var), ct.ty()) } None => ct, } @@ -2173,7 +2168,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id); let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs)); - ty.map_bound(|ty| tcx.mk_const(ty::ConstS { ty, kind }).into()) + ty.map_bound(|ty| tcx.mk_const(kind, ty).into()) } else { ty.map_bound(|ty| ty.into()) }; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index ed22058c64615..28b4bae7cbecf 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -555,13 +555,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { GenericParamDefKind::Const { .. } => { let bound_var = ty::BoundVariableKind::Const; bound_vars.push(bound_var); - tcx.mk_const(ty::ConstS { - ty: tcx.type_of(param.def_id), - kind: ty::ConstKind::Bound( + tcx.mk_const( + ty::ConstKind::Bound( ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1), ), - }) + tcx.type_of(param.def_id), + ) .into() } }); diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 0de28b826616e..2035252fe39a6 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -734,10 +734,10 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx } ty::GenericParamDefKind::Const { .. } => tcx - .mk_const(ty::ConstS { - kind: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), - ty: tcx.type_of(param.def_id), - }) + .mk_const( + ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), + tcx.type_of(param.def_id), + ) .into(), }) } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 45d5ea93d547f..0492e94b94e98 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -546,7 +546,7 @@ impl<'tcx> LowerInto<'tcx, ty::Const<'tcx>> for &chalk_ir::Const unimplemented!(), chalk_ir::ConstValue::Concrete(c) => ty::ConstKind::Value(c.interned), }; - interner.tcx.mk_const(ty::ConstS { ty, kind }) + interner.tcx.mk_const(kind, ty) } } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index e057bb6682501..3cef47c0f8ba4 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -33,7 +33,7 @@ pub(crate) fn destructure_const<'tcx>( // construct the consts for the elements of the array/slice let field_consts = branches .iter() - .map(|b| tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty })) + .map(|b| tcx.mk_const(ty::ConstKind::Value(*b), *inner_ty)) .collect::>(); debug!(?field_consts); @@ -52,10 +52,7 @@ pub(crate) fn destructure_const<'tcx>( for (field, field_valtree) in iter::zip(fields, branches) { let field_ty = field.ty(tcx, substs); - let field_const = tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(*field_valtree), - ty: field_ty, - }); + let field_const = tcx.mk_const(ty::ConstKind::Value(*field_valtree), field_ty); field_consts.push(field_const); } debug!(?field_consts); @@ -65,10 +62,7 @@ pub(crate) fn destructure_const<'tcx>( ty::Tuple(elem_tys) => { let fields = iter::zip(*elem_tys, branches) .map(|(elem_ty, elem_valtree)| { - tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(*elem_valtree), - ty: elem_ty, - }) + tcx.mk_const(ty::ConstKind::Value(*elem_valtree), elem_ty) }) .collect::>(); @@ -261,17 +255,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); - let constant = self - .tcx - .mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty }); + let constant = self.tcx.mk_const(ty::ConstKind::Unevaluated(uneval), node.ty); self.nodes.push(Node::Leaf(constant)) } ExprKind::ConstParam { param, .. } => { - let const_param = self - .tcx - .mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty }); + let const_param = self.tcx.mk_const(ty::ConstKind::Param(*param), node.ty); self.nodes.push(Node::Leaf(const_param)) } From 2aff47e3584e1a61896b7ee153ecd5cd934c80c9 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 4 Nov 2022 23:50:44 +0000 Subject: [PATCH 127/482] Update cargo 20 commits in 7e484fc1a766f56dbc95380f45719698e0c82749..9286a1beba5b28b115bad67de2ae91fb1c61eb0b 2022-10-27 15:20:57 +0000 to 2022-11-04 06:41:49 +0000 - chore: Upgrade dependencies (rust-lang/cargo#11328) - Clean more aggressively in CI (rust-lang/cargo#11335) - Remove remove_dir_all (rust-lang/cargo#11333) - test(publish): Cover more wait-for-publish cases (rust-lang/cargo#11327) - Revert rust-lang/cargo#11183 (rust-lang/cargo#11331) - fix(semver-check): adapt to a different error for variant not covered (rust-lang/cargo#11332) - Update curl-sys (rust-lang/cargo#11326) - Mention fix on build script deadlock (rust-lang/cargo#11325) - Make cargo forward pre-existing CARGO if set (rust-lang/cargo#11285) - Clean up workspace dependencies after cargo remove (rust-lang/cargo#11242) - Update the outdated link for rust-semverver (rust-lang/cargo#11322) - Fix broken link to compilation entry point (rust-lang/cargo#11317) - Only remove fingerprints and build script artifacts of the requested package (rust-lang/cargo#10621) - Newer anyhow features are required (rust-lang/cargo#11316) - Clean stale git temp files (rust-lang/cargo#11308) - Report crate size on package and publish (rust-lang/cargo#11270) - add a note that some warnings (and/or errors) can be auto-fixed (rust-lang/cargo#10989) - Update libcurl (rust-lang/cargo#11307) - artifact deps shoud works when target field specified coexists with `optional = true` (rust-lang/cargo#11183) - Fix singular verb in tests page (rust-lang/cargo#11300) --- Cargo.lock | 91 ++++++++++++++++++++++++++++++++++++++----------- src/tools/cargo | 2 +- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b73a4d6f2da50..55433a55a183c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,7 +427,6 @@ dependencies = [ "glob", "itertools", "lazy_static", - "remove_dir_all", "serde_json", "snapbox", "tar", @@ -449,7 +448,7 @@ dependencies = [ "jobserver", "libc", "log", - "miow", + "miow 0.4.0", "same-file", "shell-escape", "tempfile", @@ -815,7 +814,7 @@ dependencies = [ "lazy_static", "lazycell", "libc", - "miow", + "miow 0.3.7", "miropt-test-tools", "regex", "rustfix", @@ -840,7 +839,7 @@ dependencies = [ "lazy_static", "libc", "log", - "miow", + "miow 0.3.7", "regex", "rustfix", "serde", @@ -853,9 +852,9 @@ dependencies = [ [[package]] name = "concolor" -version = "0.0.8" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af" +checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37" dependencies = [ "atty", "bitflags", @@ -864,9 +863,9 @@ dependencies = [ [[package]] name = "concolor-query" -version = "0.0.5" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449" +checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" [[package]] name = "content_inspector" @@ -1036,9 +1035,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" dependencies = [ "curl-sys", "libc", @@ -1051,9 +1050,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.55+curl-7.83.1" +version = "0.4.59+curl-7.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" +checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407" dependencies = [ "cc", "libc", @@ -2257,6 +2256,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "miow" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7377f7792b3afb6a3cba68daa54ca23c032137010460d667fda53a8d66be00e" +dependencies = [ + "windows-sys 0.28.0", +] + [[package]] name = "miri" version = "0.1.0" @@ -2541,7 +2549,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4628,9 +4636,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e" [[package]] name = "snapbox" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7" +checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293" dependencies = [ "concolor", "content_inspector", @@ -5475,43 +5483,86 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" +dependencies = [ + "windows_aarch64_msvc 0.28.0", + "windows_i686_gnu 0.28.0", + "windows_i686_msvc 0.28.0", + "windows_x86_64_gnu 0.28.0", + "windows_x86_64_msvc 0.28.0", +] + [[package]] name = "windows-sys" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows_aarch64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_i686_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_x86_64_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" diff --git a/src/tools/cargo b/src/tools/cargo index 7e484fc1a766f..9286a1beba5b2 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 7e484fc1a766f56dbc95380f45719698e0c82749 +Subproject commit 9286a1beba5b28b115bad67de2ae91fb1c61eb0b From de63d6289737cdb1ff16b0dd1903a2904f345b61 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 27 Oct 2022 07:11:15 +0000 Subject: [PATCH 128/482] Correctly resolve Inherent Associated Types --- .../rustc_hir_analysis/src/astconv/mod.rs | 14 +++++++++ src/test/ui/assoc-inherent.rs | 20 ------------- src/test/ui/assoc-inherent.stderr | 17 ----------- .../assoc-inherent-no-body.rs | 10 +++++++ .../assoc-inherent-no-body.stderr | 10 +++++++ .../assoc-inherent-use.rs | 14 +++++++++ .../ui/resolve/resolve-self-in-impl.stderr | 30 +++++++++---------- 7 files changed, 63 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/assoc-inherent.rs delete mode 100644 src/test/ui/assoc-inherent.stderr create mode 100644 src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs create mode 100644 src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr create mode 100644 src/test/ui/associated-inherent-types/assoc-inherent-use.rs diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 7747ae14a24b2..9ad1d2bc542d7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1910,6 +1910,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } + + // see if we can satisfy using an inherent associated type + for impl_ in tcx.inherent_impls(adt_def.did()) { + let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind( + tcx, + assoc_ident, + ty::AssocKind::Type, + *impl_, + ); + if let Some(assoc_ty) = assoc_ty { + let ty = tcx.type_of(assoc_ty.def_id); + return Ok((ty, DefKind::AssocTy, assoc_ty.def_id)); + } + } } // Find the type of the associated item, and the trait where the associated diff --git a/src/test/ui/assoc-inherent.rs b/src/test/ui/assoc-inherent.rs deleted file mode 100644 index c579c962ffcc1..0000000000000 --- a/src/test/ui/assoc-inherent.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that inherent associated types work with -// inherent_associated_types feature gate. - -#![feature(inherent_associated_types)] -#![allow(incomplete_features)] - -struct Foo; - -impl Foo { - type Bar = isize; -} - -impl Foo { - type Baz; //~ ERROR associated type in `impl` without body -} - -fn main() { - let x : Foo::Bar; //~ERROR ambiguous associated type - x = 0isize; -} diff --git a/src/test/ui/assoc-inherent.stderr b/src/test/ui/assoc-inherent.stderr deleted file mode 100644 index b703453fa0334..0000000000000 --- a/src/test/ui/assoc-inherent.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: associated type in `impl` without body - --> $DIR/assoc-inherent.rs:14:5 - | -LL | type Baz; - | ^^^^^^^^- - | | - | help: provide a definition for the type: `= ;` - -error[E0223]: ambiguous associated type - --> $DIR/assoc-inherent.rs:18:13 - | -LL | let x : Foo::Bar; - | ^^^^^^^^ help: use fully-qualified syntax: `::Bar` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs new file mode 100644 index 0000000000000..71f65b92eae20 --- /dev/null +++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs @@ -0,0 +1,10 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo; + +impl Foo { + type Baz; //~ ERROR associated type in `impl` without body +} + +fn main() {} diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr new file mode 100644 index 0000000000000..387a5658da373 --- /dev/null +++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr @@ -0,0 +1,10 @@ +error: associated type in `impl` without body + --> $DIR/assoc-inherent-no-body.rs:7:5 + | +LL | type Baz; + | ^^^^^^^^- + | | + | help: provide a definition for the type: `= ;` + +error: aborting due to previous error + diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-use.rs b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs new file mode 100644 index 0000000000000..7ae425e2aaafb --- /dev/null +++ b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs @@ -0,0 +1,14 @@ +// check-pass +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo; + +impl Foo { + type Bar = isize; +} + +fn main() { + let x: Foo::Bar; + x = 0isize; +} diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr index 9f9ed68898f6c..b3042d413468a 100644 --- a/src/test/ui/resolve/resolve-self-in-impl.stderr +++ b/src/test/ui/resolve/resolve-self-in-impl.stderr @@ -1,40 +1,40 @@ error: `Self` is not valid in the self type of an impl block - --> $DIR/resolve-self-in-impl.rs:14:13 + --> $DIR/resolve-self-in-impl.rs:16:6 | -LL | impl Tr for Self {} - | ^^^^ +LL | impl Self {} + | ^^^^ | = note: replace `Self` with a different type error: `Self` is not valid in the self type of an impl block - --> $DIR/resolve-self-in-impl.rs:15:15 + --> $DIR/resolve-self-in-impl.rs:17:8 | -LL | impl Tr for S {} - | ^^^^ +LL | impl S {} + | ^^^^ | = note: replace `Self` with a different type error: `Self` is not valid in the self type of an impl block - --> $DIR/resolve-self-in-impl.rs:16:6 + --> $DIR/resolve-self-in-impl.rs:18:7 | -LL | impl Self {} - | ^^^^ +LL | impl (Self, Self) {} + | ^^^^ ^^^^ | = note: replace `Self` with a different type error: `Self` is not valid in the self type of an impl block - --> $DIR/resolve-self-in-impl.rs:17:8 + --> $DIR/resolve-self-in-impl.rs:14:13 | -LL | impl S {} - | ^^^^ +LL | impl Tr for Self {} + | ^^^^ | = note: replace `Self` with a different type error: `Self` is not valid in the self type of an impl block - --> $DIR/resolve-self-in-impl.rs:18:7 + --> $DIR/resolve-self-in-impl.rs:15:15 | -LL | impl (Self, Self) {} - | ^^^^ ^^^^ +LL | impl Tr for S {} + | ^^^^ | = note: replace `Self` with a different type From 0e588c03535e1a05dd3563b3649c82bda04b1bcc Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 27 Oct 2022 17:33:41 +0000 Subject: [PATCH 129/482] roll another resolution logic in rustdoc --- src/librustdoc/clean/mod.rs | 3 ++- .../rustdoc-ui/ambiguous-inherent-assoc-ty.rs | 5 +---- .../rustdoc-ui/ambiguous-inherent-assoc-ty.stderr | 15 --------------- 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8d38f2df0d85c..16e2d9a3cfc38 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1381,7 +1381,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id), // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s. ty::Error(_) => return Type::Infer, - _ => bug!("clean: expected associated type, found `{:?}`", ty), + // Otherwise, this is an inherent associated type. + _ => return clean_middle_ty(ty, cx, None), }; let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx); register_res(cx, trait_.res); diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs index e58bba6405853..94ea0e93bf637 100644 --- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs +++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs @@ -1,3 +1,4 @@ +// check-pass // This test ensures that rustdoc does not panic on inherented associated types // that are referred to without fully-qualified syntax. @@ -9,8 +10,4 @@ pub struct Struct; impl Struct { pub type AssocTy = usize; pub const AssocConst: Self::AssocTy = 42; - //~^ ERROR ambiguous associated type - //~| HELP use fully-qualified syntax - //~| ERROR ambiguous associated type - //~| HELP use fully-qualified syntax } diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr deleted file mode 100644 index b963b722f6620..0000000000000 --- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0223]: ambiguous associated type - --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 - | -LL | pub const AssocConst: Self::AssocTy = 42; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` - -error[E0223]: ambiguous associated type - --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 - | -LL | pub const AssocConst: Self::AssocTy = 42; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0223`. From 8e8770d768e9bfffc48cc2e90195e6fb9524589a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Fri, 28 Oct 2022 10:20:51 +0300 Subject: [PATCH 130/482] improve `filesearch::get_or_default_sysroot` r=ozkanonur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- Cargo.lock | 5 +- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- compiler/rustc_interface/Cargo.toml | 6 - compiler/rustc_interface/src/util.rs | 97 +------------- compiler/rustc_session/Cargo.toml | 7 + compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/filesearch.rs | 136 +++++++++++++++++--- compiler/rustc_session/src/session.rs | 2 +- src/tools/clippy/src/driver.rs | 79 +----------- src/tools/miri/src/bin/miri.rs | 70 ++-------- 10 files changed, 152 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55433a55a183c..f230f50212a3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3672,7 +3672,6 @@ dependencies = [ name = "rustc_interface" version = "0.0.0" dependencies = [ - "libc", "libloading", "rustc-rayon", "rustc-rayon-core", @@ -3715,7 +3714,6 @@ dependencies = [ "rustc_ty_utils", "smallvec", "tracing", - "winapi", ] [[package]] @@ -4135,6 +4133,7 @@ name = "rustc_session" version = "0.0.0" dependencies = [ "getopts", + "libc", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -4146,7 +4145,9 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "smallvec", "tracing", + "winapi", ] [[package]] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6f0a8d0a54cba..5a1ad792924fc 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1123,7 +1123,8 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { if path.exists() { return session_tlib; } else { - let default_sysroot = filesearch::get_or_default_sysroot(); + let default_sysroot = + filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); let default_tlib = filesearch::make_target_lib_path( &default_sysroot, sess.opts.target_triple.triple(), diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 6a4c5b4d37376..2e526733df974 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -48,12 +48,6 @@ rustc_resolve = { path = "../rustc_resolve" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } -[target.'cfg(unix)'.dependencies] -libc = "0.2" - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["libloaderapi"] } - [dev-dependencies] rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 519b8a7fc7c37..62ee72f988308 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -9,6 +9,7 @@ use rustc_session as session; use rustc_session::config::CheckCfg; use rustc_session::config::{self, CrateType}; use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; +use rustc_session::filesearch::sysroot_candidates; use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::parse::CrateConfig; use rustc_session::{early_error, filesearch, output, Session}; @@ -78,7 +79,7 @@ pub fn create_session( let bundle = match rustc_errors::fluent_bundle( sopts.maybe_sysroot.clone(), - sysroot_candidates(), + sysroot_candidates().to_vec(), sopts.unstable_opts.translate_lang.clone(), sopts.unstable_opts.translate_additional_ftl.as_deref(), sopts.unstable_opts.translate_directionality_markers, @@ -273,100 +274,6 @@ fn get_rustc_path_inner(bin_path: &str) -> Option { }) } -fn sysroot_candidates() -> Vec { - let target = session::config::host_triple(); - let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()]; - let path = current_dll_path().and_then(|s| s.canonicalize().ok()); - if let Some(dll) = path { - // use `parent` twice to chop off the file name and then also the - // directory containing the dll which should be either `lib` or `bin`. - if let Some(path) = dll.parent().and_then(|p| p.parent()) { - // The original `path` pointed at the `rustc_driver` crate's dll. - // Now that dll should only be in one of two locations. The first is - // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The - // other is the target's libdir, for example - // `$sysroot/lib/rustlib/$target/lib/*.dll`. - // - // We don't know which, so let's assume that if our `path` above - // ends in `$target` we *could* be in the target libdir, and always - // assume that we may be in the main libdir. - sysroot_candidates.push(path.to_owned()); - - if path.ends_with(target) { - sysroot_candidates.extend( - path.parent() // chop off `$target` - .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| p.parent()) // chop off `lib` - .map(|s| s.to_owned()), - ); - } - } - } - - return sysroot_candidates; - - #[cfg(unix)] - fn current_dll_path() -> Option { - use std::ffi::{CStr, OsStr}; - use std::os::unix::prelude::*; - - unsafe { - let addr = current_dll_path as usize as *mut _; - let mut info = mem::zeroed(); - if libc::dladdr(addr, &mut info) == 0 { - info!("dladdr failed"); - return None; - } - if info.dli_fname.is_null() { - info!("dladdr returned null pointer"); - return None; - } - let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); - let os = OsStr::from_bytes(bytes); - Some(PathBuf::from(os)) - } - } - - #[cfg(windows)] - fn current_dll_path() -> Option { - use std::ffi::OsString; - use std::io; - use std::os::windows::prelude::*; - use std::ptr; - - use winapi::um::libloaderapi::{ - GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - }; - - unsafe { - let mut module = ptr::null_mut(); - let r = GetModuleHandleExW( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - current_dll_path as usize as *mut _, - &mut module, - ); - if r == 0 { - info!("GetModuleHandleExW failed: {}", io::Error::last_os_error()); - return None; - } - let mut space = Vec::with_capacity(1024); - let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32); - if r == 0 { - info!("GetModuleFileNameW failed: {}", io::Error::last_os_error()); - return None; - } - let r = r as usize; - if r >= space.capacity() { - info!("our buffer was too small? {}", io::Error::last_os_error()); - return None; - } - space.set_len(r); - let os = OsString::from_wide(&space); - Some(PathBuf::from(os)) - } - } -} - fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> MakeBackendFn { // For now we only allow this function to be called once as it'll dlopen a // few things, which seems to work best if we only do that once. In diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 6b1eaa4d399d9..a052f29334169 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -17,3 +17,10 @@ rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } +smallvec = "1.8.1" + +[target.'cfg(unix)'.dependencies] +libc = "0.2" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi"] } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b8ad18c64dcf6..aece29ca0cbf6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2447,7 +2447,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let sysroot = match &sysroot_opt { Some(s) => s, None => { - tmp_buf = crate::filesearch::get_or_default_sysroot(); + tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); &tmp_buf } }; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index e8edb38f5038e..1b66773be6f08 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -1,5 +1,6 @@ //! A module for searching for libraries +use smallvec::{smallvec, SmallVec}; use std::env; use std::fs; use std::iter::FromIterator; @@ -62,9 +63,99 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")]) } +#[cfg(unix)] +fn current_dll_path() -> Result { + use std::ffi::{CStr, OsStr}; + use std::os::unix::prelude::*; + + unsafe { + let addr = current_dll_path as usize as *mut _; + let mut info = std::mem::zeroed(); + if libc::dladdr(addr, &mut info) == 0 { + return Err("dladdr failed".into()); + } + if info.dli_fname.is_null() { + return Err("dladdr returned null pointer".into()); + } + let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); + let os = OsStr::from_bytes(bytes); + Ok(PathBuf::from(os)) + } +} + +#[cfg(windows)] +fn current_dll_path() -> Result { + use std::ffi::OsString; + use std::io; + use std::os::windows::prelude::*; + use std::ptr; + + use winapi::um::libloaderapi::{ + GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + }; + + unsafe { + let mut module = ptr::null_mut(); + let r = GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + current_dll_path as usize as *mut _, + &mut module, + ); + if r == 0 { + return Err(format!("GetModuleHandleExW failed: {}", io::Error::last_os_error())); + } + let mut space = Vec::with_capacity(1024); + let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32); + if r == 0 { + return Err(format!("GetModuleFileNameW failed: {}", io::Error::last_os_error())); + } + let r = r as usize; + if r >= space.capacity() { + return Err(format!("our buffer was too small? {}", io::Error::last_os_error())); + } + space.set_len(r); + let os = OsString::from_wide(&space); + Ok(PathBuf::from(os)) + } +} + +pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { + let target = crate::config::host_triple(); + let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = + smallvec![get_or_default_sysroot().expect("Failed finding sysroot")]; + let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?)); + if let Ok(dll) = path { + // use `parent` twice to chop off the file name and then also the + // directory containing the dll which should be either `lib` or `bin`. + if let Some(path) = dll.parent().and_then(|p| p.parent()) { + // The original `path` pointed at the `rustc_driver` crate's dll. + // Now that dll should only be in one of two locations. The first is + // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The + // other is the target's libdir, for example + // `$sysroot/lib/rustlib/$target/lib/*.dll`. + // + // We don't know which, so let's assume that if our `path` above + // ends in `$target` we *could* be in the target libdir, and always + // assume that we may be in the main libdir. + sysroot_candidates.push(path.to_owned()); + + if path.ends_with(target) { + sysroot_candidates.extend( + path.parent() // chop off `$target` + .and_then(|p| p.parent()) // chop off `rustlib` + .and_then(|p| p.parent()) // chop off `lib` + .map(|s| s.to_owned()), + ); + } + } + } + + return sysroot_candidates; +} + /// This function checks if sysroot is found using env::args().next(), and if it -/// is not found, uses env::current_exe() to imply sysroot. -pub fn get_or_default_sysroot() -> PathBuf { +/// is not found, finds sysroot from current rustc_driver dll. +pub fn get_or_default_sysroot() -> Result { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: PathBuf) -> PathBuf { let path = fs::canonicalize(&path).unwrap_or(path); @@ -74,17 +165,32 @@ pub fn get_or_default_sysroot() -> PathBuf { fix_windows_verbatim_for_gcc(&path) } - // Use env::current_exe() to get the path of the executable following - // symlinks/canonicalizing components. - fn from_current_exe() -> PathBuf { - match env::current_exe() { - Ok(exe) => { - let mut p = canonicalize(exe); - p.pop(); - p.pop(); - p - } - Err(e) => panic!("failed to get current_exe: {e}"), + fn default_from_rustc_driver_dll() -> Result { + let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?; + + // `dll` will be in one of the following two: + // - compiler's libdir: $sysroot/lib/*.dll + // - target's libdir: $sysroot/lib/rustlib/$target/lib/*.dll + // + // use `parent` twice to chop off the file name and then also the + // directory containing the dll + let dir = dll.parent().and_then(|p| p.parent()).ok_or(format!( + "Could not move 2 levels upper using `parent()` on {}", + dll.display() + ))?; + + // if `dir` points target's dir, move up to the sysroot + if dir.ends_with(crate::config::host_triple()) { + dir.parent() // chop off `$target` + .and_then(|p| p.parent()) // chop off `rustlib` + .and_then(|p| p.parent()) // chop off `lib` + .map(|s| s.to_owned()) + .ok_or(format!( + "Could not move 3 levels upper using `parent()` on {}", + dir.display() + )) + } else { + Ok(dir.to_owned()) } } @@ -118,7 +224,5 @@ pub fn get_or_default_sysroot() -> PathBuf { } } - // Check if sysroot is found using env::args().next(), and if is not found, - // use env::current_exe() to imply sysroot. - from_env_args_next().unwrap_or_else(from_current_exe) + Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?)) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ec0a5b9d0d84f..103521983578b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1309,7 +1309,7 @@ pub fn build_session( let sysroot = match &sopts.maybe_sysroot { Some(sysroot) => sysroot.clone(), - None => filesearch::get_or_default_sysroot(), + None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"), }; let target_cfg = config::build_target_config(&sopts, target_override, &sysroot); diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index ae54b2078a65b..f24d3507823ec 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -23,8 +23,8 @@ use std::borrow::Cow; use std::env; use std::ops::Deref; use std::panic; -use std::path::{Path, PathBuf}; -use std::process::{exit, Command}; +use std::path::Path; +use std::process::exit; use std::sync::LazyLock; /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If @@ -210,17 +210,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { interface::try_print_query_stack(&handler, num_frames); } -fn toolchain_path(home: Option, toolchain: Option) -> Option { - home.and_then(|home| { - toolchain.map(|toolchain| { - let mut path = PathBuf::from(home); - path.push("toolchains"); - path.push(toolchain); - path - }) - }) -} - #[allow(clippy::too_many_lines)] pub fn main() { rustc_driver::init_rustc_env_logger(); @@ -228,51 +217,6 @@ pub fn main() { exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args: Vec = env::args().collect(); - // Get the sysroot, looking from most specific to this invocation to the least: - // - command line - // - runtime environment - // - SYSROOT - // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN - // - sysroot from rustc in the path - // - compile-time environment - // - SYSROOT - // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN - let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true); - let have_sys_root_arg = sys_root_arg.is_some(); - let sys_root = sys_root_arg - .map(PathBuf::from) - .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from)) - .or_else(|| { - let home = std::env::var("RUSTUP_HOME") - .or_else(|_| std::env::var("MULTIRUST_HOME")) - .ok(); - let toolchain = std::env::var("RUSTUP_TOOLCHAIN") - .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN")) - .ok(); - toolchain_path(home, toolchain) - }) - .or_else(|| { - Command::new("rustc") - .arg("--print") - .arg("sysroot") - .output() - .ok() - .and_then(|out| String::from_utf8(out.stdout).ok()) - .map(|s| PathBuf::from(s.trim())) - }) - .or_else(|| option_env!("SYSROOT").map(PathBuf::from)) - .or_else(|| { - let home = option_env!("RUSTUP_HOME") - .or(option_env!("MULTIRUST_HOME")) - .map(ToString::to_string); - let toolchain = option_env!("RUSTUP_TOOLCHAIN") - .or(option_env!("MULTIRUST_TOOLCHAIN")) - .map(ToString::to_string); - toolchain_path(home, toolchain) - }) - .map(|pb| pb.to_string_lossy().to_string()) - .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust"); - // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc" // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver // uses @@ -280,13 +224,7 @@ pub fn main() { orig_args.remove(pos); orig_args[0] = "rustc".to_string(); - // if we call "rustc", we need to pass --sysroot here as well - let mut args: Vec = orig_args.clone(); - if !have_sys_root_arg { - args.extend(vec!["--sysroot".into(), sys_root]); - }; - - return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run(); + return rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks).run(); } if orig_args.iter().any(|a| a == "--version" || a == "-V") { @@ -309,14 +247,6 @@ pub fn main() { exit(0); } - // this conditional check for the --sysroot flag is there so users can call - // `clippy_driver` directly - // without having to pass --sysroot or anything - let mut args: Vec = orig_args.clone(); - if !have_sys_root_arg { - args.extend(vec!["--sysroot".into(), sys_root]); - }; - let mut no_deps = false; let clippy_args_var = env::var("CLIPPY_ARGS").ok(); let clippy_args = clippy_args_var @@ -345,10 +275,11 @@ pub fn main() { let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package); if clippy_enabled { + let mut args: Vec = orig_args.clone(); args.extend(clippy_args); rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run() } else { - rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run() + rustc_driver::RunCompiler::new(&orig_args, &mut RustcCallbacks { clippy_args_var }).run() } })) } diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index bd01ea655dd70..e673ea67dbc5b 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -216,76 +216,28 @@ fn init_late_loggers(tcx: TyCtxt<'_>) { } } -/// Returns the "default sysroot" that Miri will use for host things if no `--sysroot` flag is set. -/// Should be a compile-time constant. -fn host_sysroot() -> Option { - if option_env!("RUSTC_STAGE").is_some() { - // This is being built as part of rustc, and gets shipped with rustup. - // We can rely on the sysroot computation in librustc_session. - return None; - } - // For builds outside rustc, we need to ensure that we got a sysroot - // that gets used as a default. The sysroot computation in librustc_session would - // end up somewhere in the build dir (see `get_or_default_sysroot`). - // Taken from PR . - let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); - let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); - Some(match (home, toolchain) { - (Some(home), Some(toolchain)) => { - // Check that at runtime, we are still in this toolchain (if there is any toolchain). - if let Some(toolchain_runtime) = - env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN")) - { - if toolchain_runtime != toolchain { - show_error!( - "This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\ - Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`." - ) - } - } - format!("{home}/toolchains/{toolchain}") - } - _ => option_env!("RUST_SYSROOT") - .unwrap_or_else(|| { - show_error!( - "To build Miri without rustup, set the `RUST_SYSROOT` env var at build time", - ) - }) - .to_owned(), - }) -} - /// Execute a compiler with the given CLI arguments and callbacks. fn run_compiler( mut args: Vec, target_crate: bool, callbacks: &mut (dyn rustc_driver::Callbacks + Send), ) -> ! { - // Make sure we use the right default sysroot. The default sysroot is wrong, - // because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`. - // - // Make sure we always call `host_sysroot` as that also does some sanity-checks - // of the environment we were built in and whether it matches what we are running in. - let host_default_sysroot = host_sysroot(); - // Now see if we even need to set something. - let sysroot_flag = "--sysroot"; - if !args.iter().any(|e| e == sysroot_flag) { - // No sysroot was set, let's see if we have a custom default we want to configure. - let default_sysroot = if target_crate { + if target_crate { + // Miri needs a custom sysroot for target crates. + // If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where + // that sysroot lives, and that is passed to rustc. + let sysroot_flag = "--sysroot"; + if !args.iter().any(|e| e == sysroot_flag) { // Using the built-in default here would be plain wrong, so we *require* // the env var to make sure things make sense. - Some(env::var("MIRI_SYSROOT").unwrap_or_else(|_| { + let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| { show_error!( "Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set" - ) - })) - } else { - host_default_sysroot - }; - if let Some(sysroot) = default_sysroot { - // We need to overwrite the default that librustc_session would compute. + ) + }); + args.push(sysroot_flag.to_owned()); - args.push(sysroot); + args.push(miri_sysroot); } } From 1af8e096278cf63b703e84488bbb21153f2ff0e5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 02:02:33 +0000 Subject: [PATCH 131/482] Remove some return-type booleans from FnCtxt --- compiler/rustc_hir_typeck/src/_match.rs | 6 +----- compiler/rustc_hir_typeck/src/check.rs | 5 ----- compiler/rustc_hir_typeck/src/closure.rs | 3 --- compiler/rustc_hir_typeck/src/coercion.rs | 3 ++- compiler/rustc_hir_typeck/src/expr.rs | 4 +++- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 11 ----------- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 8 ++++++++ compiler/rustc_hir_typeck/src/lib.rs | 2 +- 8 files changed, 15 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2b15d4dcd0848..8d39fa81165ea 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -491,11 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. } = self.type_var_origin(expected)? else { return None; }; - let sig = *self - .typeck_results - .borrow() - .liberated_fn_sigs() - .get(hir::HirId::make_owner(self.body_id.owner.def_id))?; + let sig = self.body_fn_sig()?; let substs = sig.output().walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index b706d786b5251..80147d9009113 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -31,13 +31,11 @@ pub(super) fn check_fn<'a, 'tcx>( fn_id: hir::HirId, body: &'tcx hir::Body<'tcx>, can_be_generator: Option, - return_type_pre_known: bool, ) -> (FnCtxt<'a, 'tcx>, Option>) { // Create the function context. This is either derived from scratch or, // in the case of closures, based on the outer context. let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id)); - fcx.return_type_pre_known = return_type_pre_known; let tcx = fcx.tcx; let hir = tcx.hir(); @@ -51,9 +49,6 @@ pub(super) fn check_fn<'a, 'tcx>( decl.output.span(), param_env, )); - // If we replaced declared_ret_ty with infer vars, then we must be inferring - // an opaque type, so set a flag so we can improve diagnostics. - fcx.return_type_has_opaque = ret_ty != declared_ret_ty; fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 14f6e7d36be2c..09df50c76b738 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -83,8 +83,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); - let return_type_pre_known = !liberated_sig.output().is_ty_infer(); - let generator_types = check_fn( self, self.param_env.without_const(), @@ -93,7 +91,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.hir_id, body, gen, - return_type_pre_known, ) .1; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 86597a703e833..e8bf299b0378e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1782,7 +1782,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // may occur at the first return expression we see in the closure // (if it conflicts with the declared return type). Skip adding a // note in this case, since it would be incorrect. - && !fcx.return_type_pre_known + && let Some(fn_sig) = fcx.body_fn_sig() + && fn_sig.output().is_ty_var() { err.span_note( sp, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9fde62a81a1a6..14d36d3777607 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -840,7 +840,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_expr_ty, ); - if self.return_type_has_opaque { + if let Some(fn_sig) = self.body_fn_sig() + && fn_sig.output().has_opaque_types() + { // Point any obligations that were registered due to opaque type // inference at the return expression. self.select_obligations_where_possible(false, |errors| { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c36c01e1b46d0..7029151011573 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -118,15 +118,6 @@ pub struct FnCtxt<'a, 'tcx> { pub(super) enclosing_breakables: RefCell>, pub(super) inh: &'a Inherited<'tcx>, - - /// True if the function or closure's return type is known before - /// entering the function/closure, i.e. if the return type is - /// either given explicitly or inferred from, say, an `Fn*` trait - /// bound. Used for diagnostic purposes only. - pub(super) return_type_pre_known: bool, - - /// True if the return type has an Opaque type - pub(super) return_type_has_opaque: bool, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -151,8 +142,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { by_id: Default::default(), }), inh, - return_type_pre_known: true, - return_type_has_opaque: false, } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 4db9c56f98fee..e3b3fb499b16a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -22,6 +22,14 @@ use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + pub(crate) fn body_fn_sig(&self) -> Option> { + self.typeck_results + .borrow() + .liberated_fn_sigs() + .get(self.tcx.hir().get_parent_node(self.body_id)) + .copied() + } + pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) { err.span_suggestion_short( span.shrink_to_hi(), diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 959c54866453d..d1762598a5206 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -250,7 +250,7 @@ fn typeck_with_fallback<'tcx>( param_env, fn_sig, ); - check_fn(&inh, param_env, fn_sig, decl, id, body, None, true).0 + check_fn(&inh, param_env, fn_sig, decl, id, body, None).0 } else { let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); let expected_type = body_ty From e1aed9ef11b592fe91878f19ccd0b817179815b9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 02:13:27 +0000 Subject: [PATCH 132/482] Remove has_errors from FnCtxt --- compiler/rustc_hir_typeck/src/expr.rs | 2 -- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 8 +------ compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 ---- src/test/ui/error-codes/E0767.rs | 3 ++- src/test/ui/error-codes/E0767.stderr | 21 +++++++++++++++---- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 14d36d3777607..682dbab56bc15 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and has_errors flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); let ty = ensure_sufficient_stack(|| match &expr.kind { hir::ExprKind::Path( @@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7c22eaf18f855..7563c543d3f19 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().node_types_mut().insert(id, ty); if ty.references_error() { - self.has_errors.set(true); self.set_tainted_by_errors(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8e0fcb56c7f37..e1955d838f253 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); match stmt.kind { hir::StmtKind::Local(l) => { @@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and `has_error` flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); } pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { @@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.diverges.set(prev_diverges); } - let mut ty = ctxt.coerce.unwrap().complete(self); - - if self.has_errors.get() || ty.references_error() { - ty = self.tcx.ty_error() - } + let ty = ctxt.coerce.unwrap().complete(self); self.write_ty(blk.hir_id, ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 7029151011573..72388baa261ea 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -112,9 +112,6 @@ pub struct FnCtxt<'a, 'tcx> { /// the diverges flag is set to something other than `Maybe`. pub(super) diverges: Cell, - /// Whether any child nodes have any type errors. - pub(super) has_errors: Cell, - pub(super) enclosing_breakables: RefCell>, pub(super) inh: &'a Inherited<'tcx>, @@ -136,7 +133,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { resume_yield_tys: None, ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), diverges: Cell::new(Diverges::Maybe), - has_errors: Cell::new(false), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), by_id: Default::default(), diff --git a/src/test/ui/error-codes/E0767.rs b/src/test/ui/error-codes/E0767.rs index 6c6cb746e6c75..14215d36a3833 100644 --- a/src/test/ui/error-codes/E0767.rs +++ b/src/test/ui/error-codes/E0767.rs @@ -1,6 +1,7 @@ -fn main () { +fn main() { 'a: loop { || { + //~^ ERROR mismatched types loop { break 'a; } //~ ERROR E0767 } } diff --git a/src/test/ui/error-codes/E0767.stderr b/src/test/ui/error-codes/E0767.stderr index 2429823306b6e..ee85247301c9c 100644 --- a/src/test/ui/error-codes/E0767.stderr +++ b/src/test/ui/error-codes/E0767.stderr @@ -1,14 +1,27 @@ error[E0767]: use of unreachable label `'a` - --> $DIR/E0767.rs:4:26 + --> $DIR/E0767.rs:5:26 | LL | 'a: loop { | -- unreachable label defined here -LL | || { +... LL | loop { break 'a; } | ^^ unreachable label `'a` | = note: labels are unreachable through functions, closures, async blocks and modules -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/E0767.rs:3:9 + | +LL | / || { +LL | | +LL | | loop { break 'a; } +LL | | } + | |_________^ expected `()`, found closure + | + = note: expected unit type `()` + found closure `[closure@$DIR/E0767.rs:3:9: 3:11]` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0767`. +Some errors have detailed explanations: E0308, E0767. +For more information about an error, try `rustc --explain E0308`. From 54fafb03d7fa4f671cf92b647230314cf35b8fcc Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 5 Nov 2022 01:11:50 +0000 Subject: [PATCH 133/482] Specify that `break` cannot be used outside of loop *or* labeled block --- compiler/rustc_error_messages/locales/en-US/passes.ftl | 10 ++++++++-- compiler/rustc_passes/src/errors.rs | 1 + compiler/rustc_passes/src/loops.rs | 2 +- src/test/ui/array-slice-vec/array-break-length.stderr | 4 ++-- src/test/ui/closures/closure-array-break-length.stderr | 4 ++-- src/test/ui/error-codes/E0268.stderr | 4 ++-- src/test/ui/for-loop-while/break-outside-loop.stderr | 8 ++++---- src/test/ui/issues/issue-28105.stderr | 4 ++-- src/test/ui/issues/issue-43162.stderr | 8 ++++---- src/test/ui/issues/issue-50576.stderr | 8 ++++---- src/test/ui/issues/issue-50581.stderr | 4 ++-- src/test/ui/issues/issue-83048.rs | 2 +- src/test/ui/issues/issue-83048.stderr | 4 ++-- src/test/ui/track-diagnostics/track.stderr | 4 ++-- 14 files changed, 37 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 88286c15f9ea4..5239ff9dc0571 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -451,8 +451,14 @@ passes_break_inside_async_block = .async_block_label = enclosing `async` block passes_outside_loop = - `{$name}` outside of a loop - .label = cannot `{$name}` outside of a loop + `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + .label = cannot `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } passes_unlabeled_in_labeled_block = unlabeled `{$cf_type}` inside of a labeled block diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index d8bed700f520a..1dbf0d642e2af 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -956,6 +956,7 @@ pub struct OutsideLoop<'a> { #[label] pub span: Span, pub name: &'a str, + pub is_break: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 077194ec687bf..b4cf19e4a34f6 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -193,7 +193,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name }); } Normal | AnonConst => { - self.sess.emit_err(OutsideLoop { span, name }); + self.sess.emit_err(OutsideLoop { span, name, is_break: name == "break" }); } } } diff --git a/src/test/ui/array-slice-vec/array-break-length.stderr b/src/test/ui/array-slice-vec/array-break-length.stderr index 93f1c238bcc47..2df7b6d7f63c6 100644 --- a/src/test/ui/array-slice-vec/array-break-length.stderr +++ b/src/test/ui/array-slice-vec/array-break-length.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/array-break-length.rs:3:17 | LL | |_: [_; break]| {} - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error[E0268]: `continue` outside of a loop --> $DIR/array-break-length.rs:7:17 diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr index 2b8ab9bfc4414..7e0b0027a6f09 100644 --- a/src/test/ui/closures/closure-array-break-length.stderr +++ b/src/test/ui/closures/closure-array-break-length.stderr @@ -10,11 +10,11 @@ error[E0268]: `continue` outside of a loop LL | while |_: [_; continue]| {} {} | ^^^^^^^^ cannot `continue` outside of a loop -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/closure-array-break-length.rs:6:19 | LL | while |_: [_; break]| {} {} - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr index c926f9e487494..6422e8a9490e9 100644 --- a/src/test/ui/error-codes/E0268.stderr +++ b/src/test/ui/error-codes/E0268.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/E0268.rs:2:5 | LL | break; - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to previous error diff --git a/src/test/ui/for-loop-while/break-outside-loop.stderr b/src/test/ui/for-loop-while/break-outside-loop.stderr index 287bf9af62e49..9092f34df3549 100644 --- a/src/test/ui/for-loop-while/break-outside-loop.stderr +++ b/src/test/ui/for-loop-while/break-outside-loop.stderr @@ -9,11 +9,11 @@ LL | break 'lab; | = note: labels are unreachable through functions, closures, async blocks and modules -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/break-outside-loop.rs:10:15 | LL | let pth = break; - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error[E0268]: `continue` outside of a loop --> $DIR/break-outside-loop.rs:11:17 @@ -38,11 +38,11 @@ LL | if cond() { break } LL | if cond() { continue } | ^^^^^^^^ cannot `continue` inside of a closure -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/break-outside-loop.rs:24:25 | LL | let unconstrained = break; - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error[E0267]: `break` inside of a closure --> $DIR/break-outside-loop.rs:30:13 diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr index 42ed838d7c037..f450256f3ecf5 100644 --- a/src/test/ui/issues/issue-28105.stderr +++ b/src/test/ui/issues/issue-28105.stderr @@ -4,11 +4,11 @@ error[E0268]: `continue` outside of a loop LL | continue | ^^^^^^^^ cannot `continue` outside of a loop -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-28105.rs:6:5 | LL | break - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index a443db40732ac..40d9200058ed1 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -1,14 +1,14 @@ -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-43162.rs:3:5 | LL | break true; - | ^^^^^^^^^^ cannot `break` outside of a loop + | ^^^^^^^^^^ cannot `break` outside of a loop or labeled block -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-43162.rs:7:5 | LL | break {}; - | ^^^^^^^^ cannot `break` outside of a loop + | ^^^^^^^^ cannot `break` outside of a loop or labeled block error[E0308]: mismatched types --> $DIR/issue-43162.rs:1:13 diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr index 9fea1411080f5..4ec22fde9106d 100644 --- a/src/test/ui/issues/issue-50576.stderr +++ b/src/test/ui/issues/issue-50576.stderr @@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L` LL | |bool: [u8; break 'L]| 0; | ^^ undeclared label `'L` -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-50576.rs:2:17 | LL | |bool: [u8; break 'L]| 0; - | ^^^^^^^^ cannot `break` outside of a loop + | ^^^^^^^^ cannot `break` outside of a loop or labeled block -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-50576.rs:5:16 | LL | Vec::<[u8; break]>::new(); - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr index 35d6fc49cedc8..07b6df072cb44 100644 --- a/src/test/ui/issues/issue-50581.stderr +++ b/src/test/ui/issues/issue-50581.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-50581.rs:2:14 | LL | |_: [u8; break]| (); - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to previous error diff --git a/src/test/ui/issues/issue-83048.rs b/src/test/ui/issues/issue-83048.rs index 520ae974398b4..8e4fb6eae9dff 100644 --- a/src/test/ui/issues/issue-83048.rs +++ b/src/test/ui/issues/issue-83048.rs @@ -1,5 +1,5 @@ // compile-flags: -Z unpretty=thir-tree pub fn main() { - break; //~ ERROR: `break` outside of a loop [E0268] + break; //~ ERROR: `break` outside of a loop or labeled block [E0268] } diff --git a/src/test/ui/issues/issue-83048.stderr b/src/test/ui/issues/issue-83048.stderr index 62d67d75844a4..dade9e4695035 100644 --- a/src/test/ui/issues/issue-83048.stderr +++ b/src/test/ui/issues/issue-83048.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/issue-83048.rs:4:5 | LL | break; - | ^^^^^ cannot `break` outside of a loop + | ^^^^^ cannot `break` outside of a loop or labeled block error: aborting due to previous error diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr index ba26cf7c7454b..8256c1f5f0ff2 100644 --- a/src/test/ui/track-diagnostics/track.stderr +++ b/src/test/ui/track-diagnostics/track.stderr @@ -5,11 +5,11 @@ LL | break rust | ^^^^ not found in this scope -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC -error[E0268]: `break` outside of a loop +error[E0268]: `break` outside of a loop or labeled block --> $DIR/track.rs:LL:CC | LL | break rust - | ^^^^^^^^^^ cannot `break` outside of a loop + | ^^^^^^^^^^ cannot `break` outside of a loop or labeled block -Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? From 8bcab9b575e2837b60e985cf41a5ff4efd358519 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Fri, 4 Nov 2022 20:05:22 -0700 Subject: [PATCH 134/482] Small round of typo fixes Signed-off-by: Alex Saveau --- library/core/src/cell.rs | 2 +- library/core/src/error.md | 2 +- library/std/src/f32.rs | 2 +- library/std/src/f64.rs | 2 +- library/std/src/sys/windows/c.rs | 2 +- library/std/src/sys/windows/pipe.rs | 9 +++++---- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 7bf32cb0d98f2..e6a11218139d9 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1856,7 +1856,7 @@ impl fmt::Display for RefMut<'_, T> { /// } /// ``` /// -/// Coverting in the other direction from a `&mut T` +/// Converting in the other direction from a `&mut T` /// to an `&UnsafeCell` is allowed: /// /// ```rust diff --git a/library/core/src/error.md b/library/core/src/error.md index 891abebbfd39b..78808d489b25a 100644 --- a/library/core/src/error.md +++ b/library/core/src/error.md @@ -46,7 +46,7 @@ These functions are equivalent, they either return the inner value if the `Result` is `Ok` or panic if the `Result` is `Err` printing the inner error as the source. The only difference between them is that with `expect` you provide a panic error message to be printed alongside the source, whereas -`unwrap` has a default message indicating only that you unwraped an `Err`. +`unwrap` has a default message indicating only that you unwrapped an `Err`. Of the two, `expect` is generally preferred since its `msg` field allows you to convey your intent and assumptions which makes tracking down the source diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 3dd5b12507fb2..dafcd87674412 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -275,7 +275,7 @@ impl f32 { /// This result is not an element of the function's codomain, but it is the /// closest floating point number in the real numbers and thus fulfills the /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` - /// approximatively. + /// approximately. /// /// # Examples /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 31351a87978c9..77048f9a28f25 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -275,7 +275,7 @@ impl f64 { /// This result is not an element of the function's codomain, but it is the /// closest floating point number in the real numbers and thus fulfills the /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` - /// approximatively. + /// approximately. /// /// # Examples /// diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index fc2dc42833d07..81461de4f721f 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -363,7 +363,7 @@ impl IO_STATUS_BLOCK { pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn( dwErrorCode: DWORD, - dwNumberOfBytesTransfered: DWORD, + dwNumberOfBytesTransferred: DWORD, lpOverlapped: *mut OVERLAPPED, ); diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 013c776c476c3..9f26acc45205c 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -324,17 +324,18 @@ impl AnonPipe { let mut async_result: Option = None; struct AsyncResult { error: u32, - transfered: u32, + transferred: u32, } // STEP 3: The callback. unsafe extern "system" fn callback( dwErrorCode: u32, - dwNumberOfBytesTransfered: u32, + dwNumberOfBytesTransferred: u32, lpOverlapped: *mut c::OVERLAPPED, ) { // Set `async_result` using a pointer smuggled through `hEvent`. - let result = AsyncResult { error: dwErrorCode, transfered: dwNumberOfBytesTransfered }; + let result = + AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred }; *(*lpOverlapped).hEvent.cast::>() = Some(result); } @@ -365,7 +366,7 @@ impl AnonPipe { // STEP 4: Return the result. // `async_result` is always `Some` at this point match result.error { - c::ERROR_SUCCESS => Ok(result.transfered as usize), + c::ERROR_SUCCESS => Ok(result.transferred as usize), error => Err(io::Error::from_raw_os_error(error as _)), } } From 20c3c6b78cc04aee2ad5b6fe8d4da9f3b5a513b5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Oct 2022 12:28:03 +0200 Subject: [PATCH 135/482] [debuginfo] Make debuginfo type names for slices and str consistent. Before this PR, the compiler would emit the debuginfo name `slice$` for all kinds of slices, regardless of whether they are behind a reference or not and regardless of the kind of reference. As a consequence, the types `Foo<&[T]>`, `Foo<[T]>`, and `Foo<&mut [T]>` would end up with the same type name `Foo >` in debuginfo, making it impossible to disambiguate between them by name. Similarly, `&str` would get the name `str` in debuginfo, so the debuginfo name for `Foo` and `Foo<&str>` would be the same. In contrast, `*const [bool]` and `*mut [bool]` would be `ptr_const$ >` and `ptr_mut$ >`, i.e. the encoding does not lose information about the type. This PR removes all special handling for slices and `str`. The types `&[bool]`, `&mut [bool]`, and `&str` thus get the names `ref$ >`, `ref_mut$ >`, and `ref$` respectively -- as one would expect. --- .../src/debuginfo/type_names.rs | 26 +++++++++---------- src/etc/natvis/intrinsic.natvis | 12 +++++++-- src/etc/natvis/liballoc.natvis | 8 +++--- src/test/debuginfo/basic-types.rs | 8 +++--- src/test/debuginfo/msvc-pretty-enums.rs | 6 ++--- src/test/debuginfo/msvc-scalarpair-params.rs | 4 +-- src/test/debuginfo/pretty-std.rs | 4 +-- src/test/debuginfo/rc_arc.rs | 8 +++--- src/test/debuginfo/result-types.rs | 6 ++--- src/test/debuginfo/type-names.rs | 10 +++---- src/test/debuginfo/unsized.rs | 12 ++++----- 11 files changed, 56 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index e05646e1e86a4..8647fbace2a75 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -59,7 +59,13 @@ fn push_debuginfo_type_name<'tcx>( match *t.kind() { ty::Bool => output.push_str("bool"), ty::Char => output.push_str("char"), - ty::Str => output.push_str("str"), + ty::Str => { + if cpp_like_debuginfo { + output.push_str("str$") + } else { + output.push_str("str") + } + } ty::Never => { if cpp_like_debuginfo { output.push_str("never$"); @@ -152,25 +158,19 @@ fn push_debuginfo_type_name<'tcx>( } } ty::Ref(_, inner_type, mutbl) => { - // Slices and `&str` are treated like C++ pointers when computing debug - // info for MSVC debugger. However, wrapping these types' names in a synthetic type - // causes the .natvis engine for WinDbg to fail to display their data, so we opt these - // types out to aid debugging in MSVC. - let is_slice_or_str = matches!(*inner_type.kind(), ty::Slice(_) | ty::Str); - - if !cpp_like_debuginfo { - output.push('&'); - output.push_str(mutbl.prefix_str()); - } else if !is_slice_or_str { + if cpp_like_debuginfo { match mutbl { Mutability::Not => output.push_str("ref$<"), Mutability::Mut => output.push_str("ref_mut$<"), } + } else { + output.push('&'); + output.push_str(mutbl.prefix_str()); } push_debuginfo_type_name(tcx, inner_type, qualified, output, visited); - if cpp_like_debuginfo && !is_slice_or_str { + if cpp_like_debuginfo { push_close_angle_bracket(cpp_like_debuginfo, output); } } @@ -195,7 +195,7 @@ fn push_debuginfo_type_name<'tcx>( } ty::Slice(inner_type) => { if cpp_like_debuginfo { - output.push_str("slice$<"); + output.push_str("slice2$<"); } else { output.push('['); } diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 277e57aaf6fc5..8c16a562e349e 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -1,6 +1,10 @@  - + + + + + {(char*)data_ptr,[length]s8} (char*)data_ptr,[length]s8 @@ -15,7 +19,11 @@ - + + + + + {{ len={length} }} length diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index bf6c02b91461a..41f4a3767f599 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -85,7 +85,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -115,7 +115,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -144,7 +144,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length @@ -173,7 +173,7 @@ - + {{ len={ptr.pointer.length} }} ptr.pointer.length diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs index 07d33be2a071f..9e82f0714690e 100644 --- a/src/test/debuginfo/basic-types.rs +++ b/src/test/debuginfo/basic-types.rs @@ -47,7 +47,6 @@ // gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13} // gdbr-check:$15 = "Hello, World!" - // === LLDB TESTS ================================================================================== // lldb-command:run @@ -96,7 +95,6 @@ // lldbg-check:[...]$12 = 3.5 // lldbr-check:(f64) f64 = 3.5 - // === CDB TESTS =================================================================================== // cdb-command:g @@ -131,7 +129,7 @@ // cdb-command:.enable_unicode 1 // FIXME(#88840): The latest version of the Windows SDK broke the visualizer for str. // cdb-command:dx s -// cdb-check:s : [...] [Type: str] +// cdb-check:s : [...] [Type: ref$] #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] @@ -156,4 +154,6 @@ fn main() { _zzz(); // #break } -fn _zzz() {()} +fn _zzz() { + () +} diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs index 7f1be6f27847c..d66e4c660f7b5 100644 --- a/src/test/debuginfo/msvc-pretty-enums.rs +++ b/src/test/debuginfo/msvc-pretty-enums.rs @@ -116,13 +116,13 @@ // cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$] // cdb-command: dx -r3 niche_w_fields_std_result_ok,d -// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$,alloc::alloc::Global>,u64> >] -// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box,alloc::alloc::Global>] +// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$,alloc::alloc::Global>,u64> >] +// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box,alloc::alloc::Global>] // cdb-check: [+0x[...]] data_ptr : [...] // cdb-check: [+0x[...]] length : 3 [...] // cdb-command: dx -r3 niche_w_fields_std_result_err,d -// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$,alloc::alloc::Global>,u64> >] +// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$,alloc::alloc::Global>,u64> >] // cdb-check: [+0x[...]] __0 : 789 [Type: unsigned __int64] // cdb-command: dx -r2 arbitrary_discr1,d diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs index 9630952cbaae0..ae67f6981519e 100644 --- a/src/test/debuginfo/msvc-scalarpair-params.rs +++ b/src/test/debuginfo/msvc-scalarpair-params.rs @@ -38,14 +38,14 @@ // cdb-command: g // cdb-command: dx s -// cdb-check:s : "this is a static str" [Type: str] +// cdb-check:s : "this is a static str" [Type: ref$] // cdb-check: [len] : 0x14 [Type: unsigned [...]] // cdb-check: [chars] // cdb-command: g // cdb-command: dx s -// cdb-check:s : { len=0x5 } [Type: slice$] +// cdb-check:s : { len=0x5 } [Type: ref$ >] // cdb-check: [len] : 0x5 [Type: unsigned [...]] // cdb-check: [0] : 0x1 [Type: unsigned char] // cdb-check: [1] : 0x2 [Type: unsigned char] diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs index a51b37205e8aa..d8c6344e0b6ac 100644 --- a/src/test/debuginfo/pretty-std.rs +++ b/src/test/debuginfo/pretty-std.rs @@ -69,7 +69,7 @@ // cdb-command: g // cdb-command: dx slice,d -// cdb-check:slice,d : { len=4 } [Type: slice$] +// cdb-check:slice,d : { len=4 } [Type: ref$ >] // cdb-check: [len] : 4 [Type: [...]] // cdb-check: [0] : 0 [Type: int] // cdb-check: [1] : 1 [Type: int] @@ -86,7 +86,7 @@ // cdb-check: [3] : 7 [Type: unsigned __int64] // cdb-command: dx str_slice -// cdb-check:str_slice : "IAMA string slice!" [Type: str] +// cdb-check:str_slice : "IAMA string slice!" [Type: ref$] // cdb-command: dx string // cdb-check:string : "IAMA string!" [Type: [...]::String] diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs index c05c565d95634..5d5492d721777 100644 --- a/src/test/debuginfo/rc_arc.rs +++ b/src/test/debuginfo/rc_arc.rs @@ -57,7 +57,7 @@ // cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] // cdb-command:dx slice_rc,d -// cdb-check:slice_rc,d : { len=3 } [Type: alloc::rc::Rc >] +// cdb-check:slice_rc,d : { len=3 } [Type: alloc::rc::Rc >] // cdb-check: [Length] : 3 [Type: [...]] // cdb-check: [Reference count] : 41 [Type: core::cell::Cell] // cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] @@ -66,7 +66,7 @@ // cdb-check: [2] : 3 [Type: u32] // cdb-command:dx slice_rc_weak,d -// cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rc::Weak >] +// cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rc::Weak >] // cdb-check: [Length] : 3 [Type: [...]] // cdb-check: [Reference count] : 41 [Type: core::cell::Cell] // cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] @@ -85,7 +85,7 @@ // cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] // cdb-command:dx slice_arc,d -// cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc >] +// cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc >] // cdb-check: [Length] : 3 [Type: [...]] // cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize] // cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] @@ -94,7 +94,7 @@ // cdb-check: [2] : 6 [Type: u32] // cdb-command:dx slice_arc_weak,d -// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak >] +// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak >] // cdb-check: [Length] : 3 [Type: [...]] // cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize] // cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs index cdac47a784d94..f1944fa38d27e 100644 --- a/src/test/debuginfo/result-types.rs +++ b/src/test/debuginfo/result-types.rs @@ -7,12 +7,12 @@ // cdb-command: g // cdb-command: dx x,d -// cdb-check:x,d : Ok [Type: enum2$ >] +// cdb-check:x,d : Ok [Type: enum2$ > >] // cdb-check: [...] __0 : -3 [Type: int] // cdb-command: dx y -// cdb-check:y : Err [Type: enum2$ >] -// cdb-check: [...] __0 : "Some error message" [Type: str] +// cdb-check:y : Err [Type: enum2$ > >] +// cdb-check: [...] __0 : "Some error message" [Type: ref$] fn main() { let x: Result = Ok(-3); diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 9cc99d7767c1f..d7b79a845d254 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -95,7 +95,7 @@ // gdb-check:type = &[usize] // gdb-command:whatis slice2 -// gdb-check:type = &[type_names::mod1::Enum2] +// gdb-check:type = &mut [type_names::mod1::Enum2] // TRAITS // gdb-command:whatis box_trait @@ -218,8 +218,8 @@ // cdb-check:struct alloc::vec::Vec vec1 = [...] // cdb-check:struct alloc::vec::Vec,alloc::alloc::Global> vec2 = [...] // cdb-command:dv /t slice* -// cdb-check:struct slice$ slice1 = [...] -// cdb-check:struct slice$ > slice2 = [...] +// cdb-check:struct ref$ > slice1 = [...] +// cdb-check:struct ref_mut$ > > slice2 = [...] // TRAITS // cdb-command:dv /t *_trait @@ -417,8 +417,8 @@ fn main() { let vec1 = vec![0_usize, 2, 3]; let slice1 = &*vec1; - let vec2 = vec![mod1::Enum2::Variant2(Struct1)]; - let slice2 = &*vec2; + let mut vec2 = vec![mod1::Enum2::Variant2(Struct1)]; + let slice2 = &mut *vec2; // Trait Objects let box_trait = Box::new(0_isize) as Box; diff --git a/src/test/debuginfo/unsized.rs b/src/test/debuginfo/unsized.rs index 7cb0002ca5125..b1ec9b0683059 100644 --- a/src/test/debuginfo/unsized.rs +++ b/src/test/debuginfo/unsized.rs @@ -32,13 +32,13 @@ // cdb-command: g // cdb-command:dx a -// cdb-check:a [Type: ref$ > >] -// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo > *] +// cdb-check:a [Type: ref$ > >] +// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo > *] // cdb-check: [...] length : 0x4 [Type: unsigned [...]int[...] // cdb-command:dx b -// cdb-check:b [Type: ref$ > > >] -// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo > > *] +// cdb-check:b [Type: ref$ > > >] +// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo > > *] // cdb-check: [...] length : 0x4 [Type: unsigned [...]int[...] // cdb-command:dx c @@ -53,8 +53,8 @@ // cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[3]] // cdb-command:dx tuple_slice -// cdb-check:tuple_slice [Type: ref$ > >] -// cdb-check: [+0x000] data_ptr : 0x[...] [Type: tuple$ > *] +// cdb-check:tuple_slice [Type: ref$ > >] +// cdb-check: [+0x000] data_ptr : 0x[...] [Type: tuple$ > *] // cdb-check: [...] length : 0x2 [Type: unsigned [...]int[...] // cdb-command:dx tuple_dyn From 4085420bf85a08584361d72f0c51f7452515a37a Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 1 Nov 2022 15:46:58 +0800 Subject: [PATCH 136/482] fix #103751: Fix capacity overflow issue during transmutability check --- compiler/rustc_transmute/src/layout/tree.rs | 4 +-- .../ui/transmute/transmute-padding-ice.rs | 29 +++++++++++++++++++ .../ui/transmute/transmute-padding-ice.stderr | 24 +++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/transmute/transmute-padding-ice.rs create mode 100644 src/test/ui/transmute/transmute-padding-ice.stderr diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 2bc6bc1fc23ae..30e20ba6f5868 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -436,8 +436,8 @@ pub(crate) mod rustc { // finally: padding let padding_span = trace_span!("adding trailing padding").entered(); - let padding_needed = layout_summary.total_size - variant_layout.size(); - if padding_needed > 0 { + if layout_summary.total_size > variant_layout.size() { + let padding_needed = layout_summary.total_size - variant_layout.size(); tree = tree.then(Self::padding(padding_needed)); }; drop(padding_span); diff --git a/src/test/ui/transmute/transmute-padding-ice.rs b/src/test/ui/transmute/transmute-padding-ice.rs new file mode 100644 index 0000000000000..a1be7075a8a03 --- /dev/null +++ b/src/test/ui/transmute/transmute-padding-ice.rs @@ -0,0 +1,29 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, + >, + { + } +} + +fn test() { + #[repr(C, align(2))] + struct A(u8, u8); + + #[repr(C)] + struct B(u8, u8); + + assert::is_maybe_transmutable::(); + //~^ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmute/transmute-padding-ice.stderr b/src/test/ui/transmute/transmute-padding-ice.stderr new file mode 100644 index 0000000000000..c9233890f7aa9 --- /dev/null +++ b/src/test/ui/transmute/transmute-padding-ice.stderr @@ -0,0 +1,24 @@ +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + --> $DIR/transmute-padding-ice.rs:27:40 + | +LL | assert::is_maybe_transmutable::(); + | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `A` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/transmute-padding-ice.rs:11:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom< + | ______________^ +LL | | Src, +LL | | Context, +LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, +LL | | >, + | |_________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From ba733632a7785385484d8fee2663a5fc86be4e8f Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Mon, 24 Oct 2022 01:28:55 -0700 Subject: [PATCH 137/482] rustdoc: add hash to filename of toolchain files All static files used by rustdoc are now stored in static.files/ and include a hash of their contents. They no longer include the contents of the --resource-suffix flag. This clarifies caching semantics. Anything in static.files can use Cache-Control: immutable because any updates will show up as a new URL. Invocation-specific files like crates-NN.js, search-index-NN.js, and sidebar-items-NN.js still get the resource suffix. The --disable-minification flag is removed because it would vary the output of static files based on invocation flags. Instead, for rustdoc development purposes it's preferable to symlink static files to a non-minified copy for quick iteration. --- src/librustdoc/config.rs | 13 +- src/librustdoc/html/layout.rs | 14 +- src/librustdoc/html/render/context.rs | 26 +- src/librustdoc/html/render/print_item.rs | 6 +- src/librustdoc/html/render/write_shared.rs | 288 +++--------------- src/librustdoc/html/static/css/rustdoc.css | 24 +- src/librustdoc/html/static/fonts/README.txt | 12 + src/librustdoc/html/static/js/main.js | 10 +- src/librustdoc/html/static/js/settings.js | 10 +- src/librustdoc/html/static/js/storage.js | 24 +- src/librustdoc/html/static_files.rs | 246 ++++++--------- src/librustdoc/html/templates/page.html | 56 ++-- src/librustdoc/html/templates/print_item.html | 2 +- src/librustdoc/lib.rs | 4 +- src/test/run-make/emit-shared-files/Makefile | 12 +- .../output-default.stdout | 4 +- src/test/rustdoc/static-root-path.rs | 12 +- src/tools/rustdoc-js/tester.js | 7 +- 18 files changed, 264 insertions(+), 506 deletions(-) create mode 100644 src/librustdoc/html/static/fonts/README.txt diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 67ea39fb96579..9c08eac4edcb0 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -239,9 +239,6 @@ pub(crate) struct RenderOptions { pub(crate) default_settings: FxHashMap, /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages. pub(crate) resource_suffix: String, - /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by - /// default. - pub(crate) enable_minification: bool, /// Whether to create an index page in the root of the output directory. If this is true but /// `enable_index_page` is None, generate a static listing of crates instead. pub(crate) enable_index_page: bool, @@ -416,7 +413,9 @@ impl Options { let to_check = matches.opt_strs("check-theme"); if !to_check.is_empty() { - let paths = match theme::load_css_paths(static_files::themes::LIGHT) { + let paths = match theme::load_css_paths( + std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(), + ) { Ok(p) => p, Err(e) => { diag.struct_err(&e.to_string()).emit(); @@ -557,7 +556,9 @@ impl Options { let mut themes = Vec::new(); if matches.opt_present("theme") { - let paths = match theme::load_css_paths(static_files::themes::LIGHT) { + let paths = match theme::load_css_paths( + std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(), + ) { Ok(p) => p, Err(e) => { diag.struct_err(&e.to_string()).emit(); @@ -675,7 +676,6 @@ impl Options { ModuleSorting::Alphabetical }; let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default(); - let enable_minification = !matches.opt_present("disable-minification"); let markdown_no_toc = matches.opt_present("markdown-no-toc"); let markdown_css = matches.opt_strs("markdown-css"); let markdown_playground_url = matches.opt_str("markdown-playground-url"); @@ -768,7 +768,6 @@ impl Options { extern_html_root_takes_precedence, default_settings, resource_suffix, - enable_minification, enable_index_page, index_page, static_root_path, diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 7d6d4b71e2eaf..087e9219b67c6 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -2,13 +2,14 @@ use std::path::PathBuf; use rustc_data_structures::fx::FxHashMap; -use crate::error::Error; use crate::externalfiles::ExternalHtml; use crate::html::format::{Buffer, Print}; use crate::html::render::{ensure_trailing_slash, StylePath}; use askama::Template; +use super::static_files::{StaticFiles, STATIC_FILES}; + #[derive(Clone)] pub(crate) struct Layout { pub(crate) logo: String, @@ -45,6 +46,9 @@ struct PageLayout<'a> { static_root_path: &'a str, page: &'a Page<'a>, layout: &'a Layout, + + files: &'static StaticFiles, + themes: Vec, sidebar: String, content: String, @@ -61,12 +65,9 @@ pub(crate) fn render( ) -> String { let static_root_path = page.get_static_root_path(); let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string(); - let mut themes: Vec = style_files - .iter() - .map(StylePath::basename) - .collect::>() - .unwrap_or_default(); + let mut themes: Vec = style_files.iter().map(|s| s.basename().unwrap()).collect(); themes.sort(); + let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version"); let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar. let sidebar = Buffer::html().to_display(sidebar); @@ -74,6 +75,7 @@ pub(crate) fn render( static_root_path, page, layout, + files: &STATIC_FILES, themes, sidebar, content, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 5733d1f9c79d6..5263d0d223285 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -32,7 +32,7 @@ use crate::html::escape::Escape; use crate::html::format::{join_with_double_colon, Buffer}; use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap}; use crate::html::url_parts_builder::UrlPartsBuilder; -use crate::html::{layout, sources}; +use crate::html::{layout, sources, static_files}; use crate::scrape_examples::AllCallLocations; use crate::try_err; @@ -498,7 +498,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { ); let (sender, receiver) = channel(); - let mut scx = SharedContext { + let scx = SharedContext { tcx, src_root, local_sources, @@ -521,19 +521,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { call_locations, }; - // Add the default themes to the `Vec` of stylepaths - // - // Note that these must be added before `sources::render` is called - // so that the resulting source pages are styled - // - // `light.css` is not disabled because it is the stylesheet that stays loaded - // by the browser as the theme stylesheet. The theme system (hackily) works by - // changing the href to this stylesheet. All other themes are disabled to - // prevent rule conflicts - scx.style_files.push(StylePath { path: PathBuf::from("light.css") }); - scx.style_files.push(StylePath { path: PathBuf::from("dark.css") }); - scx.style_files.push(StylePath { path: PathBuf::from("ayu.css") }); - let dst = output; scx.ensure_dir(&dst)?; @@ -647,10 +634,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { \ \ \ - ", - root_path = page.static_root_path.unwrap_or(""), - suffix = page.resource_suffix, + href=\"{static_root_path}{settings_css}\">\ + ", + static_root_path = page.static_root_path.unwrap_or(""), + settings_css = static_files::STATIC_FILES.settings_css, + settings_js = static_files::STATIC_FILES.settings_js, ) }, &shared.style_files, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3225ddabe2e75..c4869b3870ae4 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -30,10 +30,10 @@ use crate::html::format::{ join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause, visibility_print_with_space, Buffer, Ending, PrintWithSpace, }; -use crate::html::highlight; use crate::html::layout::Page; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::url_parts_builder::UrlPartsBuilder; +use crate::html::{highlight, static_files}; use askama::Template; use itertools::Itertools; @@ -52,8 +52,8 @@ struct PathComponent { #[derive(Template)] #[template(path = "print_item.html")] struct ItemVars<'a> { - page: &'a Page<'a>, static_root_path: &'a str, + clipboard_svg: &'static static_files::StaticFile, typ: &'a str, name: &'a str, item_type: &'a str, @@ -147,8 +147,8 @@ pub(super) fn print_item( }; let item_vars = ItemVars { - page, static_root_path: page.get_static_root_path(), + clipboard_svg: &static_files::STATIC_FILES.clipboard_svg, typ, name: item.name.as_ref().unwrap().as_str(), item_type: &item.type_().to_string(), diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 85f63c985b376..723c502c584f0 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -1,10 +1,8 @@ -use std::ffi::OsStr; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufReader}; -use std::path::{Component, Path, PathBuf}; +use std::path::{Component, Path}; use std::rc::Rc; -use std::sync::LazyLock as Lazy; use itertools::Itertools; use rustc_data_structures::flock; @@ -20,123 +18,19 @@ use crate::error::Error; use crate::html::{layout, static_files}; use crate::{try_err, try_none}; -static FILES_UNVERSIONED: Lazy> = Lazy::new(|| { - map! { - "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR, - "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM, - "FiraSans-LICENSE.txt" => static_files::fira_sans::LICENSE, - "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR, - "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD, - "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC, - "SourceSerif4-LICENSE.md" => static_files::source_serif_4::LICENSE, - "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR, - "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD, - "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC, - "SourceCodePro-LICENSE.txt" => static_files::source_code_pro::LICENSE, - "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR, - "NanumBarunGothic-LICENSE.txt" => static_files::nanum_barun_gothic::LICENSE, - "LICENSE-MIT.txt" => static_files::LICENSE_MIT, - "LICENSE-APACHE.txt" => static_files::LICENSE_APACHE, - "COPYRIGHT.txt" => static_files::COPYRIGHT, - } -}); - -enum SharedResource<'a> { - /// This file will never change, no matter what toolchain is used to build it. - /// - /// It does not have a resource suffix. - Unversioned { name: &'static str }, - /// This file may change depending on the toolchain. - /// - /// It has a resource suffix. - ToolchainSpecific { basename: &'static str }, - /// This file may change for any crate within a build, or based on the CLI arguments. - /// - /// This differs from normal invocation-specific files because it has a resource suffix. - InvocationSpecific { basename: &'a str }, -} - -impl SharedResource<'_> { - fn extension(&self) -> Option<&OsStr> { - use SharedResource::*; - match self { - Unversioned { name } - | ToolchainSpecific { basename: name } - | InvocationSpecific { basename: name } => Path::new(name).extension(), - } - } - - fn path(&self, cx: &Context<'_>) -> PathBuf { - match self { - SharedResource::Unversioned { name } => cx.dst.join(name), - SharedResource::ToolchainSpecific { basename } => cx.suffix_path(basename), - SharedResource::InvocationSpecific { basename } => cx.suffix_path(basename), - } - } - - fn should_emit(&self, emit: &[EmitType]) -> bool { - if emit.is_empty() { - return true; - } - let kind = match self { - SharedResource::Unversioned { .. } => EmitType::Unversioned, - SharedResource::ToolchainSpecific { .. } => EmitType::Toolchain, - SharedResource::InvocationSpecific { .. } => EmitType::InvocationSpecific, - }; - emit.contains(&kind) - } -} - -impl Context<'_> { - fn suffix_path(&self, filename: &str) -> PathBuf { - // We use splitn vs Path::extension here because we might get a filename - // like `style.min.css` and we want to process that into - // `style-suffix.min.css`. Path::extension would just return `css` - // which would result in `style.min-suffix.css` which isn't what we - // want. - let (base, ext) = filename.split_once('.').unwrap(); - let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext); - self.dst.join(&filename) - } - - fn write_shared( - &self, - resource: SharedResource<'_>, - contents: impl 'static + Send + AsRef<[u8]>, - emit: &[EmitType], - ) -> Result<(), Error> { - if resource.should_emit(emit) { - self.shared.fs.write(resource.path(self), contents) - } else { - Ok(()) - } - } - - fn write_minify( - &self, - resource: SharedResource<'_>, - contents: impl 'static + Send + AsRef + AsRef<[u8]>, - minify: bool, - emit: &[EmitType], - ) -> Result<(), Error> { - if minify { - let contents = contents.as_ref(); - let contents = if resource.extension() == Some(OsStr::new("css")) { - minifier::css::minify(contents) - .map_err(|e| { - Error::new(format!("failed to minify CSS file: {}", e), resource.path(self)) - })? - .to_string() - } else { - minifier::js::minify(contents).to_string() - }; - self.write_shared(resource, contents, emit) - } else { - self.write_shared(resource, contents, emit) - } - } -} - +/// Rustdoc writes out two kinds of shared files: +/// - Static files, which are embedded in the rustdoc binary and are written with a +/// filename that includes a hash of their contents. These will always have a new +/// URL if the contents change, so they are safe to cache with the +/// `Cache-Control: immutable` directive. They are written under the static.files/ +/// directory and are written when --emit-type is empty (default) or contains +/// "toolchain-specific". +/// - Invocation specific files. These are generated based on the crate(s) being +/// documented. Their filenames need to be predictable without knowing their +/// contents, so they do not include a hash in their filename and are not safe to +/// cache with `Cache-Control: immutable`. They include the contents of the +/// --resource-suffix flag and are emitted when --emit-type is empty (default) +/// or contains "invocation-specific". pub(super) fn write_shared( cx: &mut Context<'_>, krate: &Crate, @@ -149,139 +43,51 @@ pub(super) fn write_shared( let lock_file = cx.dst.join(".lock"); let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); - // Minified resources are usually toolchain resources. If they're not, they should use `cx.write_minify` directly. - fn write_minify( - basename: &'static str, - contents: impl 'static + Send + AsRef + AsRef<[u8]>, - cx: &Context<'_>, - options: &RenderOptions, - ) -> Result<(), Error> { - cx.write_minify( - SharedResource::ToolchainSpecific { basename }, - contents, - options.enable_minification, - &options.emit, - ) - } - - // Toolchain resources should never be dynamic. - let write_toolchain = |p: &'static _, c: &'static _| { - cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit) - }; - - // Crate resources should always be dynamic. - let write_crate = |p: &_, make_content: &dyn Fn() -> Result, Error>| { + // InvocationSpecific resources should always be dynamic. + let write_invocation_specific = |p: &str, make_content: &dyn Fn() -> Result, Error>| { let content = make_content()?; - cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit) + if options.emit.is_empty() || options.emit.contains(&EmitType::InvocationSpecific) { + let output_filename = static_files::suffix_path(p, &cx.shared.resource_suffix); + cx.shared.fs.write(cx.dst.join(output_filename), content) + } else { + Ok(()) + } }; - // Given "foo.svg", return e.g. "url(\"foo1.58.0.svg\")" - fn ver_url(cx: &Context<'_>, basename: &'static str) -> String { - format!( - "url(\"{}\")", - SharedResource::ToolchainSpecific { basename } - .path(cx) - .file_name() - .unwrap() - .to_str() - .unwrap() - ) - } - - // We use the AUTOREPLACE mechanism to inject into our static JS and CSS certain - // values that are only known at doc build time. Since this mechanism is somewhat - // surprising when reading the code, please limit it to rustdoc.css. - write_minify( - "rustdoc.css", - static_files::RUSTDOC_CSS - .replace( - "/* AUTOREPLACE: */url(\"toggle-minus.svg\")", - &ver_url(cx, "toggle-minus.svg"), - ) - .replace("/* AUTOREPLACE: */url(\"toggle-plus.svg\")", &ver_url(cx, "toggle-plus.svg")) - .replace("/* AUTOREPLACE: */url(\"down-arrow.svg\")", &ver_url(cx, "down-arrow.svg")), - cx, - options, - )?; - - // Add all the static files. These may already exist, but we just - // overwrite them anyway to make sure that they're fresh and up-to-date. - write_minify("settings.css", static_files::SETTINGS_CSS, cx, options)?; - write_minify("noscript.css", static_files::NOSCRIPT_CSS, cx, options)?; - - // To avoid "light.css" to be overwritten, we'll first run over the received themes and only - // then we'll run over the "official" styles. - let mut themes: FxHashSet = FxHashSet::default(); + cx.shared + .fs + .create_dir_all(cx.dst.join("static.files")) + .map_err(|e| PathError::new(e, "static.files"))?; + // Handle added third-party themes for entry in &cx.shared.style_files { let theme = entry.basename()?; let extension = try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path); - // Handle the official themes - match theme.as_str() { - "light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?, - "dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?, - "ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?, - _ => { - // Handle added third-party themes - let filename = format!("{}.{}", theme, extension); - write_crate(&filename, &|| Ok(try_err!(fs::read(&entry.path), &entry.path)))?; - } - }; - - themes.insert(theme.to_owned()); - } - - if (*cx.shared).layout.logo.is_empty() { - write_toolchain("rust-logo.svg", static_files::RUST_LOGO_SVG)?; - } - if (*cx.shared).layout.favicon.is_empty() { - write_toolchain("favicon.svg", static_files::RUST_FAVICON_SVG)?; - write_toolchain("favicon-16x16.png", static_files::RUST_FAVICON_PNG_16)?; - write_toolchain("favicon-32x32.png", static_files::RUST_FAVICON_PNG_32)?; - } - write_toolchain("wheel.svg", static_files::WHEEL_SVG)?; - write_toolchain("clipboard.svg", static_files::CLIPBOARD_SVG)?; - write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?; - write_toolchain("toggle-minus.svg", static_files::TOGGLE_MINUS_PNG)?; - write_toolchain("toggle-plus.svg", static_files::TOGGLE_PLUS_PNG)?; - - let mut themes: Vec<&String> = themes.iter().collect(); - themes.sort(); - - write_minify("main.js", static_files::MAIN_JS, cx, options)?; - write_minify("search.js", static_files::SEARCH_JS, cx, options)?; - write_minify("settings.js", static_files::SETTINGS_JS, cx, options)?; - - if cx.include_sources { - write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT, cx, options)?; - } - - write_minify("storage.js", static_files::STORAGE_JS, cx, options)?; + // Skip the official themes. They are written below as part of STATIC_FILES_LIST. + if matches!(theme.as_str(), "light" | "dark" | "ayu") { + continue; + } - if cx.shared.layout.scrape_examples_extension { - cx.write_minify( - SharedResource::InvocationSpecific { basename: "scrape-examples.js" }, - static_files::SCRAPE_EXAMPLES_JS, - options.enable_minification, - &options.emit, - )?; + let bytes = try_err!(fs::read(&entry.path), &entry.path); + let filename = format!("{}{}.{}", theme, cx.shared.resource_suffix, extension); + cx.shared.fs.write(cx.dst.join(filename), bytes)?; } + // When the user adds their own CSS files with --extend-css, we write that as an + // invocation-specific file (that is, with a resource suffix). if let Some(ref css) = cx.shared.layout.css_file_extension { let buffer = try_err!(fs::read_to_string(css), css); - // This varies based on the invocation, so it can't go through the write_minify wrapper. - cx.write_minify( - SharedResource::InvocationSpecific { basename: "theme.css" }, - buffer, - options.enable_minification, - &options.emit, - )?; + let path = static_files::suffix_path("theme.css", &cx.shared.resource_suffix); + cx.shared.fs.write(cx.dst.join(path), buffer)?; } - write_minify("normalize.css", static_files::NORMALIZE_CSS, cx, options)?; - for (name, contents) in &*FILES_UNVERSIONED { - cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?; + + if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) { + for f in static_files::STATIC_FILES_LIST { + let filename = static_files::static_filename(f.filename, f.bytes); + cx.shared.fs.write(cx.dst.join(filename), f.minified())?; + } } /// Read a file and return all lines that match the `"{crate}":{data},` format, @@ -463,7 +269,7 @@ pub(super) fn write_shared( v.push_str("\\\n}');\ncreateSourceSidebar();\n"); Ok(v.into_bytes()) }; - write_crate("source-files.js", &make_sources)?; + write_invocation_specific("source-files.js", &make_sources)?; } // Update the search index and crate list. @@ -477,7 +283,7 @@ pub(super) fn write_shared( // Sort the indexes by crate so the file will be generated identically even // with rustdoc running in parallel. all_indexes.sort(); - write_crate("search-index.js", &|| { + write_invocation_specific("search-index.js", &|| { let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str( @@ -490,7 +296,7 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; Ok(v.into_bytes()) })?; - write_crate("crates.js", &|| { + write_invocation_specific("crates.js", &|| { let krates = krates.iter().map(|k| format!("\"{}\"", k)).join(","); Ok(format!("window.ALL_CRATES = [{}];", krates).into_bytes()) })?; diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7c0dab1c527d1..61a50a9bd1392 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -4,7 +4,7 @@ font-style: normal; font-weight: 400; src: local('Fira Sans'), - url("FiraSans-Regular.woff2") format("woff2"); + url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2"); font-display: swap; } @font-face { @@ -12,7 +12,7 @@ font-style: normal; font-weight: 500; src: local('Fira Sans Medium'), - url("FiraSans-Medium.woff2") format("woff2"); + url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2"); font-display: swap; } @@ -22,7 +22,7 @@ font-style: normal; font-weight: 400; src: local('Source Serif 4'), - url("SourceSerif4-Regular.ttf.woff2") format("woff2"); + url("SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2") format("woff2"); font-display: swap; } @font-face { @@ -30,7 +30,7 @@ font-style: italic; font-weight: 400; src: local('Source Serif 4 Italic'), - url("SourceSerif4-It.ttf.woff2") format("woff2"); + url("SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2") format("woff2"); font-display: swap; } @font-face { @@ -38,7 +38,7 @@ font-style: normal; font-weight: 700; src: local('Source Serif 4 Bold'), - url("SourceSerif4-Bold.ttf.woff2") format("woff2"); + url("SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2") format("woff2"); font-display: swap; } @@ -49,28 +49,28 @@ font-weight: 400; /* Avoid using locally installed font because bad versions are in circulation: * see https://github.com/rust-lang/rust/issues/24355 */ - src: url("SourceCodePro-Regular.ttf.woff2") format("woff2"); + src: url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2"); font-display: swap; } @font-face { font-family: 'Source Code Pro'; font-style: italic; font-weight: 400; - src: url("SourceCodePro-It.ttf.woff2") format("woff2"); + src: url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2"); font-display: swap; } @font-face { font-family: 'Source Code Pro'; font-style: normal; font-weight: 600; - src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2"); + src: url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2"); font-display: swap; } /* Avoid using legacy CJK serif fonts in Windows like Batang. */ @font-face { font-family: 'NanumBarunGothic'; - src: url("NanumBarunGothic.ttf.woff2") format("woff2"); + src: url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2"); font-display: swap; unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF; } @@ -850,7 +850,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ background-size: 20px; background-position: calc(100% - 2px) 56%; /* image is black color, themes should apply a "filter" property to change the color */ - background-image: /* AUTOREPLACE: */url("down-arrow.svg"); + background-image: url("down-arrow-2d685a4bae708e15.svg"); } #crate-search > option { font-size: 1rem; @@ -1617,11 +1617,11 @@ details.rustdoc-toggle[open] > summary.hideme > span { details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle[open] > summary.hideme::before { - background-image: /* AUTOREPLACE: */url("toggle-minus.svg"); + background-image: url("toggle-minus-31bbd6e4c77f5c96.svg"); } details.rustdoc-toggle > summary::before { - background-image: /* AUTOREPLACE: */url("toggle-plus.svg"); + background-image: url("toggle-plus-1092eb4930d581b0.svg"); } details.rustdoc-toggle[open] > summary::before, diff --git a/src/librustdoc/html/static/fonts/README.txt b/src/librustdoc/html/static/fonts/README.txt new file mode 100644 index 0000000000000..0db15996d2ec1 --- /dev/null +++ b/src/librustdoc/html/static/fonts/README.txt @@ -0,0 +1,12 @@ +The Nanum Barun Gothic fonts are shipped with rustdoc because the default fonts +on many Windows installs render Korean very badly. See: + - https://github.com/rust-lang/rust/pull/84048, + - https://github.com/rust-lang/rust/issues/84035 + - https://github.com/rust-lang/rust/pull/90232 + +The font files were generated with these commands: + +```sh +pyftsubset NanumBarunGothic.ttf \ +--unicodes=U+AC00-D7AF:U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \ +--output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2 diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 33480fa41cf07..1c84393cb4e6f 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -183,9 +183,9 @@ function browserSupportsHistoryApi() { } // eslint-disable-next-line no-unused-vars -function loadCss(cssFileName) { +function loadCss(cssUrl) { const link = document.createElement("link"); - link.href = resourcePath(cssFileName, ".css"); + link.href = cssUrl; link.type = "text/css"; link.rel = "stylesheet"; document.getElementsByTagName("head")[0].appendChild(link); @@ -208,8 +208,8 @@ function loadCss(cssFileName) { event.preventDefault(); // Sending request for the CSS and the JS files at the same time so it will // hopefully be loaded when the JS will generate the settings content. - loadCss("settings"); - loadScript(resourcePath("settings", ".js")); + loadCss(getVar("static-root-path") + getVar("settings-css")); + loadScript(getVar("static-root-path") + getVar("settings-js")); }; window.searchState = { @@ -286,7 +286,7 @@ function loadCss(cssFileName) { function loadSearch() { if (!searchLoaded) { searchLoaded = true; - loadScript(resourcePath("search", ".js")); + loadScript(getVar("static-root-path") + getVar("search-js")); loadScript(resourcePath("search-index", ".js")); } } diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 5e1c7e6f03e75..141563bd46a19 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -154,7 +154,9 @@ * @return {HTMLElement} */ function buildSettingsPage() { - const themes = getVar("themes").split(","); + const theme_names = getVar("themes").split(",").filter(t => t); + theme_names.push("light", "dark", "ayu"); + const settings = [ { "name": "Use system theme", @@ -165,19 +167,19 @@ "name": "Theme", "js_name": "theme", "default": "light", - "options": themes, + "options": theme_names, }, { "name": "Preferred light theme", "js_name": "preferred-light-theme", "default": "light", - "options": themes, + "options": theme_names, }, { "name": "Preferred dark theme", "js_name": "preferred-dark-theme", "default": "dark", - "options": themes, + "options": theme_names, }, { "name": "Auto-hide item contents for large items", diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index b462a2c50f145..db2db83ca6310 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -126,33 +126,29 @@ function getCurrentValue(name) { } } -function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { - const newHref = mainStyleElem.href.replace( - /\/rustdoc([^/]*)\.css/, "/" + newTheme + "$1" + ".css"); - +function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) { // If this new value comes from a system setting or from the previously // saved theme, no need to save it. if (saveTheme) { - updateLocalStorage("theme", newTheme); - } - - if (styleElem.href === newHref) { - return; + updateLocalStorage("theme", newThemeName); } - let found = false; if (savedHref.length === 0) { onEachLazy(document.getElementsByTagName("link"), el => { savedHref.push(el.href); }); } - onEach(savedHref, el => { - if (el === newHref) { - found = true; + const newHref = savedHref.find(url => { + const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/); + if (m && m[1] === newThemeName) { + return true; + } + const m2 = url.match(/\/([^/]*)\.css$/); + if (m2 && m2[1].startsWith(newThemeName)) { return true; } }); - if (found) { + if (newHref && newHref !== styleElem.href) { styleElem.href = newHref; } } diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 75f2b7e3570d5..7b89dc8cd9f76 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -2,167 +2,119 @@ //! //! All the static files are included here for centralized access in case anything other than the //! HTML rendering code (say, the theme checker) needs to access one of these files. -//! -//! Note about types: CSS and JavaScript files are included as `&'static str` to allow for the -//! minifier to run on them. All other files are included as `&'static [u8]` so they can be -//! directly written to a `Write` handle. - -/// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page. -pub(crate) static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css"); - -/// The file contents of `settings.css`, responsible for the items on the settings page. -pub(crate) static SETTINGS_CSS: &str = include_str!("static/css/settings.css"); - -/// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled. -pub(crate) static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css"); - -/// The file contents of `normalize.css`, included to even out standard elements between browser -/// implementations. -pub(crate) static NORMALIZE_CSS: &str = include_str!("static/css/normalize.css"); - -/// The file contents of `main.js`, which contains the core JavaScript used on documentation pages, -/// including search behavior and docblock folding, among others. -pub(crate) static MAIN_JS: &str = include_str!("static/js/main.js"); - -/// The file contents of `search.js`, which contains the search behavior. -pub(crate) static SEARCH_JS: &str = include_str!("static/js/search.js"); - -/// The file contents of `settings.js`, which contains the JavaScript used to handle the settings -/// page. -pub(crate) static SETTINGS_JS: &str = include_str!("static/js/settings.js"); - -/// The file contents of `storage.js`, which contains functionality related to browser Local -/// Storage, used to store documentation settings. -pub(crate) static STORAGE_JS: &str = include_str!("static/js/storage.js"); - -/// The file contents of `scraped-examples.js`, which contains functionality related to the -/// --scrape-examples flag that inserts automatically-found examples of usages of items. -pub(crate) static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js"); - -pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md"); - -/// The file contents of `wheel.svg`, the icon used for the settings button. -pub(crate) static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg"); - -/// The file contents of `clipboard.svg`, the icon used for the "copy path" button. -pub(crate) static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg"); - -/// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox. -pub(crate) static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg"); - -/// The file contents of `toggle-minus.svg`, the icon used for opened toggles. -pub(crate) static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg"); -/// The file contents of `toggle-plus.svg`, the icon used for closed toggles. -pub(crate) static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg"); +use rustc_data_structures::fx::FxHasher; +use std::hash::Hasher; +use std::path::{Path, PathBuf}; +use std::{fmt, str}; -/// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation -/// output. -pub(crate) static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt"); - -/// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0. -pub(crate) static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt"); - -/// The contents of `LICENSE-MIT.txt`, the text of the MIT License. -pub(crate) static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt"); - -/// The contents of `rust-logo.svg`, the default icon of the documentation. -pub(crate) static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg"); - -/// The default documentation favicons (SVG and PNG fallbacks) -pub(crate) static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg"); -pub(crate) static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png"); -pub(crate) static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png"); - -/// The built-in themes given to every documentation site. -pub(crate) mod themes { - /// The "light" theme, selected by default when no setting is available. Used as the basis for - /// the `--check-theme` functionality. - pub(crate) static LIGHT: &str = include_str!("static/css/themes/light.css"); - - /// The "dark" theme. - pub(crate) static DARK: &str = include_str!("static/css/themes/dark.css"); - - /// The "ayu" theme. - pub(crate) static AYU: &str = include_str!("static/css/themes/ayu.css"); +pub(crate) struct StaticFile { + pub(crate) filename: &'static str, + pub(crate) bytes: &'static [u8], } -/// Files related to the Fira Sans font. -pub(crate) mod fira_sans { - /// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2. - pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2"); - - /// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2. - pub(crate) static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2"); - - /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font. - pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt"); +impl StaticFile { + pub(crate) fn minified(&self) -> Vec { + if self.filename.ends_with(".css") { + minifier::css::minify(str::from_utf8(self.bytes).unwrap()).unwrap().to_string().into() + } else if self.filename.ends_with(".js") { + minifier::js::minify(str::from_utf8(self.bytes).unwrap()).to_string().into() + } else { + self.bytes.to_owned() + } + } + + pub(crate) fn output_filename(&self) -> PathBuf { + static_filename(self.filename, self.bytes) + } } -/// Files related to the Source Serif 4 font. -pub(crate) mod source_serif_4 { - /// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in - /// woff2. - pub(crate) static REGULAR: &[u8] = - include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2"); - - /// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in - /// woff2. - pub(crate) static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2"); +/// The Display implementation for a StaticFile outputs its filename. This makes it +/// convenient to interpolate static files into HTML templates. +impl fmt::Display for StaticFile { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.output_filename().display()) + } +} - /// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in - /// woff2. - pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2"); +/// Insert the provided suffix into a filename just before the extension. +pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf { + // We use splitn vs Path::extension here because we might get a filename + // like `style.min.css` and we want to process that into + // `style-suffix.min.css`. Path::extension would just return `css` + // which would result in `style.min-suffix.css` which isn't what we + // want. + let (base, ext) = filename.split_once('.').unwrap(); + let filename = format!("{}{}.{}", base, suffix, ext); + filename.into() +} - /// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font. - pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md"); +pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf { + let filename = filename.rsplit("/").next().unwrap(); + Path::new("static.files").join(suffix_path(filename, &static_suffix(contents))) } -/// Files related to the Source Code Pro font. -pub(crate) mod source_code_pro { - /// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font - /// in woff2. - pub(crate) static REGULAR: &[u8] = - include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2"); +fn static_suffix(bytes: &[u8]) -> String { + let mut hasher = FxHasher::default(); + hasher.write(bytes); + format!("-{:016x}", hasher.finish()) +} - /// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro - /// font in woff2. - pub(crate) static SEMIBOLD: &[u8] = - include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2"); +macro_rules! static_files { + ($($field:ident => $file_path:literal,)+) => { + pub(crate) struct StaticFiles { + $(pub $field: StaticFile,)+ + } - /// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in - /// woff2. - pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2"); + pub(crate) const STATIC_FILES: StaticFiles = StaticFiles { + $($field: StaticFile { filename: $file_path, bytes: include_bytes!($file_path) },)+ + }; - /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font. - pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt"); + pub(crate) static STATIC_FILES_LIST: &[&'static StaticFile] = &[ + $(&STATIC_FILES.$field,)+ + ]; + } } -/// Files related to the Nanum Barun Gothic font. -/// -/// These files are used to avoid some legacy CJK serif fonts in Windows. -/// -/// Note that the Noto Sans KR font, which was used previously but was not very readable on Windows, -/// has been replaced by the Nanum Barun Gothic font. This is due to Windows' implementation of font -/// rendering that distorts OpenType fonts too much. -/// -/// The font files were generated with these commands: -/// -/// ```sh -/// pyftsubset NanumBarunGothic.ttf \ -/// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \ -/// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2 -/// ``` -pub(crate) mod nanum_barun_gothic { - /// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font. - pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2"); - - /// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font. - pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt"); +static_files! { + rustdoc_css => "static/css/rustdoc.css", + settings_css => "static/css/settings.css", + noscript_css => "static/css/noscript.css", + normalize_css => "static/css/normalize.css", + main_js => "static/js/main.js", + search_js => "static/js/search.js", + settings_js => "static/js/settings.js", + source_script_js => "static/js/source-script.js", + storage_js => "static/js/storage.js", + scrape_examples_js => "static/js/scrape-examples.js", + wheel_svg => "static/images/wheel.svg", + clipboard_svg => "static/images/clipboard.svg", + down_arrow_svg => "static/images/down-arrow.svg", + toggle_minus_png => "static/images/toggle-minus.svg", + toggle_plus_png => "static/images/toggle-plus.svg", + copyright => "static/COPYRIGHT.txt", + license_apache => "static/LICENSE-APACHE.txt", + license_mit => "static/LICENSE-MIT.txt", + rust_logo_svg => "static/images/rust-logo.svg", + rust_favicon_svg => "static/images/favicon.svg", + rust_favicon_png_16 => "static/images/favicon-16x16.png", + rust_favicon_png_32 => "static/images/favicon-32x32.png", + theme_light_css => "static/css/themes/light.css", + theme_dark_css => "static/css/themes/dark.css", + theme_ayu_css => "static/css/themes/ayu.css", + fira_sans_regular => "static/fonts/FiraSans-Regular.woff2", + fira_sans_medium => "static/fonts/FiraSans-Medium.woff2", + fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", + source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2", + source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2", + source_serif_4_italic => "static/fonts/SourceSerif4-It.ttf.woff2", + source_serif_4_license => "static/fonts/SourceSerif4-LICENSE.md", + source_code_pro_regular => "static/fonts/SourceCodePro-Regular.ttf.woff2", + source_code_pro_semibold => "static/fonts/SourceCodePro-Semibold.ttf.woff2", + source_code_pro_italic => "static/fonts/SourceCodePro-It.ttf.woff2", + source_code_pro_license => "static/fonts/SourceCodePro-LICENSE.txt", + nanum_barun_gothic_regular => "static/fonts/NanumBarunGothic.ttf.woff2", + nanum_barun_gothic_license => "static/fonts/NanumBarunGothic-LICENSE.txt", } -/// Files related to the sidebar in rustdoc sources. -pub(crate) mod sidebar { - /// File script to handle sidebar. - pub(crate) static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js"); -} +pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/js/scrape-examples.js"); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index c323869168789..4efcfc510a255 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -7,48 +7,44 @@ {#- -#} {#- -#} {{page.title}} {#- -#} - {#- -#} - {#- -#} - {#- -#} - {#- -#} - {#- -#} - {#- -#} + {#- -#} + {#- -#} + {#- -#} + {#- -#} + {#- -#} + {#- -#} {#- -#} + href="{{static_root_path|safe}}{{files.normalize_css}}"> {#- -#} {#- -#} + {#- -#} + {#- -#} + {#- -#} {%- for theme in themes -%} - + {#- -#} {%- endfor -%} {#- -#} - {#- -#} + {#- -#} {%- if page.css_class.contains("crate") -%} {#- -#} {%- else if page.css_class == "source" -%} - {#- -#} + {#- -#} {#- -#} {%- else if !page.css_class.contains("mod") -%} {#- -#} {%- endif -%} - {#- -#} + {#- -#} {%- if layout.scrape_examples_extension -%} - {#- -#} + {#- -#} {%- endif -%} {#- -#} {%- if layout.css_file_extension.is_some() -%} {#- -#} {%- else -%} {#- -#} + href="{{static_root_path|safe}}{{files.rust_favicon_png_16}}"> {#- -#} {#- -#} + href="{{static_root_path|safe}}{{files.rust_favicon_png_32}}"> {#- -#} {#- -#} + href="{{static_root_path|safe}}{{files.rust_favicon_svg}}"> {#- -#} {%- endif -%} {{- layout.external_html.in_header|safe -}} {#- -#} @@ -81,7 +77,7 @@ {%- if !layout.logo.is_empty() -%} logo {#- -#} {%- else -%} - {#- -#} + {#- -#} {%- endif -%}
{#- -#} {#- -#} @@ -95,7 +91,7 @@

{#- -#} {%- if !layout.logo.is_empty() %} logo {#- -#} {%- else -%} - {#- -#} + {#- -#} {%- endif -%}
{#- -#} {#- -#} @@ -110,7 +106,7 @@

{#- -#} {%- if !layout.logo.is_empty() %} logo {#- -#} {%- else -%} - {#- -#} + {#- -#} {%- endif -%} {#- -#} {%- endif -%} @@ -129,7 +125,7 @@

{#- -#} {#- -#} {#- -#} @@ -140,10 +136,14 @@

{#- -#} {{- layout.external_html.after_content|safe -}}
{#- -#}
{#- -#} {#- -#} diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index e497b619366b1..611d124d4b91b 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -7,7 +7,7 @@

{#- -#} {%- endfor -%} {{name}} {#- -#} {#- -#} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 4cf9435d9c8ee..1982c066b6ff2 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -469,9 +469,6 @@ fn opts() -> Vec { stable("json", |o| { o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG") }), - unstable("disable-minification", |o| { - o.optflagmulti("", "disable-minification", "Disable minification applied on JS files") - }), stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "LINT")), stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "LINT")), stable("force-warn", |o| o.optmulti("", "force-warn", "Set lint force-warn", "LINT")), @@ -610,6 +607,7 @@ fn opts() -> Vec { ) }), // deprecated / removed options + unstable("disable-minification", |o| o.optflagmulti("", "disable-minification", "removed")), stable("plugin-path", |o| { o.optmulti( "", diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index 09b4c29c1dd33..cad0c9e5b8153 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -23,24 +23,24 @@ invocation-only: toolchain-only: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs - [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] - ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff2 ] + [ -e $(TOOLCHAIN_ONLY)/static.files/storage-*.js ] + [ -e $(TOOLCHAIN_ONLY)/static.files/SourceSerif4-It-*.ttf.woff2 ] ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] ! [ -e $(TOOLCHAIN_ONLY)/theme.css ] - [ -e $(TOOLCHAIN_ONLY)/main-xxx.js ] + [ -e $(TOOLCHAIN_ONLY)/static.files/main-*.js ] ! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ] all-shared: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs - [ -e $(ALL_SHARED)/storage-xxx.js ] - [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff2 ] + [ -e $(ALL_SHARED)/static.files/storage-*.js ] + [ -e $(ALL_SHARED)/static.files/SourceSerif4-It-*.ttf.woff2 ] ! [ -e $(ALL_SHARED)/search-index-xxx.js ] ! [ -e $(ALL_SHARED)/settings.html ] ! [ -e $(ALL_SHARED)/x ] ! [ -e $(ALL_SHARED)/src ] ! [ -e $(ALL_SHARED)/theme.css ] - [ -e $(ALL_SHARED)/main-xxx.js ] + [ -e $(ALL_SHARED)/static.files/main-*.js ] ! [ -e $(ALL_SHARED)/y-xxx.css ] diff --git a/src/test/run-make/issue-88756-default-output/output-default.stdout b/src/test/run-make/issue-88756-default-output/output-default.stdout index 80cd08ee16734..b280698230dd9 100644 --- a/src/test/run-make/issue-88756-default-output/output-default.stdout +++ b/src/test/run-make/issue-88756-default-output/output-default.stdout @@ -115,8 +115,6 @@ Options: Provide width of the output for truncated error messages --json CONFIG Configure the structure of JSON diagnostics - --disable-minification - Disable minification applied on JS files -A, --allow LINT Set lint allowed -W, --warn LINT Set lint warnings --force-warn LINT @@ -173,6 +171,8 @@ Options: --scrape-tests Include test code when scraping examples --with-examples path to function call information (for displaying examples in the documentation) + --disable-minification + removed --plugin-path DIR removed, see issue #44136 for diff --git a/src/test/rustdoc/static-root-path.rs b/src/test/rustdoc/static-root-path.rs index 08c055c5b8dbb..04de52c0df0f3 100644 --- a/src/test/rustdoc/static-root-path.rs +++ b/src/test/rustdoc/static-root-path.rs @@ -1,18 +1,18 @@ // compile-flags:-Z unstable-options --static-root-path /cache/ // @has static_root_path/struct.SomeStruct.html -// @matchesraw - '"/cache/main\.js"' -// @!matchesraw - '"\.\./main\.js"' +// @matchesraw - '"/cache/static.files/main-' +// @!matchesraw - '"\.\./main' // @matchesraw - 'data-root-path="\.\./"' // @!matchesraw - '"/cache/search-index\.js"' pub struct SomeStruct; // @has src/static_root_path/static-root-path.rs.html -// @matchesraw - '"/cache/source-script\.js"' -// @!matchesraw - '"\.\./\.\./source-script\.js"' +// @matchesraw - '"/cache/static.files/source-script-' +// @!matchesraw - '"\.\./\.\./source-script' // @matchesraw - '"\.\./\.\./source-files.js"' // @!matchesraw - '"/cache/source-files\.js"' // @has settings.html -// @matchesraw - '/cache/settings\.js' -// @!matchesraw - '\./settings\.js' +// @matchesraw - '/cache/static.files/settings-' +// @!matchesraw - '\../settings' diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index df3185758bfc0..3da4fed33e111 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -307,10 +307,13 @@ function runChecks(testFile, doSearch, parseQuery) { * `parseQuery` function exported from the search module. */ function loadSearchJS(doc_folder, resource_suffix) { - const searchJs = path.join(doc_folder, "search" + resource_suffix + ".js"); const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js"); const searchIndex = require(searchIndexJs); - const searchModule = require(searchJs); + + const staticFiles = path.join(doc_folder, "static.files"); + const searchJs = fs.readdirSync(staticFiles).find( + f => f.match(/search.*\.js$/)); + const searchModule = require(path.join(staticFiles, searchJs)); const searchWords = searchModule.initSearch(searchIndex.searchIndex); return { From a0193bee257f3197da7e60e39b5725736b07a032 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 28 Sep 2022 23:52:00 -0700 Subject: [PATCH 138/482] Make --static-root-path point to static.files --- src/librustdoc/html/layout.rs | 9 ++++++--- src/librustdoc/html/render/context.rs | 2 +- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/html/render/write_shared.rs | 9 ++++++--- src/librustdoc/html/static_files.rs | 4 ++-- src/test/rustdoc/static-root-path.rs | 6 +++--- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 087e9219b67c6..c1b3526eb4541 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -35,15 +35,18 @@ pub(crate) struct Page<'a> { } impl<'a> Page<'a> { - pub(crate) fn get_static_root_path(&self) -> &str { - self.static_root_path.unwrap_or(self.root_path) + pub(crate) fn get_static_root_path(&self) -> String { + match self.static_root_path { + Some(s) => s.to_string(), + None => format!("{}{}", self.root_path, "static.files/"), + } } } #[derive(Template)] #[template(path = "page.html")] struct PageLayout<'a> { - static_root_path: &'a str, + static_root_path: String, page: &'a Page<'a>, layout: &'a Layout, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 5263d0d223285..51843a505f709 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -636,7 +636,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { \ ", - static_root_path = page.static_root_path.unwrap_or(""), + static_root_path = page.get_static_root_path(), settings_css = static_files::STATIC_FILES.settings_css, settings_js = static_files::STATIC_FILES.settings_js, ) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index c4869b3870ae4..ce4fc4d68fac2 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -147,7 +147,7 @@ pub(super) fn print_item( }; let item_vars = ItemVars { - static_root_path: page.get_static_root_path(), + static_root_path: &page.get_static_root_path(), clipboard_svg: &static_files::STATIC_FILES.clipboard_svg, typ, name: item.name.as_ref().unwrap().as_str(), diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 723c502c584f0..07d139e9e1212 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -24,7 +24,8 @@ use crate::{try_err, try_none}; /// URL if the contents change, so they are safe to cache with the /// `Cache-Control: immutable` directive. They are written under the static.files/ /// directory and are written when --emit-type is empty (default) or contains -/// "toolchain-specific". +/// "toolchain-specific". If using the --static-root-path flag, it should point +/// to a URL path prefix where each of these filenames can be fetched. /// - Invocation specific files. These are generated based on the crate(s) being /// documented. Their filenames need to be predictable without knowing their /// contents, so they do not include a hash in their filename and are not safe to @@ -85,8 +86,10 @@ pub(super) fn write_shared( if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) { for f in static_files::STATIC_FILES_LIST { - let filename = static_files::static_filename(f.filename, f.bytes); - cx.shared.fs.write(cx.dst.join(filename), f.minified())?; + let filename = cx.dst.join( + Path::new("static.files/").join(static_files::static_filename(f.filename, f.bytes)), + ); + cx.shared.fs.write(filename, f.minified())?; } } diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 7b89dc8cd9f76..c922890bc0ba2 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHasher; use std::hash::Hasher; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::{fmt, str}; pub(crate) struct StaticFile { @@ -51,7 +51,7 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf { pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf { let filename = filename.rsplit("/").next().unwrap(); - Path::new("static.files").join(suffix_path(filename, &static_suffix(contents))) + suffix_path(filename, &static_suffix(contents)) } fn static_suffix(bytes: &[u8]) -> String { diff --git a/src/test/rustdoc/static-root-path.rs b/src/test/rustdoc/static-root-path.rs index 04de52c0df0f3..86928b0fb0a80 100644 --- a/src/test/rustdoc/static-root-path.rs +++ b/src/test/rustdoc/static-root-path.rs @@ -1,18 +1,18 @@ // compile-flags:-Z unstable-options --static-root-path /cache/ // @has static_root_path/struct.SomeStruct.html -// @matchesraw - '"/cache/static.files/main-' +// @matchesraw - '"/cache/main-' // @!matchesraw - '"\.\./main' // @matchesraw - 'data-root-path="\.\./"' // @!matchesraw - '"/cache/search-index\.js"' pub struct SomeStruct; // @has src/static_root_path/static-root-path.rs.html -// @matchesraw - '"/cache/static.files/source-script-' +// @matchesraw - '"/cache/source-script-' // @!matchesraw - '"\.\./\.\./source-script' // @matchesraw - '"\.\./\.\./source-files.js"' // @!matchesraw - '"/cache/source-files\.js"' // @has settings.html -// @matchesraw - '/cache/static.files/settings-' +// @matchesraw - '/cache/settings-' // @!matchesraw - '\../settings' From f5873cc669aa612783daf69a76b7671380495225 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 29 Oct 2022 01:57:39 -0700 Subject: [PATCH 139/482] Generate static file hashes once --- src/librustdoc/html/render/write_shared.rs | 11 ++++----- src/librustdoc/html/static_files.rs | 27 ++++++++++++++-------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 07d139e9e1212..94d8a9feca69d 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -85,12 +85,11 @@ pub(super) fn write_shared( } if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) { - for f in static_files::STATIC_FILES_LIST { - let filename = cx.dst.join( - Path::new("static.files/").join(static_files::static_filename(f.filename, f.bytes)), - ); - cx.shared.fs.write(filename, f.minified())?; - } + let static_dir = cx.dst.join(Path::new("static.files")); + static_files::for_each(|f: &static_files::StaticFile| { + let filename = static_dir.join(f.output_filename()); + cx.shared.fs.write(filename, f.minified()) + })?; } /// Read a file and return all lines that match the `"{crate}":{data},` format, diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index c922890bc0ba2..afe920b7fa1e0 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -5,15 +5,19 @@ use rustc_data_structures::fx::FxHasher; use std::hash::Hasher; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::{fmt, str}; pub(crate) struct StaticFile { - pub(crate) filename: &'static str, + pub(crate) filename: PathBuf, pub(crate) bytes: &'static [u8], } impl StaticFile { + fn new(filename: &str, bytes: &'static [u8]) -> StaticFile { + Self { filename: static_filename(filename, bytes), bytes } + } + pub(crate) fn minified(&self) -> Vec { if self.filename.ends_with(".css") { minifier::css::minify(str::from_utf8(self.bytes).unwrap()).unwrap().to_string().into() @@ -24,8 +28,8 @@ impl StaticFile { } } - pub(crate) fn output_filename(&self) -> PathBuf { - static_filename(self.filename, self.bytes) + pub(crate) fn output_filename(&self) -> &Path { + &self.filename } } @@ -66,13 +70,18 @@ macro_rules! static_files { $(pub $field: StaticFile,)+ } - pub(crate) const STATIC_FILES: StaticFiles = StaticFiles { - $($field: StaticFile { filename: $file_path, bytes: include_bytes!($file_path) },)+ - }; + pub(crate) static STATIC_FILES: std::sync::LazyLock = std::sync::LazyLock::new(|| StaticFiles { + $($field: StaticFile::new($file_path, include_bytes!($file_path)),)+ + }); - pub(crate) static STATIC_FILES_LIST: &[&'static StaticFile] = &[ + pub(crate) fn for_each(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> { + for sf in [ $(&STATIC_FILES.$field,)+ - ]; + ] { + f(sf)? + } + Ok(()) + } } } From 5fb4db02f6af6b946aa7f27610106fa8a57816b8 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 29 Oct 2022 14:49:00 -0700 Subject: [PATCH 140/482] Move string literal into format string Co-authored-by: Michael Howell --- src/librustdoc/html/layout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index c1b3526eb4541..48c6abfca90ce 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -38,7 +38,7 @@ impl<'a> Page<'a> { pub(crate) fn get_static_root_path(&self) -> String { match self.static_root_path { Some(s) => s.to_string(), - None => format!("{}{}", self.root_path, "static.files/"), + None => format!("{}static.files/", self.root_path), } } } From 6064baf4f78431276df53ef2ea78415d6ffc23fb Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 3 Nov 2022 11:42:51 +0100 Subject: [PATCH 141/482] move browser opening logic in Builder This allows open() to be called from other places in bootstrap (I need this for Ferrocene), and it simplifies the callers by moving the "was_invoked_explicitly" check into the function. --- src/bootstrap/builder.rs | 18 ++++++++++++++++++ src/bootstrap/doc.rs | 40 +++++++++++----------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 6de3746363337..406bae02d84da 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -2207,6 +2207,24 @@ impl<'a> Builder<'a> { false } + + pub(crate) fn maybe_open_in_browser(&self, path: impl AsRef) { + if self.was_invoked_explicitly::(Kind::Doc) { + self.open_in_browser(path); + } + } + + pub(crate) fn open_in_browser(&self, path: impl AsRef) { + if self.config.dry_run || !self.config.cmd.open() { + return; + } + + let path = path.as_ref(); + self.info(&format!("Opening doc {}", path.display())); + if let Err(err) = opener::open(path) { + self.info(&format!("{}\n", err)); + } + } } #[cfg(test)] diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5d265b9ad0c19..0045856e2c957 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -12,7 +12,7 @@ use std::fs; use std::io; use std::path::{Path, PathBuf}; -use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; +use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::{Config, TargetSelection}; @@ -85,18 +85,6 @@ book!( StyleGuide, "src/doc/style-guide", "style-guide"; ); -fn open(builder: &Builder<'_>, path: impl AsRef) { - if builder.config.dry_run || !builder.config.cmd.open() { - return; - } - - let path = path.as_ref(); - builder.info(&format!("Opening doc {}", path.display())); - if let Err(err) = opener::open(path) { - builder.info(&format!("{}\n", err)); - } -} - // "library/std" -> ["library", "std"] // // Used for deciding whether a particular step is one requested by the user on @@ -240,11 +228,9 @@ impl Step for TheBook { invoke_rustdoc(builder, compiler, &shared_assets, target, path); } - if builder.was_invoked_explicitly::(Kind::Doc) { - let out = builder.doc_out(target); - let index = out.join("book").join("index.html"); - open(builder, &index); - } + let out = builder.doc_out(target); + let index = out.join("book").join("index.html"); + builder.maybe_open_in_browser::(index); } } @@ -384,10 +370,7 @@ impl Step for Standalone { // We open doc/index.html as the default if invoked as `x.py doc --open` // with no particular explicit doc requested (e.g. library/core). - if builder.paths.is_empty() || builder.was_invoked_explicitly::(Kind::Doc) { - let index = out.join("index.html"); - open(builder, &index); - } + builder.maybe_open_in_browser::(out.join("index.html")); } } @@ -507,7 +490,7 @@ impl Step for Std { for requested_crate in requested_crates { if STD_PUBLIC_CRATES.iter().any(|k| *k == requested_crate.as_str()) { let index = out.join(requested_crate).join("index.html"); - open(builder, &index); + builder.open_in_browser(index); } } } @@ -759,7 +742,7 @@ impl Step for Rustc { // Let's open the first crate documentation page: if let Some(krate) = to_open { let index = out.join(krate).join("index.html"); - open(builder, &index); + builder.open_in_browser(index); } } } @@ -1019,10 +1002,9 @@ impl Step for RustcBook { name: INTERNER.intern_str("rustc"), src: INTERNER.intern_path(out_base), }); - if builder.was_invoked_explicitly::(Kind::Doc) { - let out = builder.doc_out(self.target); - let index = out.join("rustc").join("index.html"); - open(builder, &index); - } + + let out = builder.doc_out(self.target); + let index = out.join("rustc").join("index.html"); + builder.maybe_open_in_browser::(index); } } From f8d3375b67f3c2486429b7887c1d7e54fb772ed1 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 3 Nov 2022 16:42:28 +0100 Subject: [PATCH 142/482] address review comment --- src/bootstrap/doc.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 0045856e2c957..1357718b84e35 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -12,7 +12,7 @@ use std::fs; use std::io; use std::path::{Path, PathBuf}; -use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; +use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::{Config, TargetSelection}; @@ -370,7 +370,10 @@ impl Step for Standalone { // We open doc/index.html as the default if invoked as `x.py doc --open` // with no particular explicit doc requested (e.g. library/core). - builder.maybe_open_in_browser::(out.join("index.html")); + if builder.paths.is_empty() || builder.was_invoked_explicitly::(Kind::Doc) { + let index = out.join("index.html"); + builder.open_in_browser(&index); + } } } From 2e225afd1761f551c84902925a60c916cb3e3319 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 3 Nov 2022 14:35:15 +0000 Subject: [PATCH 143/482] Do not make typo suggestions when suggesting pattern matching Fixes #103909. --- .../rustc_resolve/src/late/diagnostics.rs | 15 +++++++++++-- src/test/ui/did_you_mean/issue-103909.rs | 9 ++++++++ src/test/ui/did_you_mean/issue-103909.stderr | 21 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/did_you_mean/issue-103909.rs create mode 100644 src/test/ui/did_you_mean/issue-103909.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 103187b00d1b7..a1338dcd4771b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -322,7 +322,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } self.suggest_bare_struct_literal(&mut err); - self.suggest_pattern_match_with_let(&mut err, source, span); + + if self.suggest_pattern_match_with_let(&mut err, source, span) { + // Fallback label. + err.span_label(base_error.span, &base_error.fallback_label); + return (err, Vec::new()); + } self.suggest_self_or_self_ref(&mut err, path, span); self.detect_assoct_type_constraint_meant_as_path(&mut err, &base_error); @@ -341,7 +346,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if !self.type_ascription_suggestion(&mut err, base_error.span) { let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); + + // if we have suggested using pattern matching, then don't add needless suggestions + // for typos. fallback |= self.suggest_typo(&mut err, source, path, span, &base_error); + if fallback { // Fallback label. err.span_label(base_error.span, &base_error.fallback_label); @@ -937,7 +946,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err: &mut Diagnostic, source: PathSource<'_>, span: Span, - ) { + ) -> bool { if let PathSource::Expr(_) = source && let Some(Expr { span: expr_span, @@ -954,8 +963,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { "let ", Applicability::MaybeIncorrect, ); + return true; } } + false } fn get_single_associated_item( diff --git a/src/test/ui/did_you_mean/issue-103909.rs b/src/test/ui/did_you_mean/issue-103909.rs new file mode 100644 index 0000000000000..20b67cd102d70 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-103909.rs @@ -0,0 +1,9 @@ +#![allow(unused_variables)] +use std::fs::File; + +fn main() { + if Err(err) = File::open("hello.txt") { + //~^ ERROR: cannot find value `err` in this scope + //~| ERROR: mismatched types + } +} diff --git a/src/test/ui/did_you_mean/issue-103909.stderr b/src/test/ui/did_you_mean/issue-103909.stderr new file mode 100644 index 0000000000000..a28914051b980 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-103909.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `err` in this scope + --> $DIR/issue-103909.rs:5:12 + | +LL | if Err(err) = File::open("hello.txt") { + | ^^^ not found in this scope + | +help: you might have meant to use pattern matching + | +LL | if let Err(err) = File::open("hello.txt") { + | +++ + +error[E0308]: mismatched types + --> $DIR/issue-103909.rs:5:8 + | +LL | if Err(err) = File::open("hello.txt") { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. From 2668f9438d39d1a6f194f462004f9fc940d5cfdc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 4 Nov 2022 16:28:01 +0000 Subject: [PATCH 144/482] Remove an option and choose a behaviour-preserving default instead. --- .../rustc_hir_analysis/src/astconv/mod.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 9ad1d2bc542d7..8b1cc50a3a1f9 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -274,7 +274,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, - None, + ty::BoundConstness::NotConst, ); if let Some(b) = item_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); @@ -324,7 +324,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, - constness: Option, + constness: ty::BoundConstness, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -538,7 +538,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &mut substs_ctx, ); - if let Some(ty::BoundConstness::ConstIfConst) = constness + if let ty::BoundConstness::ConstIfConst = constness && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) { tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } ); @@ -611,7 +611,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, - None, + ty::BoundConstness::NotConst, ); if let Some(b) = item_segment.args().bindings.first() { @@ -641,7 +641,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, - Some(constness), + constness, ) } @@ -668,7 +668,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args, infer_args, Some(self_ty), - Some(constness), + constness, ); let tcx = self.tcx(); @@ -798,7 +798,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, - constness: Option, + constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { let (substs, _) = self.create_substs_for_ast_trait_ref( span, @@ -822,7 +822,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, is_impl: bool, - constness: Option, + constness: ty::BoundConstness, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl); @@ -2129,7 +2129,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_segment, false, - Some(constness), + constness, ); let item_substs = self.create_substs_for_associated_item( @@ -2700,7 +2700,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &GenericArgs::none(), true, None, - None, + ty::BoundConstness::NotConst, ); EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id))) .subst(tcx, substs) From 014ad0e2510536273c8c8d82cdfe00e7ed57e0db Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 4 Nov 2022 22:36:04 +0100 Subject: [PATCH 145/482] Fix search result bottom border color --- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/librustdoc/html/static/css/themes/ayu.css | 1 + src/librustdoc/html/static/css/themes/dark.css | 1 + src/librustdoc/html/static/css/themes/light.css | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 61a50a9bd1392..9ee926e1ab0ae 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -886,7 +886,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ /* A little margin ensures the browser's outlining of focused links has room to display. */ margin-left: 2px; margin-right: 2px; - border-bottom: 1px solid var(--border-color); + border-bottom: 1px solid var(--search-result-border-color); gap: 1em; } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index fdfdb3e196672..762384481e695 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -38,6 +38,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) --sidebar-link-color: #53b1db; --sidebar-current-link-background-color: transparent; --search-result-link-focus-background-color: #3c3c3c; + --search-result-border-color: #aaa3; --stab-background-color: #314559; --stab-code-color: #e6e1cf; --search-color: #fff; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 361d3d4a22597..1424de5137cce 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -33,6 +33,7 @@ --sidebar-link-color: #fdbf35; --sidebar-current-link-background-color: #444; --search-result-link-focus-background-color: #616161; + --search-result-border-color: #aaa3; --stab-background-color: #314559; --stab-code-color: #e6e1cf; --search-color: #111; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 5eb4bbcf834bb..a7ce56c95c7e4 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -33,6 +33,7 @@ --sidebar-link-color: #356da4; --sidebar-current-link-background-color: #fff; --search-result-link-focus-background-color: #ccc; + --search-result-border-color: #aaa3; --stab-background-color: #fff5d6; --stab-code-color: #000; --search-color: #000; From 8029a25cf4a5719eb0380fa5839a3b68345752bf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 4 Nov 2022 22:36:14 +0100 Subject: [PATCH 146/482] Update GUI test for bottom border color --- src/test/rustdoc-gui/search-result-color.goml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 0c3b111907424..d437ad75970bc 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -78,7 +78,7 @@ assert-css: ( // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgb(92, 103, 115)"} + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} ) // Checking the color of "keyword" text. @@ -190,7 +190,7 @@ assert-css: ( // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgb(224, 224, 224)"} + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} ) // Checking the color for "keyword" text. @@ -287,7 +287,7 @@ assert-css: ( // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgb(224, 224, 224)"} + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} ) // Checking the color for "keyword" text. From 84ec6583dd6d2717e9e0e06c01ec825d004020d2 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 29 Sep 2022 17:27:03 +0900 Subject: [PATCH 147/482] Stabilize the `instruction_set` feature Signed-off-by: Yuki Okushi --- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/active.rs | 2 -- compiler/rustc_feature/src/builtin_attrs.rs | 6 +---- src/test/ui/asm/issue-92378.rs | 2 +- src/test/ui/error-codes/E0778.rs | 8 ++---- src/test/ui/error-codes/E0778.stderr | 2 +- src/test/ui/error-codes/E0779.rs | 6 +---- src/test/ui/error-codes/E0779.stderr | 2 +- .../feature-gate-isa_attribute.rs | 6 ----- .../feature-gate-isa_attribute.stderr | 25 ------------------- 10 files changed, 9 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-isa_attribute.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-isa_attribute.stderr diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index db289a64046a7..c2aa096a99315 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -191,6 +191,8 @@ declare_features! ( (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None), /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None), + /// Allows `#[instruction_set(_)]` attribute. + (accepted, isa_attribute, "CURRENT_RUSTC_VERSION", Some(74727), None), /// Allows some increased flexibility in the name resolution rules, /// especially around globs and shadowing (RFC 1560). (accepted, item_like_imports, "1.15.0", Some(35120), None), diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 7900f1500489e..09a747662e266 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -427,8 +427,6 @@ declare_features! ( (incomplete, inline_const_pat, "1.58.0", Some(76001), None), /// Allows using `pointer` and `reference` in intra-doc links (active, intra_doc_pointers, "1.51.0", Some(80896), None), - /// Allows `#[instruction_set(_)]` attribute - (active, isa_attribute, "1.48.0", Some(74727), None), // Allows setting the threshold for the `large_assignments` lint. (active, large_assignments, "1.52.0", Some(83518), None), /// Allows `if/while p && let q = r && ...` chains. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 14c8e3c458c49..4ff3b3f2a38b3 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -391,6 +391,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ DuplicatesOk, @only_local: true, ), ungated!(track_caller, Normal, template!(Word), WarnFollowing), + ungated!(instruction_set, Normal, template!(List: "set"), ErrorPreceding), gated!( no_sanitize, Normal, template!(List: "address, memory, thread"), DuplicatesOk, @@ -452,11 +453,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ optimize, Normal, template!(List: "size|speed"), ErrorPreceding, optimize_attribute, experimental!(optimize), ), - // RFC 2867 - gated!( - instruction_set, Normal, template!(List: "set"), ErrorPreceding, - isa_attribute, experimental!(instruction_set) - ), gated!( ffi_returns_twice, Normal, template!(Word), WarnFollowing, experimental!(ffi_returns_twice) diff --git a/src/test/ui/asm/issue-92378.rs b/src/test/ui/asm/issue-92378.rs index 6e3c26e98c3f6..809b0d1555ae4 100644 --- a/src/test/ui/asm/issue-92378.rs +++ b/src/test/ui/asm/issue-92378.rs @@ -3,7 +3,7 @@ // needs-asm-support // build-pass -#![feature(no_core, lang_items, rustc_attrs, isa_attribute)] +#![feature(no_core, lang_items, rustc_attrs)] #![no_core] #![crate_type = "rlib"] diff --git a/src/test/ui/error-codes/E0778.rs b/src/test/ui/error-codes/E0778.rs index 60e5c2598f1ee..74653886d4154 100644 --- a/src/test/ui/error-codes/E0778.rs +++ b/src/test/ui/error-codes/E0778.rs @@ -1,8 +1,4 @@ -#![feature(isa_attribute)] - #[instruction_set()] //~ ERROR -fn no_isa_defined() { -} +fn no_isa_defined() {} -fn main() { -} +fn main() {} diff --git a/src/test/ui/error-codes/E0778.stderr b/src/test/ui/error-codes/E0778.stderr index 6ecae79242377..42647e5c6a1b9 100644 --- a/src/test/ui/error-codes/E0778.stderr +++ b/src/test/ui/error-codes/E0778.stderr @@ -1,5 +1,5 @@ error[E0778]: `#[instruction_set]` requires an argument - --> $DIR/E0778.rs:3:1 + --> $DIR/E0778.rs:1:1 | LL | #[instruction_set()] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0779.rs b/src/test/ui/error-codes/E0779.rs index 1b4dbce20360c..c32dae12c9cbf 100644 --- a/src/test/ui/error-codes/E0779.rs +++ b/src/test/ui/error-codes/E0779.rs @@ -1,6 +1,2 @@ -#![feature(isa_attribute)] - #[instruction_set(arm::magic)] //~ ERROR -fn main() { - -} +fn main() {} diff --git a/src/test/ui/error-codes/E0779.stderr b/src/test/ui/error-codes/E0779.stderr index da787260d4f6d..7c6a119a09615 100644 --- a/src/test/ui/error-codes/E0779.stderr +++ b/src/test/ui/error-codes/E0779.stderr @@ -1,5 +1,5 @@ error[E0779]: invalid instruction set specified - --> $DIR/E0779.rs:3:1 + --> $DIR/E0779.rs:1:1 | LL | #[instruction_set(arm::magic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-isa_attribute.rs b/src/test/ui/feature-gates/feature-gate-isa_attribute.rs deleted file mode 100644 index cb02a0955e913..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-isa_attribute.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[instruction_set] -//~^ ERROR the `#[instruction_set]` attribute is an experimental feature [E0658] -//~| ERROR malformed `instruction_set` attribute input -//~| ERROR must specify an instruction set [E0778] -fn main() { -} diff --git a/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr b/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr deleted file mode 100644 index 2a95a80ca6178..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: malformed `instruction_set` attribute input - --> $DIR/feature-gate-isa_attribute.rs:1:1 - | -LL | #[instruction_set] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` - -error[E0658]: the `#[instruction_set]` attribute is an experimental feature - --> $DIR/feature-gate-isa_attribute.rs:1:1 - | -LL | #[instruction_set] - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #74727 for more information - = help: add `#![feature(isa_attribute)]` to the crate attributes to enable - -error[E0778]: must specify an instruction set - --> $DIR/feature-gate-isa_attribute.rs:1:1 - | -LL | #[instruction_set] - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0658, E0778. -For more information about an error, try `rustc --explain E0658`. From 17e5ba49f4c1fce61281819f134a526d28407613 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 16:04:43 +0100 Subject: [PATCH 148/482] Merge `QueryDescription` into `QueryConfig` `QueryDescription` has gone through a lot of refactoring and doesn't make sense anymore. --- compiler/rustc_query_impl/src/lib.rs | 2 +- .../rustc_query_impl/src/on_disk_cache.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 29 ++++++------ .../rustc_query_system/src/query/config.rs | 44 +++++++++---------- compiler/rustc_query_system/src/query/mod.rs | 2 +- .../rustc_query_system/src/query/plumbing.rs | 8 ++-- 6 files changed, 42 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 11d4c97e71ca0..18cb0e0ca0b15 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -36,7 +36,7 @@ mod keys; use keys::Key; pub use rustc_query_system::query::QueryConfig; -pub(crate) use rustc_query_system::query::{QueryDescription, QueryVTable}; +pub(crate) use rustc_query_system::query::QueryVTable; mod on_disk_cache; pub use on_disk_cache::OnDiskCache; diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 8b14ce210a205..a6cb8f7bd5532 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -1063,7 +1063,7 @@ pub fn encode_query_results<'a, 'tcx, CTX, Q>( query_result_index: &mut EncodedDepNodeIndex, ) where CTX: QueryContext + 'tcx, - Q: super::QueryDescription, + Q: super::QueryConfig, Q::Value: Encodable>, { let _timer = tcx diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 1d17f4221969d..992e777904e6b 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -17,8 +17,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap, - QuerySideEffects, QueryStackFrame, + force_query, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, }; use rustc_query_system::{LayoutOfDepth, QueryOverflow, Value}; use rustc_serialize::Decodable; @@ -340,7 +339,7 @@ pub(crate) fn create_query_frame< fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) where - Q: QueryDescription>, + Q: QueryConfig>, Q::Key: DepNodeParams>, { debug_assert!(tcx.dep_graph.is_green(&dep_node)); @@ -365,7 +364,7 @@ where fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where - Q: QueryDescription>, + Q: QueryConfig>, Q::Key: DepNodeParams>, Q::Value: Value>, { @@ -398,12 +397,9 @@ where } } -pub(crate) fn query_callback<'tcx, Q: QueryConfig>( - is_anon: bool, - is_eval_always: bool, -) -> DepKindStruct<'tcx> +pub(crate) fn query_callback<'tcx, Q>(is_anon: bool, is_eval_always: bool) -> DepKindStruct<'tcx> where - Q: QueryDescription>, + Q: QueryConfig>, Q::Key: DepNodeParams>, { let fingerprint_style = Q::Key::fingerprint_style(); @@ -458,14 +454,12 @@ macro_rules! define_queries { })* } - $(impl<'tcx> QueryConfig for queries::$name<'tcx> { + $(impl<'tcx> QueryConfig> for queries::$name<'tcx> { type Key = query_keys::$name<'tcx>; type Value = query_values::$name<'tcx>; type Stored = query_stored::$name<'tcx>; const NAME: &'static str = stringify!($name); - } - impl<'tcx> QueryDescription> for queries::$name<'tcx> { #[inline] fn cache_on_disk(tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { ::rustc_middle::query::cached::$name(tcx, key) @@ -662,12 +656,15 @@ macro_rules! define_queries_struct { local_providers: Box, extern_providers: Box, query_structs: Vec<$crate::plumbing::QueryStruct<'tcx>>, - pub on_disk_cache: Option>, - jobs: AtomicU64, - $($(#[$attr])* $name: QueryState< as QueryConfig>::Key>,)* + $( + $(#[$attr])* + $name: QueryState< + as QueryConfig>>::Key + >, + )* } impl<'tcx> Queries<'tcx> { @@ -704,7 +701,7 @@ macro_rules! define_queries_struct { &'tcx self, tcx: TyCtxt<'tcx>, span: Span, - key: as QueryConfig>::Key, + key: as QueryConfig>>::Key, mode: QueryMode, ) -> Option> { let qcx = QueryCtxt { tcx, queries: self }; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 0a1cffa3b3331..db3ae559ad15d 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -11,12 +11,32 @@ use rustc_data_structures::fingerprint::Fingerprint; use std::fmt::Debug; use std::hash::Hash; -pub trait QueryConfig { +pub trait QueryConfig { const NAME: &'static str; type Key: Eq + Hash + Clone + Debug; type Value; type Stored: Clone; + + type Cache: QueryCache; + + // Don't use this method to access query results, instead use the methods on TyCtxt + fn query_state<'a>(tcx: CTX) -> &'a QueryState + where + CTX: 'a; + + // Don't use this method to access query results, instead use the methods on TyCtxt + fn query_cache<'a>(tcx: CTX) -> &'a Self::Cache + where + CTX: 'a; + + // Don't use this method to compute query results, instead use the methods on TyCtxt + fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable; + + fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool; + + // Don't use this method to compute query results, instead use the methods on TyCtxt + fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored; } #[derive(Copy, Clone)] @@ -45,25 +65,3 @@ impl QueryVTable { (self.compute)(tcx, key) } } - -pub trait QueryDescription: QueryConfig { - type Cache: QueryCache; - - // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state<'a>(tcx: CTX) -> &'a QueryState - where - CTX: 'a; - - // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_cache<'a>(tcx: CTX) -> &'a Self::Cache - where - CTX: 'a; - - // Don't use this method to compute query results, instead use the methods on TyCtxt - fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable; - - fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool; - - // Don't use this method to compute query results, instead use the methods on TyCtxt - fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored; -} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 118703fc0d48c..94adef41e68fe 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -12,7 +12,7 @@ pub use self::caches::{ }; mod config; -pub use self::config::{QueryConfig, QueryDescription, QueryVTable}; +pub use self::config::{QueryConfig, QueryVTable}; use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; use rustc_data_structures::sync::Lock; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 15b89daa6db11..0f7abe84231b6 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -4,7 +4,7 @@ use crate::dep_graph::{DepContext, DepNode, DepNodeIndex, DepNodeParams}; use crate::query::caches::QueryCache; -use crate::query::config::{QueryDescription, QueryVTable}; +use crate::query::config::QueryVTable; use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame}; use crate::values::Value; @@ -27,6 +27,8 @@ use std::mem; use std::ptr; use thin_vec::ThinVec; +use super::QueryConfig; + pub struct QueryState { #[cfg(parallel_compiler)] active: Sharded>, @@ -715,7 +717,7 @@ pub enum QueryMode { pub fn get_query(tcx: CTX, span: Span, key: Q::Key, mode: QueryMode) -> Option where - Q: QueryDescription, + Q: QueryConfig, Q::Key: DepNodeParams, Q::Value: Value, CTX: QueryContext, @@ -748,7 +750,7 @@ where pub fn force_query(tcx: CTX, key: Q::Key, dep_node: DepNode) where - Q: QueryDescription, + Q: QueryConfig, Q::Key: DepNodeParams, Q::Value: Value, CTX: QueryContext, From 23dc9f6a7b72f77c22fbf5f47318bd9f98350303 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 20 Oct 2022 09:39:09 +0000 Subject: [PATCH 149/482] Some tracing and comment cleanups --- .../src/transform/check_consts/qualifs.rs | 3 ++ compiler/rustc_hir/src/hir.rs | 2 ++ compiler/rustc_hir_typeck/src/callee.rs | 5 +-- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 4 +-- .../rustc_mir_dataflow/src/elaborate_drops.rs | 5 ++- compiler/rustc_mir_transform/src/shim.rs | 8 ++--- compiler/rustc_trait_selection/src/infer.rs | 12 ++----- .../rustc_trait_selection/src/traits/mod.rs | 34 +++---------------- .../src/traits/select/mod.rs | 4 ++- 10 files changed, 23 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 335992342a647..d995d533ca3e4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -146,6 +146,7 @@ impl Qualif for NeedsNonConstDrop { qualifs.needs_non_const_drop } + #[instrument(level = "trace", skip(cx), ret)] fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { // Avoid selecting for simple cases, such as builtin types. if ty::util::is_trivially_const_drop(ty) { @@ -174,6 +175,8 @@ impl Qualif for NeedsNonConstDrop { return true; }; + trace!(?impl_src); + if !matches!( impl_src, ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ef00c1ffc302d..82e260d158bc4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -388,6 +388,8 @@ impl<'hir> GenericArgs<'hir> { } #[inline] + /// This function returns the number of type and const generic params. + /// It should only be used for diagnostics. pub fn num_generic_params(&self) -> usize { self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count() } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 1b33f2f02b8ad..000f4c9b68427 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -129,6 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { output } + #[instrument(level = "debug", skip(self, call_expr, callee_expr, arg_exprs, autoderef), ret)] fn try_overloaded_call_step( &self, call_expr: &'tcx hir::Expr<'tcx>, @@ -138,10 +139,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option> { let adjusted_ty = self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false)); - debug!( - "try_overloaded_call_step(call_expr={:?}, adjusted_ty={:?})", - call_expr, adjusted_ty - ); // If the callee is a bare function or a closure, then we're all set. match *adjusted_ty.kind() { diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 365b4b1fccdb4..aa44d582fd6ce 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -495,7 +495,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } ty::ConstKind::Bound(debruijn, _) => { if debruijn >= self.binder_index { - bug!("escaping bound type during canonicalization") + bug!("escaping bound const during canonicalization") } else { return ct; } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 6c1414f7b8ac8..ae0f158ede99a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -511,12 +511,12 @@ impl<'tcx> Instance<'tcx> { Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap().unwrap() } + #[instrument(level = "debug", skip(tcx), ret)] pub fn fn_once_adapter_instance( tcx: TyCtxt<'tcx>, closure_did: DefId, substs: ty::SubstsRef<'tcx>, ) -> Option> { - debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs); let fn_once = tcx.require_lang_item(LangItem::FnOnce, None); let call_once = tcx .associated_items(fn_once) @@ -536,7 +536,7 @@ impl<'tcx> Instance<'tcx> { assert_eq!(sig.inputs().len(), 1); let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); - debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); + debug!(?self_ty, ?sig); Some(Instance { def, substs }) } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 23403628c53fa..14d265a402ef8 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -407,9 +407,8 @@ where self.drop_ladder(fields, succ, unwind).0 } + #[instrument(level = "debug", ret)] fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock { - debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs); - // drop glue is sent straight to codegen // box cannot be directly dereferenced let unique_ty = adt.non_enum_variant().fields[0].ty(self.tcx(), substs); @@ -431,8 +430,8 @@ where self.drop_subpath(interior, interior_path, succ, unwind_succ) } + #[instrument(level = "debug", ret)] fn open_drop_for_adt(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock { - debug!("open_drop_for_adt({:?}, {:?}, {:?})", self, adt, substs); if adt.variants().is_empty() { return self.elaborator.patch().new_block(BasicBlockData { statements: vec![], diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index bf5906741441d..a0ff7550faeb8 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -569,17 +569,13 @@ impl<'tcx> CloneShimBuilder<'tcx> { /// Builds a "call" shim for `instance`. The shim calls the function specified by `call_kind`, /// first adjusting its first argument according to `rcvr_adjustment`. +#[instrument(level = "debug", skip(tcx), ret)] fn build_call_shim<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>, rcvr_adjustment: Option, call_kind: CallKind<'tcx>, ) -> Body<'tcx> { - debug!( - "build_call_shim(instance={:?}, rcvr_adjustment={:?}, call_kind={:?})", - instance, rcvr_adjustment, call_kind - ); - // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used // to substitute into the signature of the shim. It is not necessary for users of this // MIR body to perform further substitutions (see `InstanceDef::has_polymorphic_mir_body`). @@ -641,7 +637,7 @@ fn build_call_shim<'tcx>( let span = tcx.def_span(def_id); - debug!("build_call_shim: sig={:?}", sig); + debug!(?sig); let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo::outermost(span); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 96ac4e9c1292a..0f2e22604dc7e 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -93,6 +93,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { /// Normalizes associated types in `value`, potentially returning /// new obligations that must further be processed. + #[instrument(level = "debug", skip(self, cause, param_env), ret)] fn partially_normalize_associated_types_in( &self, cause: ObligationCause<'tcx>, @@ -102,17 +103,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - debug!("partially_normalize_associated_types_in(value={:?})", value); let mut selcx = traits::SelectionContext::new(self); let traits::Normalized { value, obligations } = traits::normalize(&mut selcx, param_env, cause, value); - debug!( - "partially_normalize_associated_types_in: result={:?} predicates={:?}", - value, obligations - ); InferOk { value, obligations } } + #[instrument(level = "debug", skip(self), ret)] fn type_implements_trait( &self, trait_def_id: DefId, @@ -120,11 +117,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { params: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { - debug!( - "type_implements_trait: trait_def_id={:?}, type={:?}, params={:?}, param_env={:?}", - trait_def_id, ty, params, param_env - ); - let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) }; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 9ee6e0a2bf3a2..3417bb87c2049 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -117,14 +117,12 @@ pub enum TraitQueryMode { } /// Creates predicate obligations from the generic bounds. +#[instrument(level = "debug", skip(cause, param_env))] pub fn predicates_for_generics<'tcx>( cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { - let generic_bounds = generic_bounds; - debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map( move |(idx, (predicate, span))| Obligation { cause: cause(idx, span), @@ -140,6 +138,7 @@ pub fn predicates_for_generics<'tcx>( /// `bound` or is not known to meet bound (note that this is /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). +#[instrument(level = "debug", skip(infcx, param_env, span), ret)] pub fn type_known_to_meet_bound_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -147,12 +146,6 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, span: Span, ) -> bool { - debug!( - "type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})", - ty, - infcx.tcx.def_path_str(def_id) - ); - let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }); let obligation = Obligation { @@ -163,12 +156,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); - debug!( - "type_known_to_meet_ty={:?} bound={} => {:?}", - ty, - infcx.tcx.def_path_str(def_id), - result - ); + debug!(?result); if result && ty.has_non_region_infer() { // Because of inference "guessing", selection can sometimes claim @@ -190,21 +178,9 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( // *definitively* show that it implements `Copy`. Otherwise, // assume it is move; linear is always ok. match &errors[..] { - [] => { - debug!( - "type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success", - ty, - infcx.tcx.def_path_str(def_id) - ); - true - } + [] => true, errors => { - debug!( - ?ty, - bound = %infcx.tcx.def_path_str(def_id), - ?errors, - "type_known_to_meet_bound_modulo_regions" - ); + debug!(?errors); false } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9ebff48920160..84be1ced520fe 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1132,12 +1132,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// filter_impls filters constant trait obligations and candidates that have a positive impl /// for a negative goal and a negative impl for a positive goal - #[instrument(level = "debug", skip(self))] + #[instrument(level = "debug", skip(self, candidates))] fn filter_impls( &mut self, candidates: Vec>, obligation: &TraitObligation<'tcx>, ) -> Vec> { + trace!("{candidates:#?}"); let tcx = self.tcx(); let mut result = Vec::with_capacity(candidates.len()); @@ -1177,6 +1178,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + trace!("{result:#?}"); result } From cedc74bad436e68dcfbcbc8f87a9dff2f566bf1f Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Mon, 3 Oct 2022 12:14:48 +0300 Subject: [PATCH 150/482] simplify applying closure requirements Don't use `ConstraintCategory::ClosureBounds`! Set the category and the span for the promoted constraints to that of the original constraint earlier than before. This eliminates the need for `closure_bounds_mapping`. --- .../rustc_borrowck/src/constraints/graph.rs | 1 + .../rustc_borrowck/src/constraints/mod.rs | 3 + compiler/rustc_borrowck/src/nll.rs | 2 - .../src/region_infer/dump_mir.rs | 3 +- .../rustc_borrowck/src/region_infer/mod.rs | 146 ++---------------- .../src/type_check/constraint_conversion.rs | 75 +++++++-- compiler/rustc_borrowck/src/type_check/mod.rs | 96 +++--------- .../src/type_check/relate_tys.rs | 1 + ...tion-two-region-trait-bound-closure.stderr | 7 +- 9 files changed, 97 insertions(+), 237 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index 609fbc2bc1515..385f153174c3c 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -163,6 +163,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> { span: DUMMY_SP, category: ConstraintCategory::Internal, variance_info: VarianceDiagInfo::default(), + from_closure: false, }) } else { None diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index df04128135b89..9d9c4abb0aa57 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -96,6 +96,9 @@ pub struct OutlivesConstraint<'tcx> { /// Variance diagnostic information pub variance_info: VarianceDiagInfo<'tcx>, + + /// If this constraint is promoted from closure requirements. + pub from_closure: bool, } impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 08fdd28eb01b7..4e0205f8d43a1 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -242,7 +242,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>( mut liveness_constraints, outlives_constraints, member_constraints, - closure_bounds_mapping, universe_causes, type_tests, } = constraints; @@ -264,7 +263,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>( universal_region_relations, outlives_constraints, member_constraints, - closure_bounds_mapping, universe_causes, type_tests, liveness_constraints, diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index fe5193102f958..cc9450999525a 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -74,8 +74,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); constraints.sort_by_key(|c| (c.sup, c.sub)); for constraint in &constraints { - let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } = - constraint; + let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint; let (name, arg) = match locations { Locations::All(span) => { ("All", tcx.sess.source_map().span_to_embeddable_string(*span)) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 0e7f243bcf36c..6782fc0665f04 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; -use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::CRATE_HIR_ID; use rustc_index::vec::IndexVec; -use rustc_infer::infer::canonical::QueryOutlivesConstraint; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; @@ -19,9 +18,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::{ - self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable, -}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_span::Span; use crate::{ @@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> { /// `member_region_scc`. member_constraints_applied: Vec, - /// Map closure bounds to a `Span` that should be used for error reporting. - closure_bounds_mapping: - FxHashMap, Span)>>, - /// Map universe indexes to information on why we created it. universe_causes: FxHashMap>, @@ -265,10 +258,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { universal_region_relations: Frozen>, outlives_constraints: OutlivesConstraintSet<'tcx>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, - closure_bounds_mapping: FxHashMap< - Location, - FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>, - >, universe_causes: FxHashMap>, type_tests: Vec>, liveness_constraints: LivenessValues, @@ -310,7 +299,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { rev_scc_graph: None, member_constraints, member_constraints_applied: Vec::new(), - closure_bounds_mapping, universe_causes, scc_universes, scc_representatives, @@ -1804,18 +1792,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - pub(crate) fn retrieve_closure_constraint_info( - &self, - constraint: OutlivesConstraint<'tcx>, - ) -> Option<(ConstraintCategory<'tcx>, Span)> { - match constraint.locations { - Locations::All(_) => None, - Locations::Single(loc) => { - self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied() - } - } - } - /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`. pub(crate) fn find_outlives_blame_span( &self, @@ -1921,6 +1897,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { span: p_c.definition_span, category: ConstraintCategory::OpaqueType, variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, }; handle_constraint(constraint); } @@ -2066,31 +2043,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Classify each of the constraints along the path. let mut categorized_path: Vec> = path .iter() - .map(|constraint| { - let (category, span, from_closure, cause_code) = - if constraint.category == ConstraintCategory::ClosureBounds { - if let Some((category, span)) = - self.retrieve_closure_constraint_info(*constraint) - { - (category, span, true, ObligationCauseCode::MiscObligation) - } else { - ( - constraint.category, - constraint.span, - false, - ObligationCauseCode::MiscObligation, - ) - } - } else { - (constraint.category, constraint.span, false, cause_code.clone()) - }; - BlameConstraint { - category, - from_closure, - cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code), - variance_info: constraint.variance_info, - outlives_constraint: *constraint, - } + .map(|constraint| BlameConstraint { + category: constraint.category, + from_closure: constraint.from_closure, + cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()), + variance_info: constraint.variance_info, + outlives_constraint: *constraint, }) .collect(); debug!("categorized_path={:#?}", categorized_path); @@ -2274,92 +2232,6 @@ impl<'tcx> RegionDefinition<'tcx> { } } -pub trait ClosureRegionRequirementsExt<'tcx> { - fn apply_requirements( - &self, - tcx: TyCtxt<'tcx>, - closure_def_id: DefId, - closure_substs: SubstsRef<'tcx>, - ) -> Vec>; -} - -impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> { - /// Given an instance T of the closure type, this method - /// instantiates the "extra" requirements that we computed for the - /// closure into the inference context. This has the effect of - /// adding new outlives obligations to existing variables. - /// - /// As described on `ClosureRegionRequirements`, the extra - /// requirements are expressed in terms of regionvids that index - /// into the free regions that appear on the closure type. So, to - /// do this, we first copy those regions out from the type T into - /// a vector. Then we can just index into that vector to extract - /// out the corresponding region from T and apply the - /// requirements. - fn apply_requirements( - &self, - tcx: TyCtxt<'tcx>, - closure_def_id: DefId, - closure_substs: SubstsRef<'tcx>, - ) -> Vec> { - debug!( - "apply_requirements(closure_def_id={:?}, closure_substs={:?})", - closure_def_id, closure_substs - ); - - // Extract the values of the free regions in `closure_substs` - // into a vector. These are the regions that we will be - // relating to one another. - let closure_mapping = &UniversalRegions::closure_mapping( - tcx, - closure_substs, - self.num_external_vids, - closure_def_id.expect_local(), - ); - debug!("apply_requirements: closure_mapping={:?}", closure_mapping); - - // Create the predicates. - self.outlives_requirements - .iter() - .map(|outlives_requirement| { - let outlived_region = closure_mapping[outlives_requirement.outlived_free_region]; - - match outlives_requirement.subject { - ClosureOutlivesSubject::Region(region) => { - let region = closure_mapping[region]; - debug!( - "apply_requirements: region={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - region, outlived_region, outlives_requirement, - ); - ( - ty::Binder::dummy(ty::OutlivesPredicate( - region.into(), - outlived_region, - )), - ConstraintCategory::BoringNoLocation, - ) - } - - ClosureOutlivesSubject::Ty(ty) => { - debug!( - "apply_requirements: ty={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - ty, outlived_region, outlives_requirement, - ); - ( - ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)), - ConstraintCategory::BoringNoLocation, - ) - } - } - }) - .collect() - } -} - #[derive(Clone, Debug)] pub struct BlameConstraint<'tcx> { pub category: ConstraintCategory<'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index d5bfc2f520826..88be80c0b558d 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -1,10 +1,10 @@ -use rustc_infer::infer::canonical::QueryOutlivesConstraint; +use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; -use rustc_middle::mir::ConstraintCategory; +use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, TyCtxt}; @@ -38,6 +38,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> { locations: Locations, span: Span, category: ConstraintCategory<'tcx>, + from_closure: bool, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, } @@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { span, category, constraints, + from_closure: false, } } @@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } self.constraints.member_constraints = tmp; - for query_constraint in outlives { - self.convert(query_constraint); + for (predicate, constraint_category) in outlives { + // At the moment, we never generate any "higher-ranked" + // region constraints like `for<'a> 'a: 'b`. At some point + // when we move to universes, we will, and this assertion + // will start to fail. + let predicate = predicate.no_bound_vars().unwrap_or_else(|| { + bug!("query_constraint {:?} contained bound vars", predicate,); + }); + + self.convert(predicate, *constraint_category); + } + } + + /// Given an instance of the closure type, this method instantiates the "extra" requirements + /// that we computed for the closure. This has the effect of adding new outlives obligations + /// to existing region variables in `closure_substs`. + #[instrument(skip(self), level = "debug")] + pub fn apply_closure_requirements( + &mut self, + closure_requirements: &ClosureRegionRequirements<'tcx>, + closure_def_id: DefId, + closure_substs: ty::SubstsRef<'tcx>, + ) { + // Extract the values of the free regions in `closure_substs` + // into a vector. These are the regions that we will be + // relating to one another. + let closure_mapping = &UniversalRegions::closure_mapping( + self.tcx, + closure_substs, + closure_requirements.num_external_vids, + closure_def_id.expect_local(), + ); + debug!(?closure_mapping); + + // Create the predicates. + let backup = (self.category, self.span, self.from_closure); + self.from_closure = true; + for outlives_requirement in &closure_requirements.outlives_requirements { + let outlived_region = closure_mapping[outlives_requirement.outlived_free_region]; + let subject = match outlives_requirement.subject { + ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(), + ClosureOutlivesSubject::Ty(ty) => ty.into(), + }; + + self.category = outlives_requirement.category; + self.span = outlives_requirement.blame_span; + self.convert(ty::OutlivesPredicate(subject, outlived_region), self.category); } + (self.category, self.span, self.from_closure) = backup; } - fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) { + fn convert( + &mut self, + predicate: ty::OutlivesPredicate, ty::Region<'tcx>>, + constraint_category: ConstraintCategory<'tcx>, + ) { debug!("generate: constraints at: {:#?}", self.locations); // Extract out various useful fields we'll need below. @@ -94,17 +146,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { tcx, region_bound_pairs, implicit_region_bound, param_env, .. } = *self; - // At the moment, we never generate any "higher-ranked" - // region constraints like `for<'a> 'a: 'b`. At some point - // when we move to universes, we will, and this assertion - // will start to fail. - let ty::OutlivesPredicate(k1, r2) = - query_constraint.0.no_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", query_constraint,); - }); - - let constraint_category = query_constraint.1; - + let ty::OutlivesPredicate(k1, r2) = predicate; match k1.unpack() { GenericArgKind::Lifetime(r1) => { let r1_vid = self.to_region_vid(r1); @@ -188,6 +230,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { sub, sup, variance_info: ty::VarianceDiagInfo::default(), + from_closure: self.from_closure, }); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3c1c3ab45ce7a..3d9e08b4ca7ba 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -27,7 +27,7 @@ use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts}; +use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, @@ -61,7 +61,7 @@ use crate::{ region_infer::values::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, }, - region_infer::{ClosureRegionRequirementsExt, TypeTest}, + region_infer::TypeTest, type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, universal_regions::{DefiningTy, UniversalRegions}, Upvar, @@ -144,7 +144,6 @@ pub(crate) fn type_check<'mir, 'tcx>( liveness_constraints: LivenessValues::new(elements.clone()), outlives_constraints: OutlivesConstraintSet::default(), member_constraints: MemberConstraintSet::default(), - closure_bounds_mapping: Default::default(), type_tests: Vec::default(), universe_causes: FxHashMap::default(), }; @@ -585,7 +584,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let all_facts = &mut None; let mut constraints = Default::default(); let mut type_tests = Default::default(); - let mut closure_bounds = Default::default(); let mut liveness_constraints = LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body))); // Don't try to add borrow_region facts for the promoted MIR @@ -597,10 +595,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { &mut constraints, ); mem::swap(&mut this.cx.borrowck_context.constraints.type_tests, &mut type_tests); - mem::swap( - &mut this.cx.borrowck_context.constraints.closure_bounds_mapping, - &mut closure_bounds, - ); mem::swap( &mut this.cx.borrowck_context.constraints.liveness_constraints, &mut liveness_constraints, @@ -653,18 +647,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { .add_element(region, location); } } - - if !closure_bounds.is_empty() { - let combined_bounds_mapping = - closure_bounds.into_iter().flat_map(|(_, value)| value).collect(); - let existing = self - .cx - .borrowck_context - .constraints - .closure_bounds_mapping - .insert(location, combined_bounds_mapping); - assert!(existing.is_none(), "Multiple promoteds/closures at the same location."); - } } fn sanitize_projection( @@ -941,9 +923,6 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, - pub(crate) closure_bounds_mapping: - FxHashMap, Span)>>, - pub(crate) universe_causes: FxHashMap>, pub(crate) type_tests: Vec>, @@ -2562,6 +2541,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span: location.to_locations().span(body), category, variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, }); match mutbl { @@ -2679,62 +2659,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { substs: SubstsRef<'tcx>, location: Location, ) -> ty::InstantiatedPredicates<'tcx> { - if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements - { - let closure_constraints = QueryRegionConstraints { - outlives: closure_region_requirements.apply_requirements( - tcx, - def_id.to_def_id(), - substs, - ), - - // Presently, closures never propagate member - // constraints to their parents -- they are enforced - // locally. This is largely a non-issue as member - // constraints only come from `-> impl Trait` and - // friends which don't appear (thus far...) in - // closures. - member_constraints: vec![], - }; - - let bounds_mapping = closure_constraints - .outlives - .iter() - .enumerate() - .filter_map(|(idx, constraint)| { - let ty::OutlivesPredicate(k1, r2) = - constraint.0.no_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", constraint,); - }); - - match k1.unpack() { - GenericArgKind::Lifetime(r1) => { - // constraint is r1: r2 - let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1); - let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2); - let outlives_requirements = - &closure_region_requirements.outlives_requirements[idx]; - Some(( - (r1_vid, r2_vid), - (outlives_requirements.category, outlives_requirements.blame_span), - )) - } - GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, - } - }) - .collect(); - - let existing = self - .borrowck_context - .constraints - .closure_bounds_mapping - .insert(location, bounds_mapping); - assert!(existing.is_none(), "Multiple closures at the same location."); - - self.push_region_constraints( + if let Some(ref closure_requirements) = tcx.mir_borrowck(def_id).closure_requirements { + constraint_conversion::ConstraintConversion::new( + self.infcx, + self.borrowck_context.universal_regions, + self.region_bound_pairs, + self.implicit_region_bound, + self.param_env, location.to_locations(), - ConstraintCategory::ClosureBounds, - &closure_constraints, + DUMMY_SP, // irrelevant; will be overrided. + ConstraintCategory::Boring, // same as above. + &mut self.borrowck_context.constraints, + ) + .apply_closure_requirements( + &closure_requirements, + def_id.to_def_id(), + substs, ); } diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 4f2dc263bf57b..94d5103286609 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -136,6 +136,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> span: self.locations.span(self.type_checker.body), category: self.category, variance_info: info, + from_closure: false, }, ); } diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 0195a693e5ffb..1260a656c98f2 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -167,7 +167,7 @@ LL | | T: Anything<'b, 'b>, = note: defining type: two_regions::<'_#1r, T> error: lifetime may not live long enough - --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 + --> $DIR/projection-two-region-trait-bound-closure.rs:87:5 | LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -175,9 +175,12 @@ LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `Cell<&'_#8r ()>`, which makes the generic argument `&'_#8r ()` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:97:29 From 3d2c1e6525b137c880a4684428cd3f2877d56972 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Mon, 3 Oct 2022 13:45:02 +0300 Subject: [PATCH 151/482] use spans in TypeTest rather than mir::Location Spans are independent of the body being borrow-checked, so they don't need remapping when promoting type-tests and they yield more specific error spans inside bodies of closures/inline consts. --- .../src/diagnostics/region_errors.rs | 2 +- .../rustc_borrowck/src/region_infer/mod.rs | 16 ++++----- .../src/type_check/constraint_conversion.rs | 7 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 9 ----- src/test/ui/consts/issue-102117.rs | 4 +-- src/test/ui/consts/issue-102117.stderr | 24 ++++--------- .../generic-associated-types/issue-91139.rs | 1 + .../issue-91139.stderr | 13 ++++++- .../propagate-from-trait-match.rs | 3 +- .../propagate-from-trait-match.stderr | 13 ++----- ...98589-closures-relate-named-regions.stderr | 8 ++--- src/test/ui/nll/issue-98693.rs | 2 +- src/test/ui/nll/issue-98693.stderr | 9 ++--- .../projection-implied-bounds.stderr | 4 +-- .../projection-no-regions-closure.stderr | 8 ++--- .../projection-one-region-closure.stderr | 8 ++--- ...tion-two-region-trait-bound-closure.stderr | 8 ++--- ...ram-closure-approximate-lower-bound.stderr | 4 +-- ...m-closure-outlives-from-return-type.stderr | 4 +-- ...aram-closure-outlives-from-where-clause.rs | 5 ++- ...-closure-outlives-from-where-clause.stderr | 36 +++++++------------ 21 files changed, 76 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 15230718dc0de..196ddbe8d5046 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -181,7 +181,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Try to convert the lower-bound region into something named we can print for the user. let lower_bound_region = self.to_error_region(type_test.lower_bound); - let type_test_span = type_test.locations.span(&self.body); + let type_test_span = type_test.span; if let Some(lower_bound_region) = lower_bound_region { let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 6782fc0665f04..94e9e05e5d640 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -214,8 +214,8 @@ pub struct TypeTest<'tcx> { /// The region `'x` that the type must outlive. pub lower_bound: RegionVid, - /// Where did this constraint arise and why? - pub locations: Locations, + /// The span to blame. + pub span: Span, /// A test which, if met by the region `'x`, proves that this type /// constraint is satisfied. @@ -870,13 +870,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { if deduplicate_errors.insert(( erased_generic_kind, type_test.lower_bound, - type_test.locations, + type_test.span, )) { debug!( "check_type_test: reporting error for erased_generic_kind={:?}, \ lower_bound_region={:?}, \ - type_test.locations={:?}", - erased_generic_kind, type_test.lower_bound, type_test.locations, + type_test.span={:?}", + erased_generic_kind, type_test.lower_bound, type_test.span, ); errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); @@ -919,7 +919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) -> bool { let tcx = infcx.tcx; - let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test; + let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test; let generic_ty = generic_kind.to_ty(tcx); let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { @@ -947,7 +947,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject, outlived_free_region: static_r, - blame_span: locations.span(body), + blame_span: type_test.span, category: ConstraintCategory::Boring, }); @@ -999,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let requirement = ClosureOutlivesRequirement { subject, outlived_free_region: upper_bound, - blame_span: locations.span(body), + blame_span: type_test.span, category: ConstraintCategory::Boring, }; debug!("try_promote_type_test: pushing {:#?}", requirement); diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 88be80c0b558d..ce7f857e27310 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -169,10 +169,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { .type_must_outlive(origin, t1, r2, constraint_category); } - GenericArgKind::Const(_) => { - // Consts cannot outlive one another, so we - // don't need to handle any relations here. - } + GenericArgKind::Const(_) => unreachable!(), } } @@ -202,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { verify_bound: VerifyBound<'tcx>, ) -> TypeTest<'tcx> { let lower_bound = self.to_region_vid(region); - TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound } + TypeTest { generic_kind, lower_bound, span: self.span, verify_bound } } fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3d9e08b4ca7ba..50af229baaaed 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -583,7 +583,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { // modify their locations. let all_facts = &mut None; let mut constraints = Default::default(); - let mut type_tests = Default::default(); let mut liveness_constraints = LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body))); // Don't try to add borrow_region facts for the promoted MIR @@ -594,7 +593,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { &mut this.cx.borrowck_context.constraints.outlives_constraints, &mut constraints, ); - mem::swap(&mut this.cx.borrowck_context.constraints.type_tests, &mut type_tests); mem::swap( &mut this.cx.borrowck_context.constraints.liveness_constraints, &mut liveness_constraints, @@ -615,13 +613,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { swap_constraints(self); let locations = location.to_locations(); - - // Use location of promoted const in collected constraints - for type_test in type_tests.iter() { - let mut type_test = type_test.clone(); - type_test.locations = locations; - self.cx.borrowck_context.constraints.type_tests.push(type_test) - } for constraint in constraints.outlives().iter() { let mut constraint = constraint.clone(); constraint.locations = locations; diff --git a/src/test/ui/consts/issue-102117.rs b/src/test/ui/consts/issue-102117.rs index b77342c4135e1..3ed90aed2350d 100644 --- a/src/test/ui/consts/issue-102117.rs +++ b/src/test/ui/consts/issue-102117.rs @@ -14,11 +14,11 @@ pub struct VTable { impl VTable { pub fn new() -> &'static Self { const { - //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough &VTable { layout: Layout::new::(), type_id: TypeId::of::(), + //~^ ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough drop_in_place: unsafe { transmute::(drop_in_place::) }, diff --git a/src/test/ui/consts/issue-102117.stderr b/src/test/ui/consts/issue-102117.stderr index eb4b329bd8134..f42bcf90fb756 100644 --- a/src/test/ui/consts/issue-102117.stderr +++ b/src/test/ui/consts/issue-102117.stderr @@ -1,14 +1,8 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/issue-102117.rs:16:9 + --> $DIR/issue-102117.rs:19:26 | -LL | / const { -LL | | -LL | | -LL | | &VTable { -... | -LL | | } -LL | | } - | |_________^ ...so that the type `T` will meet its required lifetime bounds +LL | type_id: TypeId::of::(), + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | @@ -16,16 +10,10 @@ LL | pub fn new() -> &'static Self { | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/issue-102117.rs:16:9 + --> $DIR/issue-102117.rs:19:26 | -LL | / const { -LL | | -LL | | -LL | | &VTable { -... | -LL | | } -LL | | } - | |_________^ ...so that the type `T` will meet its required lifetime bounds +LL | type_id: TypeId::of::(), + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs index 5fc6071c93966..e321da53d5668 100644 --- a/src/test/ui/generic-associated-types/issue-91139.rs +++ b/src/test/ui/generic-associated-types/issue-91139.rs @@ -21,6 +21,7 @@ fn foo() { //~| ERROR `T` does not live long enough //~| ERROR `T` does not live long enough //~| ERROR `T` may not live long enough + //~| ERROR `T` may not live long enough // // FIXME: This error is bogus, but it arises because we try to validate // that `<() as Foo>::Type<'a>` is valid, which requires proving diff --git a/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.stderr index 8bbe98fa1e501..5485570cecd76 100644 --- a/src/test/ui/generic-associated-types/issue-91139.stderr +++ b/src/test/ui/generic-associated-types/issue-91139.stderr @@ -22,6 +22,17 @@ error: `T` does not live long enough LL | let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/issue-91139.rs:14:58 + | +LL | let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); + | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn foo() { + | +++++++++ + error: `T` does not live long enough --> $DIR/issue-91139.rs:14:58 | @@ -57,6 +68,6 @@ error: `T` does not live long enough LL | let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); | ^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs index 3bdb543394857..cda781d8e2637 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs @@ -30,8 +30,6 @@ where T: Trait<'a>, { establish_relationships(value, |value| { - //~^ ERROR the parameter type `T` may not live long enough - // This function call requires that // // (a) T: Trait<'a> @@ -43,6 +41,7 @@ where // The latter does not hold. require(value); + //~^ ERROR the parameter type `T` may not live long enough }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 750b08bbe855c..038a5e11f88ce 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -23,17 +23,10 @@ LL | | T: Trait<'a>, = note: defining type: supply::<'_#1r, T> error[E0309]: the parameter type `T` may not live long enough - --> $DIR/propagate-from-trait-match.rs:32:36 + --> $DIR/propagate-from-trait-match.rs:43:9 | -LL | establish_relationships(value, |value| { - | ____________________________________^ -LL | | -LL | | -LL | | // This function call requires that -... | -LL | | require(value); -LL | | }); - | |_____^ ...so that the type `T` will meet its required lifetime bounds +LL | require(value); + | ^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr b/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr index 6def5602e70b3..d8b26f0b0171e 100644 --- a/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr +++ b/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr @@ -35,10 +35,10 @@ LL | || { None::<&'a &'b ()>; }; = help: consider adding the following bound: `'b: 'a` error[E0309]: the parameter type `T` may not live long enough - --> $DIR/issue-98589-closures-relate-named-regions.rs:26:5 + --> $DIR/issue-98589-closures-relate-named-regions.rs:26:10 | LL | || { None::<&'a T>; }; - | ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | @@ -46,10 +46,10 @@ LL | fn test_early_type<'a: 'a, T: 'a>() { | ++++ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/issue-98589-closures-relate-named-regions.rs:32:5 + --> $DIR/issue-98589-closures-relate-named-regions.rs:32:10 | LL | || { None::<&'a T>; }; - | ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/issue-98693.rs b/src/test/ui/nll/issue-98693.rs index 18e6ec6304646..7a325e2e998f3 100644 --- a/src/test/ui/nll/issue-98693.rs +++ b/src/test/ui/nll/issue-98693.rs @@ -13,8 +13,8 @@ where fn test() { || { - //~^ ERROR the parameter type `T` may not live long enough assert_static::(); + //~^ ERROR the parameter type `T` may not live long enough }; } diff --git a/src/test/ui/nll/issue-98693.stderr b/src/test/ui/nll/issue-98693.stderr index 31689620c6414..15ca38aa25dce 100644 --- a/src/test/ui/nll/issue-98693.stderr +++ b/src/test/ui/nll/issue-98693.stderr @@ -1,11 +1,8 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/issue-98693.rs:15:5 + --> $DIR/issue-98693.rs:16:9 | -LL | / || { -LL | | -LL | | assert_static::(); -LL | | }; - | |_____^ ...so that the type `T` will meet its required lifetime bounds +LL | assert_static::(); + | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr index 3b9b2956c5183..d949e29b2b812 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -1,8 +1,8 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/projection-implied-bounds.rs:30:18 + --> $DIR/projection-implied-bounds.rs:30:36 | LL | twice(value, |value_ref, item| invoke2(value_ref, item)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index ee1f7b64bb231..4933b93486831 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -23,10 +23,10 @@ LL | | T: Iterator, = note: defining type: no_region::<'_#1r, T> error[E0309]: the associated type `::Item` may not live long enough - --> $DIR/projection-no-regions-closure.rs:25:23 + --> $DIR/projection-no-regions-closure.rs:25:31 | LL | with_signature(x, |mut y| Box::new(y.next())) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `::Item: 'a`... = note: ...so that the type `::Item` will meet its required lifetime bounds @@ -80,10 +80,10 @@ LL | | T: 'b + Iterator, = note: defining type: wrong_region::<'_#1r, '_#2r, T> error[E0309]: the associated type `::Item` may not live long enough - --> $DIR/projection-no-regions-closure.rs:42:23 + --> $DIR/projection-no-regions-closure.rs:42:31 | LL | with_signature(x, |mut y| Box::new(y.next())) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `::Item: 'a`... = note: ...so that the type `::Item` will meet its required lifetime bounds diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 4e57dfad794e3..dbda04c42c5c7 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -25,10 +25,10 @@ LL | | T: Anything<'b>, = note: defining type: no_relationships_late::<'_#1r, T> error[E0309]: the parameter type `T` may not live long enough - --> $DIR/projection-one-region-closure.rs:45:29 + --> $DIR/projection-one-region-closure.rs:45:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | @@ -75,10 +75,10 @@ LL | | 'a: 'a, = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> error[E0309]: the parameter type `T` may not live long enough - --> $DIR/projection-one-region-closure.rs:56:29 + --> $DIR/projection-one-region-closure.rs:56:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 1260a656c98f2..90f04914286c1 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -24,10 +24,10 @@ LL | | T: Anything<'b, 'c>, = note: defining type: no_relationships_late::<'_#1r, '_#2r, T> error[E0309]: the associated type `>::AssocType` may not live long enough - --> $DIR/projection-two-region-trait-bound-closure.rs:38:29 + --> $DIR/projection-two-region-trait-bound-closure.rs:38:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `>::AssocType: 'a`... = note: ...so that the type `>::AssocType` will meet its required lifetime bounds @@ -58,10 +58,10 @@ LL | | 'a: 'a, = note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T> error[E0309]: the associated type `>::AssocType` may not live long enough - --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 + --> $DIR/projection-two-region-trait-bound-closure.rs:48:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `>::AssocType: 'a`... = note: ...so that the type `>::AssocType` will meet its required lifetime bounds diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index 61c7d2550caad..f316a551cffa6 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -44,10 +44,10 @@ LL | fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) { = note: defining type: generic_fail:: error[E0309]: the parameter type `T` may not live long enough - --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24 + --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:31 | LL | twice(cell, value, |a, b| invoke(a, b)); - | ^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 50d9e3aabe2d4..35979c8bf5171 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -23,10 +23,10 @@ LL | | T: Debug, = note: defining type: no_region::<'_#1r, T> error[E0309]: the parameter type `T` may not live long enough - --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23 + --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:27 | LL | with_signature(x, |y| y) - | ^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs index d7702def32c52..b802876105041 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs @@ -25,13 +25,12 @@ where #[rustc_regions] fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { with_signature(a, b, |x, y| { - //~^ ERROR the parameter type `T` may not live long enough - // // See `correct_region`, which explains the point of this // test. The only difference is that, in the case of this // function, there is no where clause *anywhere*, and hence we // get an error (but reported by the closure creator). require(&x, &y) + //~^ ERROR the parameter type `T` may not live long enough }) } @@ -62,9 +61,9 @@ where T: 'b, { with_signature(a, b, |x, y| { - //~^ ERROR the parameter type `T` may not live long enough // See `correct_region` require(&x, &y) + //~^ ERROR the parameter type `T` may not live long enough }) } diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 14c55e32a3ebe..4c97db58c6c3d 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -22,17 +22,10 @@ LL | fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { = note: defining type: no_region:: error[E0309]: the parameter type `T` may not live long enough - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:32:9 | -LL | with_signature(a, b, |x, y| { - | __________________________^ -LL | | -LL | | // -LL | | // See `correct_region`, which explains the point of this -... | -LL | | require(&x, &y) -LL | | }) - | |_____^ ...so that the type `T` will meet its required lifetime bounds +LL | require(&x, &y) + | ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | @@ -40,7 +33,7 @@ LL | fn no_region<'a, T: 'a>(a: Cell<&'a ()>, b: T) { | ++++ note: external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:42:26 | LL | with_signature(a, b, |x, y| { | ^^^^^^ @@ -54,7 +47,7 @@ LL | with_signature(a, b, |x, y| { = note: where T: '_#2r note: no external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:39:1 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:1 | LL | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T) LL | | where @@ -64,7 +57,7 @@ LL | | T: 'a, = note: defining type: correct_region::<'_#1r, T> note: external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:63:26 | LL | with_signature(a, b, |x, y| { | ^^^^^^ @@ -79,7 +72,7 @@ LL | with_signature(a, b, |x, y| { = note: where T: '_#2r note: no external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:60:1 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:59:1 | LL | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) LL | | where @@ -89,15 +82,10 @@ LL | | T: 'b, = note: defining type: wrong_region::<'_#1r, T> error[E0309]: the parameter type `T` may not live long enough - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:65:9 | -LL | with_signature(a, b, |x, y| { - | __________________________^ -LL | | -LL | | // See `correct_region` -LL | | require(&x, &y) -LL | | }) - | |_____^ ...so that the type `T` will meet its required lifetime bounds +LL | require(&x, &y) + | ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | @@ -105,7 +93,7 @@ LL | T: 'b + 'a, | ++++ note: external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26 | LL | with_signature(a, b, |x, y| { | ^^^^^^ @@ -119,7 +107,7 @@ LL | with_signature(a, b, |x, y| { = note: where T: '_#3r note: no external requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1 + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:71:1 | LL | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) LL | | where From c9280d43fe8beb70e112f385fa619900958a1d88 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 13 Oct 2022 23:27:17 +0800 Subject: [PATCH 152/482] fix #102806, suggest use .. to fill in the rest of the fields of Struct --- .../locales/en-US/parser.ftl | 3 ++ compiler/rustc_parse/src/errors.rs | 9 ++++ compiler/rustc_parse/src/parser/expr.rs | 21 ++++++-- src/test/ui/parser/issue-102806.rs | 22 ++++++++ src/test/ui/parser/issue-102806.stderr | 51 +++++++++++++++++++ 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/parser/issue-102806.rs create mode 100644 src/test/ui/parser/issue-102806.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 13c368d1c5850..455ff34f7247f 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -112,6 +112,9 @@ parser_missing_semicolon_before_array = expected `;`, found `[` parser_invalid_block_macro_segment = cannot use a `block` macro fragment here .label = the `block` fragment is within this context +parser_expect_dotdot_not_dotdotdot = expected `..`, found `...` + .suggestion = use `..` to fill in the rest of the fields + parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition .add_then_block = add a block here .condition_possibly_unfinished = this binary operation is possibly unfinished diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index dc20490284293..b02bd66453373 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -368,6 +368,15 @@ pub(crate) struct MissingSemicolonBeforeArray { pub semicolon: Span, } +#[derive(Diagnostic)] +#[diag(parser_expect_dotdot_not_dotdotdot)] +pub(crate) struct MissingDotDot { + #[primary_span] + pub token_span: Span, + #[suggestion_verbose(applicability = "maybe-incorrect", code = "..")] + pub sugg_span: Span, +} + #[derive(Diagnostic)] #[diag(parser_invalid_block_macro_segment)] pub(crate) struct InvalidBlockMacroSegment { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0eb633f641687..7de025e7860dd 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -20,9 +20,9 @@ use crate::errors::{ InvalidNumLiteralSuffix, LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, - MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, - NotAsNegationOperator, NotAsNegationOperatorSub, OctalFloatLiteralNotSupported, - OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields, + MissingDotDot, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, + NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub, + OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses, @@ -2897,6 +2897,21 @@ impl<'a> Parser<'a> { } self.recover_struct_comma_after_dotdot(exp_span); break; + } else if self.token == token::DotDotDot { + // suggest `..v` instead of `...v` + let snapshot = self.create_snapshot_for_diagnostic(); + let span = self.token.span; + self.bump(); + match self.parse_expr() { + Ok(_p) => { + self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span }); + break; + } + Err(inner_err) => { + inner_err.cancel(); + self.restore_snapshot(snapshot); + } + } } let recovery_field = self.find_struct_error_after_field_looking_code(); diff --git a/src/test/ui/parser/issue-102806.rs b/src/test/ui/parser/issue-102806.rs new file mode 100644 index 0000000000000..f5513c87a92e8 --- /dev/null +++ b/src/test/ui/parser/issue-102806.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] + +struct V3 { + x: f32, + y: f32, + z: f32, +} + +fn pz(v: V3) { + let _ = V3 { z: 0.0, ...v}; + //~^ ERROR expected `..` + //~| ERROR missing fields `x` and `y` in initializer of `V3` + let _ = V3 { z: 0.0, ... }; + //~^ expected identifier + //~| ERROR missing fields `x` and `y` in initializer of `V3` + + let _ = V3 { z: 0.0, ...Default::default() }; + //~^ ERROR expected `..` + //~| ERROR missing fields `x` and `y` in initializer of `V3` +} + +fn main() {} diff --git a/src/test/ui/parser/issue-102806.stderr b/src/test/ui/parser/issue-102806.stderr new file mode 100644 index 0000000000000..53a43b5396141 --- /dev/null +++ b/src/test/ui/parser/issue-102806.stderr @@ -0,0 +1,51 @@ +error: expected `..`, found `...` + --> $DIR/issue-102806.rs:10:26 + | +LL | let _ = V3 { z: 0.0, ...v}; + | ^^^ + | +help: use `..` to fill in the rest of the fields + | +LL | let _ = V3 { z: 0.0, ..v}; + | ~~ + +error: expected identifier, found `...` + --> $DIR/issue-102806.rs:13:26 + | +LL | let _ = V3 { z: 0.0, ... }; + | -- ^^^ expected identifier + | | + | while parsing this struct + +error: expected `..`, found `...` + --> $DIR/issue-102806.rs:17:26 + | +LL | let _ = V3 { z: 0.0, ...Default::default() }; + | ^^^ + | +help: use `..` to fill in the rest of the fields + | +LL | let _ = V3 { z: 0.0, ..Default::default() }; + | ~~ + +error[E0063]: missing fields `x` and `y` in initializer of `V3` + --> $DIR/issue-102806.rs:10:13 + | +LL | let _ = V3 { z: 0.0, ...v}; + | ^^ missing `x` and `y` + +error[E0063]: missing fields `x` and `y` in initializer of `V3` + --> $DIR/issue-102806.rs:13:13 + | +LL | let _ = V3 { z: 0.0, ... }; + | ^^ missing `x` and `y` + +error[E0063]: missing fields `x` and `y` in initializer of `V3` + --> $DIR/issue-102806.rs:17:13 + | +LL | let _ = V3 { z: 0.0, ...Default::default() }; + | ^^ missing `x` and `y` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0063`. From 5d743428f0969fb958598e2581f761c7913fea3c Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 14 Oct 2022 06:52:23 +0800 Subject: [PATCH 153/482] fake a base to suppress later extra error message --- compiler/rustc_parse/src/errors.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 29 ++++++++++----------- src/test/ui/parser/issue-102806.rs | 11 +++++--- src/test/ui/parser/issue-102806.stderr | 34 ++++++++++--------------- 4 files changed, 35 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index b02bd66453373..0924c8537159c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -373,7 +373,7 @@ pub(crate) struct MissingSemicolonBeforeArray { pub(crate) struct MissingDotDot { #[primary_span] pub token_span: Span, - #[suggestion_verbose(applicability = "maybe-incorrect", code = "..")] + #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")] pub sugg_span: Span, } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7de025e7860dd..338e6a8e28955 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2880,7 +2880,7 @@ impl<'a> Parser<'a> { }; while self.token != token::CloseDelim(close_delim) { - if self.eat(&token::DotDot) { + if self.eat(&token::DotDot) || self.recover_struct_fileds_dots(close_delim) { let exp_span = self.prev_token.span; // We permit `.. }` on the left-hand side of a destructuring assignment. if self.check(&token::CloseDelim(close_delim)) { @@ -2897,21 +2897,6 @@ impl<'a> Parser<'a> { } self.recover_struct_comma_after_dotdot(exp_span); break; - } else if self.token == token::DotDotDot { - // suggest `..v` instead of `...v` - let snapshot = self.create_snapshot_for_diagnostic(); - let span = self.token.span; - self.bump(); - match self.parse_expr() { - Ok(_p) => { - self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span }); - break; - } - Err(inner_err) => { - inner_err.cancel(); - self.restore_snapshot(snapshot); - } - } } let recovery_field = self.find_struct_error_after_field_looking_code(); @@ -3042,6 +3027,18 @@ impl<'a> Parser<'a> { self.recover_stmt(); } + fn recover_struct_fileds_dots(&mut self, close_delim: Delimiter) -> bool { + if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim)) + && self.eat(&token::DotDotDot) + { + // recover from typo of `...`, suggest `..` + let span = self.prev_token.span; + self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span }); + return true; + } + false + } + /// Parses `ident (COLON expr)?`. fn parse_expr_field(&mut self) -> PResult<'a, ExprField> { let attrs = self.parse_outer_attributes()?; diff --git a/src/test/ui/parser/issue-102806.rs b/src/test/ui/parser/issue-102806.rs index f5513c87a92e8..ba297bdc9677b 100644 --- a/src/test/ui/parser/issue-102806.rs +++ b/src/test/ui/parser/issue-102806.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] +#[derive(Default)] struct V3 { x: f32, y: f32, @@ -9,14 +10,16 @@ struct V3 { fn pz(v: V3) { let _ = V3 { z: 0.0, ...v}; //~^ ERROR expected `..` - //~| ERROR missing fields `x` and `y` in initializer of `V3` - let _ = V3 { z: 0.0, ... }; - //~^ expected identifier - //~| ERROR missing fields `x` and `y` in initializer of `V3` let _ = V3 { z: 0.0, ...Default::default() }; //~^ ERROR expected `..` + + let _ = V3 { z: 0.0, ... }; + //~^ expected identifier //~| ERROR missing fields `x` and `y` in initializer of `V3` + + let V3 { z: val, ... } = v; + //~^ ERROR expected field pattern } fn main() {} diff --git a/src/test/ui/parser/issue-102806.stderr b/src/test/ui/parser/issue-102806.stderr index 53a43b5396141..6872b8bc0afec 100644 --- a/src/test/ui/parser/issue-102806.stderr +++ b/src/test/ui/parser/issue-102806.stderr @@ -1,5 +1,5 @@ error: expected `..`, found `...` - --> $DIR/issue-102806.rs:10:26 + --> $DIR/issue-102806.rs:11:26 | LL | let _ = V3 { z: 0.0, ...v}; | ^^^ @@ -9,16 +9,8 @@ help: use `..` to fill in the rest of the fields LL | let _ = V3 { z: 0.0, ..v}; | ~~ -error: expected identifier, found `...` - --> $DIR/issue-102806.rs:13:26 - | -LL | let _ = V3 { z: 0.0, ... }; - | -- ^^^ expected identifier - | | - | while parsing this struct - error: expected `..`, found `...` - --> $DIR/issue-102806.rs:17:26 + --> $DIR/issue-102806.rs:14:26 | LL | let _ = V3 { z: 0.0, ...Default::default() }; | ^^^ @@ -28,24 +20,26 @@ help: use `..` to fill in the rest of the fields LL | let _ = V3 { z: 0.0, ..Default::default() }; | ~~ -error[E0063]: missing fields `x` and `y` in initializer of `V3` - --> $DIR/issue-102806.rs:10:13 +error: expected identifier, found `...` + --> $DIR/issue-102806.rs:17:26 | -LL | let _ = V3 { z: 0.0, ...v}; - | ^^ missing `x` and `y` +LL | let _ = V3 { z: 0.0, ... }; + | -- ^^^ expected identifier + | | + | while parsing this struct -error[E0063]: missing fields `x` and `y` in initializer of `V3` - --> $DIR/issue-102806.rs:13:13 +error: expected field pattern, found `...` + --> $DIR/issue-102806.rs:21:22 | -LL | let _ = V3 { z: 0.0, ... }; - | ^^ missing `x` and `y` +LL | let V3 { z: val, ... } = v; + | ^^^ help: to omit remaining fields, use one fewer `.`: `..` error[E0063]: missing fields `x` and `y` in initializer of `V3` --> $DIR/issue-102806.rs:17:13 | -LL | let _ = V3 { z: 0.0, ...Default::default() }; +LL | let _ = V3 { z: 0.0, ... }; | ^^ missing `x` and `y` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0063`. From 21897e91fa3741ce109b824c2e914eaef4f3e16a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 5 Nov 2022 19:33:12 -0700 Subject: [PATCH 154/482] Fix typo --- compiler/rustc_parse/src/parser/expr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 338e6a8e28955..4a1162b959983 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2880,7 +2880,7 @@ impl<'a> Parser<'a> { }; while self.token != token::CloseDelim(close_delim) { - if self.eat(&token::DotDot) || self.recover_struct_fileds_dots(close_delim) { + if self.eat(&token::DotDot) || self.recover_struct_field_dots(close_delim) { let exp_span = self.prev_token.span; // We permit `.. }` on the left-hand side of a destructuring assignment. if self.check(&token::CloseDelim(close_delim)) { @@ -3027,7 +3027,7 @@ impl<'a> Parser<'a> { self.recover_stmt(); } - fn recover_struct_fileds_dots(&mut self, close_delim: Delimiter) -> bool { + fn recover_struct_field_dots(&mut self, close_delim: Delimiter) -> bool { if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim)) && self.eat(&token::DotDotDot) { From 3b2b70d9b597c32b996640cb08429c89ac858cc5 Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Tue, 1 Nov 2022 21:50:28 +0100 Subject: [PATCH 155/482] Fixes #103816 make --json work --- src/bootstrap/builder.rs | 1 + src/bootstrap/doc.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 406bae02d84da..81b334d954d75 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -690,6 +690,7 @@ impl<'a> Builder<'a> { doc::UnstableBookGen, doc::TheBook, doc::Standalone, + doc::JsonStd, doc::Std, doc::Rustc, doc::Rustdoc, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 1357718b84e35..de642c121b898 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -515,7 +515,7 @@ impl Step for JsonStd { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target }); + run.builder.ensure(JsonStd { stage: run.builder.top_stage, target: run.target }); } /// Build JSON documentation for the standard library crates. From 4f5e70edc9e67c6d2eb23918f4af5f95e5fb0f63 Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Tue, 1 Nov 2022 22:18:19 +0100 Subject: [PATCH 156/482] fix json running all the time --- src/bootstrap/doc.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index de642c121b898..19b642209a6a1 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -510,8 +510,13 @@ impl Step for JsonStd { const DEFAULT: bool = false; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let default = run.builder.config.docs && run.builder.config.cmd.json(); - run.all_krates("test").path("library").default_condition(default) + if run.builder.config.cmd.json() { + let default = run.builder.config.docs && run.builder.config.cmd.json(); + run.all_krates("test").path("library").default_condition(default) + } else { + // Without this JsonStd would take priority on Std and prevent it from running. + run.never() + } } fn make_run(run: RunConfig<'_>) { From 46884598c4b63994e12a0e830b1e14a0bc2a872e Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Wed, 2 Nov 2022 11:23:42 +0100 Subject: [PATCH 157/482] merge JsonStd and Std steps --- src/bootstrap/builder.rs | 1 - src/bootstrap/dist.rs | 7 +++- src/bootstrap/doc.rs | 77 ++++++++++++---------------------------- src/bootstrap/test.rs | 7 +++- 4 files changed, 34 insertions(+), 58 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 81b334d954d75..406bae02d84da 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -690,7 +690,6 @@ impl<'a> Builder<'a> { doc::UnstableBookGen, doc::TheBook, doc::Standalone, - doc::JsonStd, doc::Std, doc::Rustc, doc::Rustdoc, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 805633c926c3a..110a3ee4918da 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -19,6 +19,7 @@ use crate::cache::{Interned, INTERNER}; use crate::channel; use crate::compile; use crate::config::TargetSelection; +use crate::doc::DocumentationFormat; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, output, t, timeit}; @@ -97,7 +98,11 @@ impl Step for JsonDocs { /// Builds the `rust-docs-json` installer component. fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - builder.ensure(crate::doc::JsonStd { stage: builder.top_stage, target: host }); + builder.ensure(crate::doc::Std { + stage: builder.top_stage, + target: host, + format: DocumentationFormat::JSON, + }); let dest = "share/doc/rust/json"; diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 19b642209a6a1..f334d46750949 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -420,6 +420,7 @@ impl Step for SharedAssets { pub struct Std { pub stage: u32, pub target: TargetSelection, + pub format: DocumentationFormat, } impl Step for Std { @@ -432,7 +433,15 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target }); + run.builder.ensure(Std { + stage: run.builder.top_stage, + target: run.target, + format: if run.builder.config.cmd.json() { + DocumentationFormat::JSON + } else { + DocumentationFormat::HTML + }, + }); } /// Compile all standard library documentation. @@ -448,13 +457,16 @@ impl Step for Std { builder.ensure(SharedAssets { target: self.target }); let index_page = builder.src.join("src/doc/index.md").into_os_string(); - let mut extra_args = vec![ - OsStr::new("--markdown-css"), - OsStr::new("rust.css"), - OsStr::new("--markdown-no-toc"), - OsStr::new("--index-page"), - &index_page, - ]; + let mut extra_args = match self.format { + DocumentationFormat::HTML => vec![ + OsStr::new("--markdown-css"), + OsStr::new("rust.css"), + OsStr::new("--markdown-no-toc"), + OsStr::new("--index-page"), + &index_page, + ], + DocumentationFormat::JSON => vec![OsStr::new("--output-format"), OsStr::new("json")], + }; if !builder.config.docs_minification { extra_args.push(OsStr::new("--disable-minification")); @@ -478,15 +490,7 @@ impl Step for Std { }) .collect::>(); - doc_std( - builder, - DocumentationFormat::HTML, - stage, - target, - &out, - &extra_args, - &requested_crates, - ); + doc_std(builder, self.format, stage, target, &out, &extra_args, &requested_crates); // Look for library/std, library/core etc in the `x.py doc` arguments and // open the corresponding rendered docs. @@ -499,43 +503,6 @@ impl Step for Std { } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct JsonStd { - pub stage: u32, - pub target: TargetSelection, -} - -impl Step for JsonStd { - type Output = (); - const DEFAULT: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - if run.builder.config.cmd.json() { - let default = run.builder.config.docs && run.builder.config.cmd.json(); - run.all_krates("test").path("library").default_condition(default) - } else { - // Without this JsonStd would take priority on Std and prevent it from running. - run.never() - } - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(JsonStd { stage: run.builder.top_stage, target: run.target }); - } - - /// Build JSON documentation for the standard library crates. - /// - /// This is largely just a wrapper around `cargo doc`. - fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let target = self.target; - let out = builder.json_doc_out(target); - t!(fs::create_dir_all(&out)); - let extra_args = [OsStr::new("--output-format"), OsStr::new("json")]; - doc_std(builder, DocumentationFormat::JSON, stage, target, &out, &extra_args, &[]) - } -} - /// Name of the crates that are visible to consumers of the standard library. /// Documentation for internal crates is handled by the rustc step, so internal crates will show /// up there. @@ -548,7 +515,7 @@ impl Step for JsonStd { const STD_PUBLIC_CRATES: [&str; 5] = ["core", "alloc", "std", "proc_macro", "test"]; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -enum DocumentationFormat { +pub enum DocumentationFormat { HTML, JSON, } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 935ce5e7f84b3..931d9a67944df 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -16,6 +16,7 @@ use crate::cache::Interned; use crate::compile; use crate::config::TargetSelection; use crate::dist; +use crate::doc::DocumentationFormat; use crate::flags::Subcommand; use crate::native; use crate::tool::{self, SourceType, Tool}; @@ -822,7 +823,11 @@ impl Step for RustdocJSStd { command.arg("--test-file").arg(path); } } - builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage }); + builder.ensure(crate::doc::Std { + target: self.target, + stage: builder.top_stage, + format: DocumentationFormat::HTML, + }); builder.run(&mut command); } else { builder.info("No nodejs found, skipping \"src/test/rustdoc-js-std\" tests"); From f80ed31cecfcd2da69ff3e5363ff28ae0eedf441 Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Wed, 2 Nov 2022 11:28:31 +0100 Subject: [PATCH 158/482] prevent open with json --- src/bootstrap/doc.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index f334d46750949..6b407e8aa76a5 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -492,6 +492,11 @@ impl Step for Std { doc_std(builder, self.format, stage, target, &out, &extra_args, &requested_crates); + // Don't open if the format is json + if let DocumentationFormat::JSON = self.format { + return; + } + // Look for library/std, library/core etc in the `x.py doc` arguments and // open the corresponding rendered docs. for requested_crate in requested_crates { From 99e0dec0a0e9a658c449d82e895201440a78f063 Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Sat, 5 Nov 2022 18:30:01 +0100 Subject: [PATCH 159/482] fix out dir being wrong in json --- src/bootstrap/doc.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 6b407e8aa76a5..280e232ca2dd0 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -451,7 +451,11 @@ impl Step for Std { fn run(self, builder: &Builder<'_>) { let stage = self.stage; let target = self.target; - let out = builder.doc_out(target); + let out = match self.format { + DocumentationFormat::HTML => builder.doc_out(target), + DocumentationFormat::JSON => builder.json_doc_out(target), + }; + t!(fs::create_dir_all(&out)); builder.ensure(SharedAssets { target: self.target }); From ef3df420e1f4515180e22ddf3e388405f12e7e30 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 4 Nov 2022 15:13:13 -0700 Subject: [PATCH 160/482] rustdoc: clean up `.logo-container` layout CSS This commit should result in no appearance changes. To make the logo container exactly the desired height, you want to get rid of the part of the box used for typographic descenders (you know, the part of g, y, and j that descends below the baseline). After all, it contains no text, but the space is still left open in the layout by default, because `` is `display:inline`. The CSS used to employ three different tricks to accomplish this: * By making `.sidebar .logo-container` a flex container, the image becomes a flex item and is [blockified], without synthesizing any inline boxes. No inline boxes means no descenders. * By giving `.mobile-topbar .logo-container` a max-height exactly the same as the height of the image plus the padding, the descender area gets cut off. * By setting `.sub-logo-container { line-height: 0 }`, we ensure that the only box that contributes to the height of the line box is the image itself, and not any zero-content text boxes that neighbor it. See the [logical height algorithm]. This commit gets rid of the first two hacks, leaving only the third, since it requires only one line of code to accomplish and doesn't require setting the value based on math. [blockified]: https://drafts.csswg.org/css-flexbox-1/#flex-items [logical height algorithm]: https://www.w3.org/TR/css-inline-3/#inline-height --- src/librustdoc/html/static/css/rustdoc.css | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9ee926e1ab0ae..c4d50ff6cbc96 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -367,7 +367,8 @@ img { overflow: visible; } -.sub-logo-container { +.sub-logo-container, .logo-container { + /* zero text boxes so that computed line height = image height exactly */ line-height: 0; } @@ -465,10 +466,9 @@ img { } .sidebar .logo-container { - display: flex; margin-top: 10px; margin-bottom: 10px; - justify-content: center; + text-align: center; } .version { @@ -1755,10 +1755,6 @@ in storage.js white-space: nowrap; } - .mobile-topbar .logo-container { - max-height: 45px; - } - .mobile-topbar .logo-container > img { max-width: 35px; max-height: 35px; From addcffaccab6012aaa6c947250067b0a52c6a50b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 5 Nov 2022 10:14:31 -0700 Subject: [PATCH 161/482] rustdoc: add test case for huge logo --- src/test/rustdoc-gui/huge-logo.goml | 21 +++++++++++++++++++ src/test/rustdoc-gui/search-filter.goml | 2 ++ src/test/rustdoc-gui/sidebar-source-code.goml | 2 +- src/test/rustdoc-gui/source-code-page.goml | 2 +- src/test/rustdoc-gui/src/huge_logo/Cargo.lock | 7 +++++++ src/test/rustdoc-gui/src/huge_logo/Cargo.toml | 8 +++++++ src/test/rustdoc-gui/src/huge_logo/src/lib.rs | 17 +++++++++++++++ 7 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc-gui/huge-logo.goml create mode 100644 src/test/rustdoc-gui/src/huge_logo/Cargo.lock create mode 100644 src/test/rustdoc-gui/src/huge_logo/Cargo.toml create mode 100644 src/test/rustdoc-gui/src/huge_logo/src/lib.rs diff --git a/src/test/rustdoc-gui/huge-logo.goml b/src/test/rustdoc-gui/huge-logo.goml new file mode 100644 index 0000000000000..01f06771c15a5 --- /dev/null +++ b/src/test/rustdoc-gui/huge-logo.goml @@ -0,0 +1,21 @@ +// huge_logo crate has a custom 712x860 logo +// test to ensure the maximum size in the layout works correctly +goto: "file://" + |DOC_PATH| + "/huge_logo/index.html" + +size: (1280, 1024) +// offsetWidth = width of sidebar +assert-property: (".sidebar .logo-container", {"offsetWidth": "200", "offsetHeight": 100}) +assert-property: (".sidebar .logo-container img", {"offsetWidth": "100", "offsetHeight": 100}) + +size: (400, 600) +// offset = size + margin +assert-property: (".mobile-topbar .logo-container", {"offsetWidth": "55", "offsetHeight": 45}) +assert-property: (".mobile-topbar .logo-container img", {"offsetWidth": "35", "offsetHeight": 35}) + +goto: "file://" + |DOC_PATH| + "/src/huge_logo/lib.rs.html" + +size: (1280, 1024) +assert-property: (".sub-logo-container", {"offsetWidth": "60", "offsetHeight": 60}) + +size: (400, 600) +assert-property: (".sub-logo-container", {"offsetWidth": "35", "offsetHeight": 35}) diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml index 27db816e68517..e0228694eec5c 100644 --- a/src/test/rustdoc-gui/search-filter.goml +++ b/src/test/rustdoc-gui/search-filter.goml @@ -14,6 +14,7 @@ click: "#crate-search" // We select "lib2" option then press enter to change the filter. press-key: "ArrowDown" press-key: "ArrowDown" +press-key: "ArrowDown" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#titles" @@ -37,6 +38,7 @@ assert-property: ("#crate-search", {"value": "lib2"}) click: "#crate-search" press-key: "ArrowUp" press-key: "ArrowUp" +press-key: "ArrowUp" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#titles" diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 9ba6636877295..e9a987d52bbdb 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -28,7 +28,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" // Only "another_folder" should be "open" in "lib2". assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 5) +assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 6) // We now switch to mobile mode. size: (600, 600) diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index a2dac2aa681d5..3c4db978d5fb2 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -78,7 +78,7 @@ assert: ".source-sidebar-expanded" // We check that the first entry of the sidebar is collapsed assert-property: ("#source-sidebar details:first-of-type", {"open": "false"}) -assert-text: ("#source-sidebar details:first-of-type > summary", "implementors") +assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo") // We now click on it. click: "#source-sidebar details:first-of-type > summary" assert-property: ("#source-sidebar details:first-of-type", {"open": "true"}) diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.lock b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock new file mode 100644 index 0000000000000..142805750642d --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "huge_logo" +version = "0.1.0" diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.toml b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml new file mode 100644 index 0000000000000..3f10d09c80adf --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "huge_logo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/test/rustdoc-gui/src/huge_logo/src/lib.rs b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs new file mode 100644 index 0000000000000..ec137fb9a88f7 --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs @@ -0,0 +1,17 @@ +// ignore-tidy-linelength +#![doc(html_logo_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsgAAANcCAQAAADoIpEcAAAAAmJLR0QA/4ePzL8AAHSISURBVHja7Z15vFbT/sefzNflXtzr+qHOXvs5p051KtVJIg1IhqRoQlHKVKbKUBkaRQiRpEhKkqIQkURyJJUkQxNKs4bTPJ7h8/uj5Ax772fvZ6+999r7+bzXP14vPXufs9b3+znr+a7v+n5jMUIIIYQQ95zxTz1Tr6e10Dpp3bX+4nkxRrwnZonvxW/iN/Gb2CpyRa7YIyAgIHaLXJErcsVqsUxfoM0QU7Sx+ouij9ZFuyZ+oZ6ZeTLnkxBCbJJ1XLy8uEx01p4Wb4vZYrnYfVhqZY1csVC8qz+j3y0u1zXONyGEFCPt1PiF4nZtqJgpVol8yQJsObRdYp4YrT+gXZTxL64DISRlySirXSsGielirZ8SbDoKxBJtrH63qB47imtDCEkJxAnaRdrD4j2xXgkZNg5qvCe6UpgJIdHlmLRs0UObIfYpK8QlwxmbxUT9pvi/uXSEkMig6frdYnp4hLjE2C+m67ee/R+uIyEkzBwVv1AMEj+FVIiLj4PiI/0mHvwRQkJIWpboK36LhBQXHfvExHijWBmuLyEkFIiK+sAISnHR8YvolnYqV5oQojAZx+uttBmiMNJi/Hf+8ghRkWtOCFFyXyyeF7mpIMXFMpenaBdw7QkhChG/UEz0936dSkPPEQ1pA4SQwMk+Vr9RfJ+qUlxkTIufS2sghAQpxjdpKyjGh0ehmKjptApCiP8cpbcSyynDJcYB8Tzv9RFCfEW7Riyj/JqM9XprWgghxB8xriG+oOwmGJ/HK9BSCCGeIv5PvCYKKLg2xh6tO2vFEUK8oox+k9hCqXUwvk7PoNkQQqSjZ4ovKbGOxw5xM22HECKTo7WHQls6M/gxPuskmhAhRM7eWOPe2OVYGq9KOyKEuEa0Fzsoqa7Hbq0tbYkQ4oKsk8QEiqm08QSzLgghSRKvoP1IGZU6PmK/EUJIEmgtxE5KqPSxqNxZtC1CiBPK6I+lRpH5AMbv8fI0MEKITTKO18dROD0cW0QdWhkhxAYV/qvnUDS9vi6i16OlEUISIARLavrTj4+STAixJF5BrKZY+lZ86CJaHCHETI6rig0USj93ydr5tDpCiAFaTVZy833kpleh5RFCSqBnio0UyADGOnbhI4QUD1aUZ7AisLE843RaICHkMELwKC/IoedkHE8rJITEYrGyp4mlFMWAx4RYGVoiISlPxvGsdaxExsXDtEVCUp0y2liKoRKjUDSnORKS0oi+lEJ1UuCYb0FICqM3FQUUQpVKc551Iq2SkJQkXkFspwgqNkbQLglJQbJOYjcQJVPgWtM2CUm96PEYip+akeR4Gq2TkNSS4zaUPmXHTLZCJSSFyCgrtlL4FA5b3EUbJSRVOErMpugpXpaTCXCEpEi4ohslT/nxOa9SE5ICpMXFbgpeCHbJnWirhESdMuJTil0oxtYK/6W5EhJp9FsodaHZI79CeyUkyuGKU8UmCl1oRgE77hES5f3xMMpcqPbI85mRTEhESa+i5VHkQpaRfCPtlpBIwkL0IRyry/6DlktI5IhfRXljJxFCiAocLX6iuIVybE87leZLSKTQOlLaQjv60H4JiRBZx4k/KGyhHdvi/6YNExIZ9Fspa6EevWnDhEQnfrycohbuOLI4hWZMSCQQ7Slpoc9HfoR2TEgUKCN+oaCFv9RQxr9oyoSEHq0J5SwS+cgP0ZYJCX/AYibFLBJjffaxtGZCQk28qiikmEVktKE9ExLu/fFrFLLIBC2+oj0TEub98b/FHgpZdEZaNm2akNCi300RYw8RQogSaD9SxCI19p79H1o1IeGU4wsoYZHbI99HuyYklIiXKWCRG7+xqRMhISTrOLGFAhbB0ZC2TUj4AhYtKF482COEqBGwmELximZ1ZHECrZuQUJF5sthH8Ypo5beWtG9CwhWwuIHCFdkxhfZNSKjQ36FwRXYcYDYyISHirBPFbgpXhMfttHFCwrM/vpqiFekxmzZOSHgEeRhFK9KjsOzZtHJCQoL4laLFoAUhRAE0nYIV+dS3D2nnhIRjf9yZghX5sT/rJFo6IWEQZN7RS4XRjJZOiPocI7ZTrlIgaPEqTZ0Q5dHrUaxSYvzJQpyEKI82gGKVIuM8WjshqkeQZ1OqUiRo8RitnRClyT6WfaZTZsylvROidsCiJoUqZUrV52X8ixZPiMoBC+Ygp5IkN6HFE6KyIL9OmUqhKPJgWjwhKgvyUspUCo3vaPGEqCvHp4gCylQKjYK0U2n1hKgqyJdRpHiBmhCihiD3pkSl2BhCqydEVUGeTIlKsbGIVk+IqoK8jBKValHkzJNp94QoSMbxWh4lKuVGA1o+IQqin0N5SsFc5Ado+YQoiHYD5SkFx0RaPiEq7pAfozyl4FhFyydEQdi6KUWDFmfQ9glRT5CZY5GagtyUtk+IanJ8gsinOKVkzbf+tH5CFCMti9KUouNjWj8hiqFdSWlK0bGW1k+IaiELlqZP2XH2f2j/hKglyIMoTCl7rFef9k+IWoL8FoUpZY/1utD+CVFLkOdQmFJ2vET7J0QtQV5HYUrZHfJXtH9CFCLrODZvSuGxPVaGPkCIMpRLpyyl8sgoSx8gRJ2ARQOKUkoHLa6gDxCiDHprilJKj3voA4Qog3YnRSlhti7qoAXaojO6oAs6oA0aoEJUfrvn6QOEqBOy6EvBNRuX4FG8g+U4ACPWYjoGowXSw/3H5kP6ACHqCPJLFF4jKR6O32GPXLyD66CH9XddSh8gRJ2QxSTKb/HwRGfMRSGcshL9UCmMv/GB2NH0AkJU2SHPogj/PW7FL0ieLXgcmeH7rQW9gBBVBPlnyvCh0RBfwj3r0T1kv3e8Eb2AEFVCFpspxQIZeAEHIYvPUDtMv/0d9AJC1OAotm8SaIBFkEsu7grP1ZCn6QaEKEHmyZTjztgNLxgXllzlifQDQtQIWJwpOR6JZngaH2MZcgEAediM7zEJPXCBmvFTDE0io8Iui1AnDII8h35AiBLEK8hz7Dp4ERtNxakQC/GAYjkIFTAN3rIBjdUPWayhHxCixg65phynzsYY5NkQqM3ojQxFhKgyvoL37EAb1SU5P3YMPYEQBZBT663L4QCFPVbheiXkeAH8Ya/ykswSnISosUNu4l7YPnAsUQUYHnAFiPKYBf/Yi9ZqBy3OpycQosIO+Tp3rlwXS5IUqfmoFeBR3nT4y3ZcovJ18Vb0BEIUQL/FjSNfjPWuDryuDEiAhsF/ViNb3R1yd3oCISrskLsm78aNsMX1gVfzAOTnLg8T3ayYq26hzmfpCYSoIMg9k3Xi+tggQaR2oYXP4lPfo2sgdnheVUEeT08gRIWQxaPJuXAVLJckUrtwha81KxYhOAqUyC8xiCF/Rk8gRAG0/sk4cDpmS7084d99tucRLGtRWUVJXkxPIESFkMUTyTjwc5Jl6nufqj5cZNKMyU9GqyjIG+kJhKgQsnjGuftea+tOnjPG+NIL5BsET0EgB5kJ7+odRV8gJPiQxQvOr1Ss8ESobvZcdu6BGixUsP9exun0BUKCD1kMd+q6T3kkUxtxjsd381ZBFdSrlZxWmb5ASPCCPMppESHvksbe8FRy+kAdVqO8apLckL5ASPAhi7HOHHeMp9HVZp4JTkVshkr0VC3xrTV9gZDgBfkNJ257vsS+c0bM8UxwekMt/lDt1l5n+gIhIdshj/RcqLypipaOP6Aa96lVzeIh+gIhwceQxzi5nbfLc5n62qPqFerxi1o75CfpC4QEL8iv23faHr4IlRd75HlQEaXK1o+gLxASvCCPtu+0/lyryJEuNo2hJh+rJMhv0xcICV6QX7N/oFfgk1A1kSw2YxQV5LwAS/SXGp/SFwgJXpBt5yE/6ZtQyb1GneGo35+/DFBHkOfRFwgJHP1Vuy671DeZ2olKEqXmZkk50ovxKcbhNXyKn6WVKFLoYG85fYGQwNFesdusyU+6SpSaKa5/msXojprFnlkV3ZAj5TdtpIogb6IvEBJ8yOIlFS9WzJGYgbzD1U+yCreYlgJqj19d/6ZPqSLIB+gLhAQvyEPsOezHvgpyIRpIEprWrn6Oj1AtQcGiSa4rQasStMg+lt5ASNAhi6fs7TO3+Xzc1T/w/tIF6G3zsLPQ1Z8eVXpRx/9NbyAkYPTH7DhrU9/zD76UJDOLk3x/PrrZfsdjrn7TOxUR5HJn0RsICTpk0duOsw5Kaoe5DhuSzkfYLyXTolKSvU0KHR4ruqnxMU6VHXJ5egMhQQtyTzvOOs2hFH+Ctsg65OZogTFJyXJHCSLTJkmRHOG4OdQXSQvyClWiyNXpDYQEHUPubsdZlzsQmDW4ttTn6ybRpVrG9ZBBSUlkThKlMc9LOspecPhPV+A9Q+rSGwgJOoZ8l527bva/+P9o0ogpjucdCtWvEkTmvSQEcg8uSOpdXZPeI7dSo0R9Y3oDIUEL8i2JXbWRAxGtafGcAQ53jpVdi8wvScjjoKTftihJQe6rRkXka+kNhAQdsmib2FU72xSWfWic4EnPOBKqa1xfCtnvWBx/ddHt7qYkBfkNNXbI7egNhAQtyNckdtXBNoWlt43Dr88cCNVDLiXmwiTEsZurN85XpOBoUjvkjvQGQoIOWTSWVb5yma2jsHOwybedYyvH0rgeGa7eeG9SgryaXfUIIbFYLBa/MLGrfmBLVm636fjdbQvVApcSc7djaezj8o2Z2J7UJRQlGp52pTcQEnTIokZiV51lqwiPbjtnd4FNodruUmKc3qDbKyEBLbli+EoUqu9BbyAk6JBFZmJX/cGGpAz25PDL3W29oQ5l8T0JstYiKUG+XAVB7k1vICRgMsomdtWVNiSlricVJuq5kpjXHcpiBynlPpPpT9JWhSyLgfQGQgKm7GmJXTXXxoGeN4df17qSmMmORDFXUiT3/SQE+Q4VBPkZegMhAZN1XGJXTXwp+BXHh187fBAqZxU4PpQkbN2TEORuKgjyi/QGQgJH7E3kqps9KAQ03pZQPepKYj51JIoPSxK2ZJpdPaRCDHkEfYGQ4AX5z0SuusGDLIEbbAnV864k5jNHonixrDKW2O1YkJ9Q4WLIK/QFQoIX5OWJXHVtAjnZkIT7Z2CnB2Uwi4+ZjiLI8qTtW8eCPESFHfIo+gIhgaPNd5tlMcuzCO/rvgnyfInSNs6xIA9WQZBH0xcICX6HPDORq65IICdvJiUAfWwI1Zu+HepNkChtzzgW5CdVEOQx9AVCghfkyW4vhjyblABcY0Oo3nElMU46Qj8mUdoedCzIA1WIIb9BXyAkeEEe7fZwrGeSdR8Sl73/wLdrzDJbjbZ3LMi9VNghv0lfICR4QX7ebYpaslm0vycUqimuJGZYQHflWoaz8/Rb9AVCAkfrn8hVhySQk7uSlIDEjUHddWTu70ASm0iUtmscC3I7FQT5bfoCIYGj35/IVR/y6D5d4pDCSFcSc6cDSbxQorRd5ViQr1Lhpt479AVCghfkWxO56i0J5KRrkhLwlMf5uU5CBzUkStsVjgW5pgo75Mn0BUKCjyG3SeSqTRLIySNJSkDfhEL1uCuJqeOgXLxMSbzeoRzvs11L2tPxHn2BkOAF+XK3+RDJ9mnuYVksfjruQzXX15ivwkB8buMy83kSpa2zQ0H+XY0WTh/QFwgJHO38xM66zFJQXk5SAu4xfFoB5uA+VJYqNulog5H4zacY8kMOBfkzNbpOf0hfICRw0rISO+sUS0GZmqQE3FrqSZsxxGGpe2ejAQbgGxQY/A4NJb7lKYeCPEyNHfI0+gIhgWOnZ8hAS0FZlKQEdCz2lCW4HxV8kZ46GIifSvwOzSU+f7RDQb5XDUGeTl8gJHCyTkrsrO08qZTW7cgTfrFZUbkyLsdt6I9hGIXx+BAfYSrGYwyGYwA6o6mjo7lGGIp1nlzN+NKhIF+qhCBrM+gLhCiAOJjIWasbfs3/mzouLm6sxF2IW/67LNyAwfgMf9oQtz2Yj9HohkYJnvnXoV8n5EjI5yg+1jmS4+22flIfxkx6AiEqCPKmxO66yFJUbkuyK/R+DLEMU9RHf8yxUfPCiF2Yjl64wMbP0RSTMUqasFVGoaOfc6YacgzxKT2BEBUEeVlid7W+Pv1iklkWDUz/X1U8ip8hg2UYYSNCnClN2FqFsfQmBMTH9ARCVBDkb93WZ1gkVRqaYjz2QC6/YQjq+yJsQxz+ZE0UEWSmvRGihiB/YieTN9dCVAqS6KpnlnmxGF5RgDno7nkmxzxHP9OfatzS48UQQpQR5LfsOOz7lsLygJSylXPhPVswRGrlipIR5IOOfpq3VZFjiCn0BEJUEOThdhz2dkth+dp1mOIr+MdevCH1Ksjfo6vDn+RmZQSZ1d4IUUOQH7d3/XiThbAUuojQVsaryIffFGAaGkmXtVmOfoZcZKizQ2Y9ZEKUEOQH7bnsCEtxGZqkEHTAGgRFAT6yyPRwPrIdpui9oY4cs2MIIWqQuCLyoXGRZYbtTlR1LAJVE1TJ8IMDGI1sSaL2tMN3t1BIkPVx9ARCVBDkVnaddr6lvDzhUAKuxh9Qgz0YgooS9sfbHL11iUr7Y4gx9ARCFCDeyHn1CeOIqJPshV4O8xG85g+b9TTMr2F/6vCNj6olyK/REwhRQZBr2XXajATx3rdsH+NNh4p86qIu8gjHV7urKCXI+qv0BEIUoFy6fbd9JMEh2Q22yl/+mECs8vEtnsGduBpN0RYP4ytH9SE2YCg6oiWuwo3ojSmOAgn7MCSpa9R9HIv/y2rtjyFG0BMIUYCM0+27bQVsSHDtIlHlt5bYYvmElRhgcMh2m+0Ax7RSd/HScRM+TVCvrnhLpfaOe4QUOpTjA1KbRkkZL9ETCFEAcYLzopnmLLbshHcPDlh8diPuNy1G+blNqatjWv/YSY7wdNSzPSO9HcsxME41OYY2lJ5AiBqSfNDJHvn3BGLzo+nhXh/Lfeosi6hqA+yQUD3tQQcXUPbheVuJfN0c7L3/Yr+tsqA+j+fpB4SoIci5ybdeMuJXXGLwuUGWn1mDSoZvq4J2eMtR9bd5eND03uBQR8K5G8NxToLZaIxhjq+2DFdPjiGepR8QooYgr3bmvJ8lEJwfSrUqjWNcgs+MNris3RPfJn2pej1exfkG8umUnRhm8JzStThGY7PtC9NVFRRk7Wn6ASFqCPLPzpy3PvZZCM6oUhUa0jExoUx9WeIz9fC96zS2Xehe6nAwuSvWOeiC9IRJgR0xBXsTPu0RFffHEIPoB4SoIchznbrvw6Z33u4yEKoPbZairFHk8G8b5PD2kUPGOLpaVnVOfHVkiI3KF1XQC79YPOU7VXrolRyP0w8IUQJthnMHnmIYO25scAg4w7bk5WE+JuA1yUXqczERYzANWyU8qxAL8IiNG4lNMd5wr3zAgwpzkkIWA+gHhKixQ57s3IGzsLKE2ExB5VL/qhJmI3rkIwfdkZWwV/cA/FrikwMVlWMB0Zd+QIgaO+SxybhwY2wvUvK9h2G5nfmILnsxFbcmaAml4zq8fyT3eqY6DZtKj970A0KUQB+WnBM3w24AwApcZvi1fT2iz3ZMwA0J4sLZGIJcrPOwdZSEkMXD9ANC1AhZDEq+D94eTDbMIH4E+5E6bMCLuMhypiqqeBmk6OhJPyBEjZDFw8k78nmGheenIhVZjH5K74ItgysP0A8IUWOH3FWma7fEOqQuezEJzUIoyNp99ANC1Igh3yXLreMY7LCvXFT3yj0Mck6UHl3pB4SosUO+XY5Tn4scanGRS9evK5t1bBCyuJt+QIgaMeSOMlz6BvxJFS7FfHRSOdnt75BFF/oBIWqELG50687peDGJMpSpwlJ0Vl+U76AfEKJGyOI6d858fqQvgMjhe1yntiDfTj8gRI0dcms3rtzJVcmeVOIjg+ZU3CETQorHkNsm68bl8WoSDYxSl224V1VB7kw/IESNkEWH5Jy4Lr6jxjpmsklvlIAP9e6kHxCixg65UzIufCd2Ul2TzFKuxbQ3QojJDvkOp+6bidHUVResRkNenSaEGAryPc6c9xIspaa6LkekWLGhvvQDQtQIWfR34rr3O+oBTcxYoVQhIjY5JUSVHfJwu25bGZOppNL4XKHrIvow+gEhauyQJ9lz2jr4mSoqlcfU2SG/QT8gRI0d8pd2XLYpNlJBJbMX56siydPoB4SoIcg/J3bYy7CD+ukB76siyPPoB4SoIcibEgcr1lM7bVKId9ERbfEoltj41wVooIYg/0Y/IEQFjhL5iWq5/UidtUk+7izS3soOr6ohyDvoCIQogHZmImcdTJ21zePFuk3bYaMiuRaZJ9MXCAmctGxrR62HA9RZm8wsJq6P2fzU1WrkWVSiLxASOHpTa0d9jTpr+/Zd0aseNbDF5uf6qJGJ3Ji+QEjgWHfUq4JdVFpb5KFNUXnDdNuffFuNHXIn+gIhwQtyX+uabqWZjevwNDZTg4tlSxSvdPyCg89+qYYgD6AvEBI42kgrNx1rkNZV+/BX8kXU4cMcRPdis9bDUdn+xWrkWUygLxASfAz5Qys3LZ1L+8eR/1eTfaYBALkl+uV1d9jwVRFB/p6+QEjwO+Qfrdy0dL+8VUX+bxeqMeajTrEZexD5jp+ghCDvjpWhNxAStCDvMnfSuIG4HEBmkX+R2v2mC/EaMorNWN8kegx+qMj16fRy9AZCAiXjdOvOIEYU/YLeIoXleDPalbjROCqp57ysSsW3JvQHQoKNINe2dlKjYvQfFfsXH6SoHOfg3GLzUA2zknzS3aoI8kP0B0KCFeTW1k662rBeQ+Mi/6IWNqRgxYpnEC82Txfh16SfpkwJzrfpD4QEiuhh7aQ5hhLyCyoU+TdXGBz9RftGXusSs9QO25N+2q/qNHJaRn8gJFhBftnaSc0uOEwqtkNslEK75M9L9cLrizwXzxuqjiAXVvgvPYKQIAX5c2snvdFUSD4oll9QF7+nxPXo50qEKrLwvstnNlap93QzegQhQQry+kRtTc17TM8olgBXK/Id91aheYnZuRIrXT7zG5XkGPpgegQhgZHxr8ROOslCTuaiSrE8gyhnJb+LrBIz0w17XT/1VqUEWXxLnyAkuP3xeYmdtE2Ca79FI6qV8EVEL0ffXqoK3lQJz12sSHH6I4lveVkn0SsICUqQ29v4GotllqKyotjV4QzLHXU4mXW4nNLf42rXoYpD3KTW/hgCaZfQKwgJSpAft+OktyWQlTVoWEzAh0ZIjPegd4ldbHkMdZVV8TcfKyfHAqIvvYKQoAR5iq2jHixMeIn4ymKf6CVJsoLm01KXNprY6iVth90lihIpMj6nVxASlCCvtOemrRKWzNmDDtKuSqjBRnQr1X17EA5Ke/4DKsoxxD5GkQkJRo5PEYV2HfV1Gzm6PYt9ogFWhFaMCzC+VE5FYyyW+IZpasoxBLRr6RmEBIB2kX03rWTj4kchBpcot/NlSA/xLi+Vjf2SxL0x8CuqKivIYgw9g5AgBLm7E0e9xlZceEqxyyLpeN5h94ygWYy2pX7z27FO6ju2FzsEVW5sjR1D3yDEf0Ee68xVH7IlNwtLJIm1w5aQiPFq3FsqL7iJSXml5DmA60u8o4ZqktyQvkGI/4L8o1NXtVeAfQOaFvvUefg2BBXcHkb5Er/tBXhH+v4+H11KSf7nqgnyc/QNQnzmrBO1PMdNfjDTluzsR98SraD64oCyYrwVg1CxxG9aE8OxX/qb8nFfifdUx2ocRGW1BPl3egchPiMaJuOslfGNTfGZXEJm5GYpyGILnkClEr9jNl7BPk9qxd1Tqmfhl0re2NOr0T8I8VeQeyXnrJXwtU0B+g2XlcrjVWmfvBZ9S4lxdTyHXZ68bZ9BIaGRh//fSNUEeSD9gxB/I8hTk3XXivjKpgjtxSMljskuSbrznFyWoVuJftECVTHEIzEGctGy1DwOOPJ/f1Itirw2djQ9hBD/KCM2Je+wmfjYthTloG6JT3fCqkDFeC5uKZVNURlPY5uH8t+g1Bz2LpbBna2aJF9GFyHEN/RMl19qMSjhdeq/2IWeJQSwAgZhRyClgsYZdOiohIHY6uFb3zc4tOteIn/jbtUEeQJ9hBD/Isjt3TvtPQ7yEL4stUesisG+Nkf9FX2KldP/6zbh057mSe/DowYzdz/yS/y7CcrVtCh7Gr2EEL8EebQMt22O9Q4uRAwvVR+iMh7HZs+leBcm4QaDUvDnYrhnMeND/IhLDWbN6LvFWvVqWnShlxDilyCvluO25zjqnPEnupcSxop40LPWTwcwHV2KXeb+a9THOA/yjItyEC+UumoikIG3Tf79RaoJ8nx6CSGhiCAXH10cxYMX4gaDZ1yCEVL3yvvxFXrgHMPod1tMLxUykM18w27SWZht+on+yu2RmY1MiC9od8p13foO97gLSlRP/mv32BETXMvyb3gNHUrlF/8liL19KAq6weB7wKGrMVbNsGarV2ZoBD2FED8CFpNlO28cPR2mjS3GbYayFcfVeAJfYKdDGVyF9/EQLjT9CRtjDHb7kMcxxOQidPcEt/8OqHaBGmK/fgZ9hRCvOVrkupXfqobx5NEOi/EsxwDUNE2sa4A7MRRTsdgkKW0/1uAbjEM/tEN1i5/2fDyOX3xJqhtdqh3qXzNjJ2/7VvX2yH3oLIR4vT8+z62j1sB6g7rBAgItsdTx4dfH6Ij0hGWNzkVjNEULtMU1aIoGtopWVkcvfOtLReYdGG56ueNmrLX1jPHqCfKf4gT6CyGeog9066gXAyjEeMMv2enohz1JxF1fRgvEJUa1e2OW1C4fVnWUB6Gayc9RG5MdzIGu3sHeLfQXQjzFeR3kkqPFYQn5A60N/39D2wWIStZem4SurroxZ6MLxuJXny6bHMRHuMn0z0gcvRzmOV+u3h55aawMPYYQ7wIWwr2bdixS4XeU4T5Zx2Mu9qcrMQWP4TrbvTRq4wYMxAf43fZ1brcUYgH6msa/BQRuSKLc6FMqtnS6nD5DiHeCfI97J72vmIxsxB2G/+oqG41RE7EdP+ADvIbB6IEuuANt0RZt0Rld0BPPYAym4UcfcieKsxQDcYHl/DSzWci/JPNUFOSZ9BlCvBPkme6ddEApKZmKcw3zfj9DlMjFaFyVYG4a49Ok9+l5ltki7LFHSNTk+BRx0L2LjjDcy/Y0OJTSMSQiYrwW/Uyum/w9rsMnLnM6uqooyLPpN4R4I8gdZLjo+6YXhhsZBjgOhFyMV6F7qXL2okRB0e5Scp2nqSjIiDei5xDihSBPl+Ggcy1qSDxmsE++1oeabl6xDYNQwXI2GmCotHrKewxLIQU+5jHXghDppP/Peadpo2Hd8SPHIJ58oWUdB1XJwwjDO4l/X5DphfmSMzs6KrlH1q6k9xAiGf1uOe6ZqCfzRjQzKAU/L2RyPNewYtuhUQUPIMeTmnFvKSnI+gLukQmRHbD4WoZzVrfVKeMug+aoM0Ijxptxr+nv3wbvYq+Hb44rKcmiOf2HEJn7Y00UynDNpjavTgwvFU1Ox1uhkOOPTK6k6OiERZ6/vYWaQYsVWcfRhwiRhvawHNe807a0vF/qiEr9NLg/0M7k974dy335CV5Wc4cM0ZU+RIgsymgr5Djm0w7EZaFBDbQ+nvfrSP4Q72VUNLl7518E/DdVBTm3wn/pRoTICVhcKssx33ZYl6J+qSd0SqIenPcsRhOTgkXv+FYj4xCNFJVkbSj9iBApiImy3PJbh/KyCVeWesbl2KCUGO9EP8OazHE8iu2+/zRPqbpHzk+vQk8ixDUV/iv2y3JL51K6y6CxaR38rIwcz8T5hr/pFT4c4Rnxo6qCDP0z+hIh7gMW98tyyaykvr4fxN2lnlTVogezf/xu0vukIob4VODeiAbKSjKviBDiPmDxiyyHbJ6kxBRggEF3kSG+NFgyv+g9xOSqcjv8EeifiSfUFeQVbOtEiLv98aXyHLKHC5mZYFCi52bkBiJ5hfjQ4LjxUEvS8T4f4pXmB2UFWUDrT48ixM3+eJo8d3zFldDMQpVST6yFT30XvO/Q0uTqx4MB/YEo+efiQnUl+UBaZfoUIcnujzNFgTx3/NKl1CxDXcN99w4fxbiDye92OeYrc9A4UOE9spjNyhaEJLs/HiHTGde7lpo/cbVhhYzRPlwYmY9OpuWCRiFPoUS8hSoLMrSO9CtCkqDsaWK3PEesLiW6uh8PmXTh+9yz6O0BTME1pr/XPdio2DWVQpNUPEXG1vT/0bcIcYysChaHRltpgjPFsFu1QBNMk5558QcGWXSIvgQ5Sl7k7q/2HnksfYsQh2QcL9bLdMPHpWYAX2vyljoYhJVS3rEeo9HSoIfJX+NcjFMqUFE8vCLUluQr6F+EOIsfd5brhB9IlZx8jDBtWaSjBV7E4iR3y3uRg2fQ3EKKBbIwRMmaGn9nbtdRW5LXpZ1KDyPENtnHipVynfB3D2qb3Wz5xhrojKGYgTW2rmgvwiQ8jpYon+D3qIrBSqS3hTjTAgLidfoYIbbRb5HrgFU8ulc3C5fYurTdCNejKwZiOIZjOEZjPMbjZTyBHrgdrW0fgtXAkAAKBiXDYtUFGdq19DJC7HG0WC7X/dp4Jj15mIiLfRCQJngb+xEeGqouyRvO/g8djRA78eP2st1vkMcx0w9NKhLLKYrUXaFrH3YZrPweWbxJTyPEzv54qWzn86NJ6XLLFLVkRjraYrLSx3fm/Kq+IEO7hs5GSKL48Y3yXW+zTzJ0ANPwAM5z/fNegJ6Y5uOlbC+4TH1B3qydSX8jxIKs48Rvsh2vnu931X7By7jVcZmdDFyFXngLKxAFhoVgjyw+ZW0LQizQust3u3sDE6Ud+AavYwDuRWtcXOqGXzXUwqXogIcwDO/hBxxAlPjDMpdamdGNPkeICfF/iy3yne51hWRqP7YjF9tDlTGRLM3DIMj7RXX6HSHG8eOBXjjdUpAgGBUGQYb45awT6XmElA5XnCmzvttfo2bgXTRSlT8N+2ErOF6i7xFSCrn1j/8ad1IZA6NdOAS5UL+a3kdIMdKytDwv3G0cdTEw3g2HIEPkajo9kJCi++MvvHG236mLgbHHpHa0gmNe1nH0QUL+kuM23jjaeVTFQLk3LIIMMYReSEgsFovFyv5DrPLGzbpREwPli/AIMvSW9ERCYrGY1t8rJ5tITQyUPJwbGkHWdomK9EWS8sTTxB6vnGwNNTFg+oVojywWl/0H/ZGkevx4ilcOVp96GDg/hEmQoY2kP5LUDldc6Z179aAeKkDjUEmyfhN9kqQsmSeL1d451xSqoQIMDZUgi91plemXJFX3x0M93OvgT6qhAqxBPFySvDTzZHomSUH02iLfO8dqSi1UhLbhEmSIt+ibJPU4RnzvpVsNoRIqwpSwCTL0W+meJNXCFQ9761SLqYSKsA/VwibJ+7Sa9FCSQsQriH1eulRtlt1UiIdDt0fWVohT6KUkVThKzPbWoXpSBRViUegEWUBMjx1NRyUpgejptTvNoAoqxeVhlOS+9FSSCtHjSt6GKwQqYg81UClGhlGQC7Vr6a0k6hwj5nntSh2pgIqxBRlhlOSdWiU6LIl2uKKv9470BhVQOW4LoyBDLMn4F32WRDdcUUMc9N6N1lL/lGNGOAUZYnKsDP2WRHN3fIL4yXsXupLqpyB5qB1SSda603NJNAV5lB8ONJjqpySPh3WPnK83pu+SyKE/4I8DLaL2KcmKsAoyxBYh6L8kWnLc2MtSQn+PC3hHT1muCa8kL2Q3ERIlOc4U2/xxncepe8oyPryCDDGGXkwiQsa/xM9+Oc4P1D1l2YVKIZZk1oAj0eBoMc0vp7mQAQul6RbmPfJ+cR6dmYQ/XDHYP6dhwEJt5oRZkCE2pJejP5Nwy/GNfroMAxZqU4gG4ZbkhWf8kz5NQktattjrn7swYKE+z4dbkKG/w5t7JKRoZ4q1fjrLE9Q75dmA9JBLsuhNzyYhRJwg5vrrKgxYhIEbwy7IhaINvZuET5BH+eso9RiwCAUfh12QIfbGz6V/k3DJ8YN+uwkDFuEgD3XCL8nryp5NHyfhkePL/LkozT7TYeTZ8AsytPm8TE1Cgn8Xpf8eDRiw4MGev5I8lp5OQkDWSf5dlP57DKHOhYhbIyDIAuJBejtRnTLapACyQ7GKKhciZkVDkAv0q+nwhId5pUZLalyoCP2NvSNtUNOy6PNEWbSLtbwgHONNalzIGB4NQYZYLk6h3xMlSS8nNgXhFOWRS4ULGbmoEBVJ/iB2FH2fKEfG8WJeMC7RmfoWQu6JiiBDf5TeT9QLV4wMyiFmUN1CyLeREWRRoF1J/ydK4W+ZzaKjBg5S3UJJ4+hIcm65dGoAUWd3XFPsC8oZelPZQsro6AgyxPdnnUgdIEqQebJYGpwrLKKyhZSdqBwlSX6TSkBUoIz+TnBu0JBXpkNMjygJMvS7KQYkcES3IJ1gKFUtxPwQKUEWB/X61AMS7GFebXEgOBeIYy1VLdQ0jZYkb2RZThIgaaeKlUE6wM1UtJAzIVqCDPFN1nHUBRJQ9Fi8F6z5f0xFCzl7cU7EJFkbSmEgwUSPewZr+rWQR0ULPX2itkeGfiO1gfgfPa4fTCGhv8fjVLMIsDxygix2a5WoD8RXMk4X64I2/BVUs0hwQ/QkeTEbPBF/o8fvB230ralkEWFG9AQZ4mWKBPEN7b7gTf5dKllEKMBFEZRkrS11gvhCWnaQuceHRlXspZJFhteiKMi74hWoFcRzsk4Sy4I390epYhFiN6pGUJL1BRnHUy+I19kV41Qw9h+pYpGiXxTjyBDPUS+It3J8iwqGfjkVLGKsRnoUBblQNKdmEM+IV9B2qWDoY6lgkeOWaO6Rc4WgbhBPECeIRSoYeWXson5Fjq+jKcgQc7OPpXYQL8IVw9QwcR7oRZMroirJT1A7iPz98eWiUA0DX0rtiiTuK79dgv5orWATVL0x9YNIJeN0sUEN825F5Yoo+1DDlWWciwMADuJO9ST5z3JnUUOIPMqID1Qx7g+oXJFlsCvLqH34Kfl4WD1JnhU7mjJCJKHdqYph18QB6lZk2Yjyrqxj4ZEnDVdPkntRR4gcOa4k9qhi1oOpWpHmXlfW0anIk15W7Sp1nl6bWkJck32smKeKUaezh17EWezSQiYXedYrqu2Rl5x1IvWEuN0fP6WOSd9KxYo817osOrWqyLNGqFbd4kXqCXGFXk/kq2PQs6lXkWeqSxtpgFx1d8mFWhNqCkmatFPFanXMuSEKqVeRJw91XNrJ9cUOfhU73ttQ4b/UFZIk4k2VjPkVqlVK8JJrS7mlWPvbQWpJ8nvUFZJc9LiFSoZcGdupVSnBNmS5tpbORSS5EL3UyrfoRG0hjsk4XWxUyYwfolKlDI9JsJe7ikhyPu5SSZJ36Br1hTg9zntHqfNpLKdOpQwbXF4QKS3JB9FeJUmeGStDhSFOosft1UoYupEqlVI8IMVqigYu9qK5SmGLLtQYYpuyZ4tctQR5JjUqpfgNcemSvAl11bHo3ekZ1BlijzJimhyzq415uF/CcxqggBqVYtwuSfruLZIsuQzV1AnC5bDcELEXrugsy+g+hNvqBIfGaOpTyrFImvQ9UeSpc1FBnV1yV2oNSZzspoudcgyuHQDgMtfPqcKWTSnJddKkb0yRp74LXRVB3pdWmXpDrDlKzJZjbuXxG4BVEp7Uj9qUknwhTfri+KTIc59UZ4/8dewoSg6xClfcK8vYngEAPC8h4e13alOK0kSa9FXEd0eeWoCO6kSS76bmEFN0Tdslx9DqYx8A4FLXT+pIXUpZ3pMofdnYcOS5O3GxMtkWaXHqDjHbH0+Xm6b2rYQn5VCXUpZ8NJAofs2KFB36XZ18i4+pO8T4OK+jLCO77bDZd3b9pMas8JbSjJEqfr2KPPlzSZnOEsIW7ag9pPTu+P9kXQapjHUAgHVId/2st6lJKc0+ZEsVv6L29IIqe+Qt6f+j/pCSgvyuLAMbftjgn3D9pFrYT01KcYZKFb9M/FDkcE+Z+hbjqT+k+HFea1nGdTEOAgD2orrrZw2lHqU82yUU4yw66hbpKJLruhi+tNGMGkSOcPZ/5JXa/PKwsb8mIfSxjXpEMFCy+HUsci6xABlqCPLqrJOoQ+Sv47w3ZB/nHZSw9+hNLSKQVYyz6Bhb5OmqdN3TB1OHyCE5vkJehG71YTOf4PpZ6cX6B5NU5iHJ4lcJK448uxC3qVGQM09UpxaR2Bn/FH/IMqpnj+SPNpRQOJEQHM7Xkb1HbnL4pAMAduACXqQmyhznDZZlUOdjz2ETf1/C076jDpEj9JAuf8VrwKmRk8xueylPvKo4KMucph35Eui+BkFLahApwlrpe+Q4vvbw4DDJsTXjdGpSKnOUmCPLmNoeMe7pEp72CTWIeLxHPh87jjz9AK5UQ5Jfoyil8nFeF1mGlI6lR/bHV0goTZRPBSIe75EFehZ5/gpUUkGQC0VD6lKqyvGZYpssQ+p/xLA/kpyWRMghHvSgl/ncIs8fo0Yc+cfYMdSmlERMkFfacOdhoy5AY9dPq4G9VB9SilUSaqOUvle6v0gC3A1qhC3uoTalohxfJs+E3jxi1DIq2D5L7SE+xZEFBhd5/hrJ17STHLk82ks5yv5D/CrLgBodabWej0tcP60CNlF5iCEbUFG6/KXjZ+XCFuJlKlSq7Y8fl2c+s46Y8zuSD1oIKU5/D+SvWZEj5AK0UUGQC+K1qFEpRFplcUCW8dxwxJjzcZGEY5blVB1iSq4nQYWiXalXo7IKkvwlVSqV9sfT5X3hW3rElCdIeB476BFrBnsgf1WKhcleVaPYUGvqVIqgt/KiKc5+nC/hed9QcYglOyXU2S49ehR5QwGaq5D+tuaMf1KrUuM4b6Uso6mMP4+Y8UgJz2tKvSEJGeaB/MWxuMgbFnuQYJfE6Eu1SgG0/vJM5u+OHrul9D57n2pDErLPkz4f1xV7x6MqCPKesmdTryJOPE3skWUwdYpc4HhGyvPyqDbEBt4kp00v8oZdqK2CJI+iYkX9OO89eeYy+Yj5bpFy9v0KlYbY4iDqeyB/DYvUSAamKJH+ptWgZkV5f9xIZonvgiPG21fC887BbioNsclkTwSw+JZAiYvU06hakSX7WLFEnqn8XU12LSpIeN7TVBliGxk1U0qPakU6UgMrlGiAql9K5Ypqutv98sykbRHDvV9KN77NVBnigE89kb8+xd7RV4U98iI2doqmHJ8htsszk4VHjPY3KSlCj1BhiEOu9UD+KmBDkTdsRw0V9sjtqF5RPM57XZ6J3FLEaO+Qct+PHaaJU+Z4In+9i71DiVt7q8QJ1K+oZR/XFAXykuiXHDHYH6FLeOKdVBeSBG093yMflNA/XcIe+X4qWNQCFp/JM497ixjszVKeuJjaQpJgvg975Okq7JG3ZPyLGhalcEUzmfVjfztirD9I2R+3pbKQJLnB8z2yN/twx3vkR6li0eEY8bM3ZVjkmOpX1BWSJPN82CMvlrLtcDm2lz2NQhaV+PGdMncP644Y6lxJF0wIUXuPfIcCe2RtAJUsEmSeLDbKM4t+0l1hKjWFKB5HXoZ48IK8K/1/VLMoxI8HyTOKykWubyyU8sT6RdrnEKLKHjmzSGFZAOiqwh75KapZ6MkoK6+6W/HrzZ2kPPEN6glRco88uNg7VqlQIXkvy3GGf3/8pjyDqIrtRwx0iZSDjmzso54QJffINYoUlwWAHiqkvz1PRQs18VqiUJ45PFPEPO+WXOCeENX2yGOLvWOdlBJaLse+jLJUtTDvj2fJM4asIpWwVkr5AlcZ26glRAqtPamPXFDsHY+osEceQlULb7rbFTJN4YkiptlLyhP7U0eIJD73RP5mFnvHHyrEkfdknE5lCydlxLfyDKESthwxzG2oJOGJGUUymglxy5UeyF/HEu+4V4Vci/6UtnDuj1vINIMBRcxyqJQn3kcNIRLxoodIHKuLvWOJEnf24v+muoWPo8QP3txcypPS81fHMmoIkUge6nogf4NKvKWjCnHkHpS30KHfKNMEeknfiXSkghDJvOZJ8tuBYu+Yp4Igbyz7DypcqMg+Vvwq84vbyiIm2VTKM7+lfhDJ7PWkv8dHJd7SUoU48p3UuHClu90uc/nvKGKOcgoKXU31IB7wrAfi16HEOz5TYY+8Ous4qlx45PgEbY3M5f+uiDl29mTXQYgMclFZuvill6j8VqhEDxHRnjoXHkHuJnPp2xQxxs1SGqPXQx61g3hCbw/E7+US7xipQtDix1gZKl0oOOOfMsttFk+OHy7lia9TN4hHrPbg8kajEu/YhooqSPJF1Lpw5B8/LHPZL0VhkS9rDSQ8sTr2UDeIZ9zjgfj9XOIdD6oQtHifWhcCMv4lcmUu+1tFzPArD8oaEiKX7z0QvydLvONnFQS5ID2Deqd+/LinzEU/p9huVsaBXgVsomYQT2kmXfzqFfmeeIhrWYyT2MmvEOu9uqck50CvJ/WCeMy7HojfDyXeMUUFQd7JS9SqC3JXuQk/Rcv/vCzlwvQK6gXxmAPIli5+A0u94xwVDva6U/MUJus48YfM5e5SzAQvk/DEW6gWxAcGS5e++qXe8bAKe+RVsWOoe8qi3yZ3uecXMb8lUp44j1pBfGCjlPBa8bG8xDu+U0GQoV1L3VOVo7UVMpf6ymLmN0jCE5tRKYhPdJEufcNLveMiBQRZ/4zCp2r8uL3cpR5XxPQKcaGEJ06jThCf+Fa69LUs9Y6hKuyRC+PlqX0qcpT4SeZCV8YuyeZdH/nUCeIbl0uvabG1xBvWIa6CJA+i+KkYP24td5mLp6fJ6KE3hhpBfOQt6dL3fql3XK9CFHlzxvHUP9UoI77zLu/yIKrzwjQJGXslWG3x8WCpd0xS4mBPb0UBVIz4VXKXuEkxs5NRAZYXponfDJQsfHVLvWG7B9kcSeyRZ1ABVTvQm+XdgZ6MUirleWGa+M5q6THelaXe0U6Jgz1WtVAKrYbcBa5U7ECvALUkXzEhxB86SJa+N0q94Q0lghbicaqgSoI8Vu7ydi1mcgskPDGH2kACYJpk4bu71Bs2qZFpsTH7WOqgKnJ8pjggd3m/KmZyT0qolVVAbSABkIdzPY4iK1L3Ddo1VEJVEt4Gyl3a80rkC1/q+okvUhlIQDwuWfg2lHrDCDWCFu9SCZXgrBPFFrlLO6iYua2SkFC/kbpAAuJ36FK9Y5rB0aESgnzg7P9QDVXIr7hD9tIuK2Zuo1w/7zaqAgmQVp6W4QSAxmpkI99GNVThQsgvcpe1aQljc38X6XNqAgkQueXqWxq8ob8ae+TZlMPgD/SayF7WUcVMbY/rxPcLWMGCBMpeZEn0jyqlmjkBM9UQ5EJNpyIGfaD3meSvPVhfzNS+dP3EIVQEEjAPSPWR1aWev1uJ+3oC2sNUxEBJryIK5S5pixKm9pTL58WLNYEiJAjmSPWR6QZvaKnGHnkJNTHYgMVIbwMW7nMsO1INSOAUop5EHzH6zjdEDUGGqE5VDIzMk8VO2QGLdZIjyJ9SDYgCyOyxd4fB8+crIsjaAOpicAlvnWUv5zUlzGy2y+fVQB61gCjASonZyI0Nnp+HKmpI8jLqYnCC/J3s5RxZwsyedvm8h6gERBGukVh6q9Dg+R0U2SOnZVEZg8mvqC1/MVdLPqqYSx0gijDW0+vTCkWRe1Mbg9kfj5K9lCW/iu1FeZc1MVhSiKhCLtKlecq3Bs//QhVB/oHaGADxf4vdspfyiRIm5rax6QCqAFGIG6V5ytuGgq8rIsl6JvXR/4S3LvIXsmSA4XWJXfkICZq3pXnKM4bPb6DKHrkX9dH/gMVC2ctYtVRGhLv7TQ0Mjz4ICYodqOBJR/a/uFcVQZ5DffRbjuvIX8a7ShnYVR7sIggJjk6SfKWT4dNHqSLIBen/o0b6K8ivyV/Gd0qYV57L/cQy+j9RjCkeVUQ8xAJVBBlaW2qkvwd6e6QfBGBLCfNa6up5l9H7iXLsRkUp3lLHJCSiiiCLN6mSfmYg3yp/CUvfPprs6nnD6P1EQTpL8ZYMk/OR81QR5K2xo6mT/gUsZslfwj6ljOsxV/vt1fR9EuGgxV7Dp9+gTtDiAuqkT6SXEwXyF7B0p7C2Lp7WnJ5PlGSHy8tOf43Nhk/vrY4gs8iQb/vjBz1IJcfWUsaVzS7TJILcJMVjVhk+e4w6UeSFVEq/BHmxHxHkXcywIJFknBSPWWL47K/VEeTCCv+lVvpAWmUvlq93KdP6ycXT6tLribL8ibgEj5lv8myhTtCiBdXSj/3xIC8W76NSpvWRVHknRB1aSPCYHJNnV1RHkIdSLb2njFjpxeKVLic4zMXTvqTPE4UZKcFjvjZ5dgN19sg/US69z0Cu78XS1TIwrIeTflplHKDPE4VZ6eEOuY1CUWT9DCqm1wGLEV4snVEj0uRv/d9OjyeK09CzHfK9CkWR9dZUTE/JOk5s8WLhjLroNpVaK5YQlejnmSA/rpAgi+HUTG8DFld7s3AzDQwr2UugcWyivxPFme3aZ+aYPPk1lQR5CTXTU7Sx3ixc6VtH+Um3u2lGbyfKsx+VXfrMQpMnT1NJkJmL7ClHexOwuMDArHKTftoL9HYSAtxWRl5u8tz5KgkytCspm97tjy/2ZtE6ST2H/om+TkLAGy69Zr3Jc5cqJciiL3XTuwyL571ZtMcNzGpR0nVi2baJhIG1Lr1mp8lz16glyB9TN70T5N+9WbQJEg89utPTSUi41FUxrnyTp+aqJchbY2WonN7IcXWvFm2egVl9mOSz3qWfk5DgJvWtiulTD6glyIiXp3Z6I8h9vFqyrQZmNUnaFWxC1ORTFz7TyOK55dU61mN3PY8EeaE3C3aOoVGNl26mhKjFzqRTOwXaWjy3ulqC/AK10wPiaaLQmwW7xtCokiu0zSpvJEw0T9prulk89UKlBFnPoXp6sT++x6sFMz6GeyWpZ02nj5MQ8VTSXvOkxVMbqBVF3s5jPS8EeaZXC/a0oVENT+rS9Db6OAkROUl7zZjQ7JAF0stRPyWTdZI44NVyGZvWCCltoAhRmf3ITNJrPrd46vmKCbLWhAoq+47eFd4t18eGRvVqEk96hB5OQsZ1SXrNGotnnqeYIIseVFDJ6IO9W64F0g713qN/k5DxfFI+UwkFFs88V7Ud8htUUNkR5O+9Wy7jv/XJ3PRfT/8mKRFFbmr5zJqq7ZAXUUGlcvZ/RIF3y7XP0KjedvycC+ndJHTsSSoXuavlM2uoJsj7Y8dQRWUGLFp6t1jVTIxqmmQjJURNrkrCa4ZZPjFLNUGGnkkVlRmwGO7dUjWQ9lVuDH2bhJA+EhucAkAedOUEWbuCKipTkJd7t1SXmZjVYsdPWkzfJiHkgyTy7XdZPG+zcnIsoN1JFZVGejkvl6qZiVk5LVCfiYP0bRJCNjj2mcstn7dcQUHWB1NH5e2PO3i5VG1MzGqbw+dcS88mIcXpRY6elk+br6Agi8nUUXmXQt7wcqnamxpWRUfPGUC/JiHlLoc+M9HyaZ+qKMhMfJO4Q17t5VLdbmpYzkqkfEC/JiFllEOfWWn5tEkqCvJO6qis/fGZ3i6VebKas0ulq+jXJKTMc2Tp9RI8baSKgoyM06mlcvbHzbxdqAdNDaurg6dkWV4lJURldiMuseb3ACUFWa9NLZVzKWSgtwtl3pT0aQdPaUWvJiHmEge2PjPBs25RUpBFM2qpnJDFDG8X6i5Tw5rs4Cl96dMkxNxr29IrYE+CZ12q5g75NmqpDMqIbd4u1K2mhrVY2rkzIWpjvz/OjQmeVJB0hWWPBflRiqmMCHJFrxeqvalp7XFwBfQX+jQJMd/YtvTxCZ60Xs2ABfQXqaYyIsg3er1Q11kYl92E+Qze0iOhZqfNzUcGcqVJu8+C/A7VVEYE+QWvF8rqht3NNp9xKT2ahJyGtiy9Y8LnTFBUkLWvqKYyQhZzvV6oJhbG9ZzNZ3ShP5OQswQ5yEEOZmEyRuIxdEUrg7rGiXviPKGoIIvlVFPXZB0n9nm9UFZl5T+3+Yzn6M8kkmzBHLyB+3ExBAQqJ8ywANqqKsg7qKeuScv2fqEqoNDUuLbafMaH9FwScXLxGaYk/FeFqKaqIBfGjqaiug1YdPBjqayOKerZesJy+ishAH5VVY4hkHkyFdXtkd7TfizUEgsD68YcC0JsM0VhQdbOpKK63SF/7MdCfWFhYO/a+PzF9ENCACTXDsqvES9PRXUryKv9WKgJFga20UZ+Zkf6ISEAgGtU3iHXoKK6IuNfotCPhXrB0sQS38zvRz8kBECew6YOPu+QL6SmurulV9ufhephaWT92G2aEFvkYwquUneHzM7TLo/0bvBnoZpZGllOws/PoicScoT56IJ0FS9Pt6SmutshP+rPQlVEvuVf/Wz2CiHEEavQD5VVE+R21FR3R3pj/Fqq3yyNq4flZ9ORR/8jpBTbMBTVVRLkG6mp7gT5a7+W6iNLw/rS8rMX0PMIMWEPhuMcCnJEBHmjX0s1OMHZsdXf+Zb0OhKZPe0vWIzF+B45WIQ1NipX2GEnhihxoVq/iZrqRo5P8CfpTUCgUwKT6p1U12pCwrCH/QrPoTOuMhTNCqiDVngIo5GDDS7esgPPoQoFOczEy/u3VOcnMKefLT77FH2ahJJ9mIyOjhou1UJnvIbFlofg5mxFX5SnIIc26e1iPxdrbQJjamr6yXH0bBI6tmKQizBCFm7C61iTxHv/wD0OGqNJHu2pqm6S3m7yc7HeTWBIb5p+8nN6NwkVBzBUUkraZXgaC1Hg8P0/oh0FOYQ75If8XKwHExjRLlMT/pkeTkLET7hEsu/UwUDLiolGfI6LKMgh2yEP83Ox6iY0of4mn9xEHyehYQIqeORBl2OEo2O/g3gZWf7GkFtRVd3skCf5+/dzWQIDWocMo4IlSR5wEOI/g70u34P2+MyBR2xENx8jyqxl4S7tbZa/gvxSQvPpavCpbHo5CQnP+ORJF+IlbLX9U823UU9R0g65HlXVjSD/5K8gJ77gscTgr/nl9HMSCsb56k0V0BU/2D5kfNaXdDitJlXVjSD/6XO1VGxMaDodS32qHT2dhID5hgE3r8f1+NLmz7cMzb338ApU1eQpo+X5bT6jE5rNL4jznh4JHbttNuv1YjTBB7aiyvl41dElFeej3FmU1aTJ+Jf/ptPChtmUjCP3obcT5ekd8KXl+phgqybiMjT2cof8b+pq0pQ9O4CrlTYqG68pkTb0LL2dKM4yJcrF17MlyvvR27O8i9jR1NXks5AzgzCap22Yd/GWTqPo70RxOilTkdieKM9EDS/evoOq6qa0UK0gDOY8G+aSW8xc3qG/E8X3x7oygiwg0BDTUJjgZ16LK+W/eSlV1U2ORcNgzOVTGyb+dpF/P4MeT5Smh4Ld7a7BvAQ/9R50kf3WWVRVN/f0mgRjKtfbMPFCtDzy7+fR44nC7FGus91f4xb8nsDLhpbKaXI13qaquhHka4IylJ9sfQ38K6vzF/o8UZh3FJXjQ5dHnkrQk+QDmdnTz1FV3RzqtQrKTLrZMvRBh//1Svo8UZhbFRbkQx0ppyU44Kso6109qapuYsjXB2UiGbYKb+8/nDG5kT5PlGUfKikuyAICHSyrxM2V1fqJxTdd7ZDbBWcgPWwZ+y+oAIEd9HqiLF+HQI4FBKpigkXmxfdy4uCXUVXd7JDbB2ceGVhty9xHQuAgvZ4oy5CQCLKAQHuLffKXEmLJ+jlUVTeC3CFI47jflrkX4Eb6PFGYm0IkyAI1MMv0N5nsNpu6MOskqmpIQxYCcZuNmbbQ54nC1A6VIAvoeMr0atZL7p69jprqbofcJljTuIHeTEJObsjk+NC4DtsMf5tCd1fAeS3EZR7ytUEbxmf0aBJq5oVSkAUuNinylYs6yRenf4Wa6i5k0TT4Qih76dMkxLwdUkEWqInvDH+jucnXrXuQmuouZHFZ8GYxiD5NQsyToRVkgUr4xvB3Srays3YNNdUV8QuDN4p0m0d7hKhI5xALskBlfGvwO21PsjRnWhY11V3IopoKRtHUVp8DQtRjAxqEWpAFqhrWlRmdzLMKyv6DmuouZCHUMIpn6NkkZOThU3RUokuI+0oXWw1+u/rOAxYrqKguKXuaGiaRju/p4SQ07MfrLnIRVEyCK/0ddaTz50ygorrlGFVMogF20s9JCNiH13BehMT40Bhc6vfc5rwCHHMsJAQtdqhiEp0TtpwhJGimoW7kxFhAoDyWlfpdH3B687YR9dS9IC9XxyjYypSozO+4IZJifGi0QEGJ33emwzoWZU+jnrq/q/eVOiaRgfn0eqIkhRgTiqrHMjtd7nZW/e13qqkMQZ6k1t2h1fR9ohxbcWPExfjQHrkkrZzkWEyimsoQ5KFqGUVj7KL/E6X4AeengBwLCCwo8ZsPdvLpXlRTGVdDHlGv1QyviRB1mIIKKSLHAn1L/O6O6nSwV4gUQb5RPbPoWup4gZBgGI14ysixQN0Sv7395lRaXsa/qKYRqWZRegygEhAFeCKFxPjQ+LXY77/a/ifnUkulUO4sNQ1jKNWABMyglJNjgY+LzYCD4vtPUEvlUEbsUdM0hlERSIA8Y8NGr8W0iAnySyWySxhB9v9qyM/OlqwCzsOlaIm2uA5N0RCZnhnHi1QFEhDjE1rneZiMQhRK6NSs0nik2Cxsth1BzjyZSion7a2G2GZv0uujL97BUoMciE1YgHF4CI3d9qwtNV6gMpAA+DJBFTcdfbDn8L+tHSlB7llsHjbY/dwcKqkcOa4ptti5rjEIi20Z8mZMwa1S98z9mHFBfGYVqibYG+cU+ddXRkqQexSbiUU2P6UPpJbKyLCoJbYmmuo6eM1x17tdeAOXSzORe3GQGkF8Yx+usLTH1thU7N/fHClB7l3sd3vfriBfSjWVkfCWoNJbJp7HgaQNew7aSjKSm3h7j/hGT0tbfKBUyK5vpAR5ZLHfbai9T+0960TqqVs5rpoodnwdfndt3N+hpaQL1axxQfzgM0s7fMqgROyYSAnytGK/W3d7n3qfeuqSjLLaGsvKpnhOUuy2ENOkVAKoyUpwxHO2WR7RPWf4mVmREuTiVZHttXHSOlFRXVH2NLHEaoJrYJZUM9+NvhJ6j1XABCoG8RSrHeETJp9ZEyE5rlnsG8A6e58qEP9HTXWTd3yCnmN9n/1XD0x9oZTuvN2OJBsRIpv5Fmmbd5r2sylEjcgI8p3FfrN3mfLmiyCPsprey7HRI3Pfgc4STOZyrKRyEA/IQ2NTq2uG/RafbBsZQW6NQUVGM3bS80GOu1lNblPs8NDkC/GChKsjVTCF6kGkY344VznB8XbqlSAqlvKWSVVNmrRLtDzzqb0CuZ6b/UxUkdIQdRsVhEhkD2qZWtukBJ+dlsJyrK2gqiZ/L0+3upfX2Ac5BoCfcYEEQzgfc6giRBrPW/zxT0RuStVMLjGGU1eTJPtY8Y2VwG3wzfg3J7gLZfOrEnphN5WESGA3qplek95u4/NXpHLIIkdvFTuG+uo8evy8VVz2F18dYIfdA4OEFbdmUE2Ia0aZWtg7tj4/IKWjyAJilX4bRdnZzbyrRKHZdGYUK5biDztxjSRjuM/WHoYQM/JQz8S2rrJ5PerzVBdkCIhleqtYGSqtvd2xELnmU/l2IG6wE9dKMoVamExVIUkz1dSy7G5UDkg5qo7AEd9X8QpUWzvR4znmk/hogJG7FtJMoSPWUVlIUjQ3sanbHTzjbsrxobFP9IgdTc213h8/a9WEJsjilttwiTRTqIThyKe6EIfMMz00Xu7gKR9Siv8e38TTqLrmyW5NzKPH55Wo7eo/q3GuRFNoUaI4CiGJuNfElto7esoeVKYQ/z22xBtReQ3RNfMi9PEADvNK86NUU87AIBc1nEmqYS6ksx0+6YFQS2gGzkEd1EcTND0yLkZ9nJtkjrWWJ7pSfR1Gj4co4hRfSKgFV3Q04KURYpPJptekCh0+aX4ohfhVbE1QLiEff+JnTMcL6IwGzkofvMxocsno8ZPm03W9QhHX8ZLNLI6H2WWE2OAmEwtKptRro9DJ8VDHv+NWTEYXZNndJ0/KOJ4q/LccXy4KzCufblTKMXpKN7a6+IZ6QyzZYvLd7BzL6m5mjA6ZHD+W9LztxVsWtfGKjfd4YeQw5c4Sm8yvHX+mmGscwNXyL3WiH+PJxIJRtnov249HVw+RHA90HJQpTiG+sld49HVeF4nFYrGj9M/MJ+lJBZ1jnSeFvi/z+VI4CRNmF/iTPYMYHBo5HiRpBmfiwsRv6005jol+wqLcdp6S7pEj+XDvr/PjIcxPJobx0LhJMmiy/SS3oGIYygGV6C3tjr0YjPLWbywUzVNdjhuIfLPpqY61yrrIUI9M8Fqsov6QEkw2/TKfPE8qL8cVPGjwsBh1rd+6XYhUvgpyplhv/tdR5fpoBbjKIzPMwngqEClGVxNbWezimTsV77BXA996Mpe5aGf95tkpmwKXfayY7cXJqj9846Ex3ootVCFy5I9/tkllcG8OClUYl3r4TTEfj1u/vVuqhitGmE/K1YFWrrBHBw8NMluJu4lEBRZLzbD4m4PK5iPf5XnP9tFW9/r2pGTYQtxuviDVsDoEjrLCk6O9v0Y6hiR9ZEOihNl5xTTXT16oYEundAz3ZVbHWl4TSb3o8cXigHn0+JOQuMqDHhtnB5+6BxKVaW0iXDL6rj+imBzXxXzf5vUxi58jrW5qyXENsdN8MvqHxlU2el45q46PBkpUJA+VTOoFymCXnexc30Y37PR1ZptbHe2lDhlltTXhjh7/zWAfvsIxdJHK/GBiFy9Ie34FJcS4qgdJbolYZ3FjMWX2yOkZYrlVssuaULnLLtT0wVg7YhuVKUUxqzsh75vTGAXk+LaAKtZMsaptkRJHeXW0zVa7wa9D5zBjfIqtfU9tSknuMbSH8kkVFTKjW6BiXFvC8WSyFJr3yyzUKkVfjtuLfVZLMyaUMb6GPt1bmkh1SkGMb5Y1l/qOg4kuS3g24nhIyuFk8nxvWjlZGxlpMT77P9ok68W5L6QuM8038+2laG0P4hV/mlhCP8nv2Y2mAchxa/yowBx3NW2DWva06O6Nm5lfkj40rgttAcpCiT2pEyfC7aRKpRCfmNjBVOlv2oIrfRXjC/GRInP8m3k29h3RTHKrKT5PtDyNsT3EbrPQWcMYV6MhfqVOpQzPmljBOg/etROtfLLhbLwqNQbullvMbkTkRG9nXFEba94N5O9s23Uhd5w7fNxbnMNr1SnD7SZlN71hH271oWjQS55fjHbKt6YHe+XSI3X9QxtrXlyzqMAsC73j/I6MCF4vJUHT0CQN0rvw2zAPCwLUxouKdpC8Otol68v+Q79JfG3368tPkXCd3j4fiPTkAV/k2Wsijt720ZmHOh7Y6xV4R+ErX6bNi5eEP0hRXTwvcu0u0wX4LSLOs8V2h1tZoy12U7MijVmdtykev3cn+kncJ2fiLuXvF+xAplliXvnQSnG5s8S94jsnS3Ul1kfIfYb6njZ0NbZStSLMRJN196P74lJcL8FCm2JMSI7ru0SpOrI4Rb9Jm6rlOVus+7EvYl8w6/guyQ3Y8inCDDDpvehXguh36Jxkgc44mmEYlodormea/S4zwyXFJ+hNxUTzUpoqlRLxngkBJNefh6VUrohyk0k3DT9ZhSG4wpE93onx+DN0c52Hqsa/0UFxSkgaMOlNxZtidzIicn2kQhV/k4/LApDkah51HyNB08Ckn4b//IHR6I7LTXKJ4qiLtuiNyaFoLGHGPWbZyC2VF+O0ymKQ2JhsHuLYCJeT/Dyg/rwfUb0iR56J/D0b4M90AEvxNT7BRIzCOEzBdORgmVKXPJLnA7OaFkMVluIz/inucHZwVzz61SvyPTDaBtT4ZgIVLGKsMlnrdzk1nrAT5Y1nfLGqFz3OFH3FluTrOt0RmRQ3KxYH1KdMD2WtPGLOl55XQia2NlOFFf6rnhhXEm85zaIoujPuHqoTV3d0DaiUISU5Wpi14dzMqfGIF818q7lSYqxrYkTyYlwNfbE2pZZ1TWBNcXSMpVdFBuMmnJVRyKnxiO/MPOs5ZcS4wn/Fy+Jg8mnh45UrJOIHAwPrvkBJjg7GNcgu58R4Rp7ZbduFquyNW4lNyXZLHpjC+bHbLZonei/J4+lZkeByw/W9nRPjIe2NvSpfgVzktLiYnlz32PuRk/J9kkcG2KOMu+RocI7h6g7kxHjIy2apb02CvoF3s9jrVAgqohMmYy9XFcBBk6R+vyT5HS5ByNlrsravcWo8ZJGZID8VoBhnHK+NdHoxoRMms/ZYMd4LtJNvOj7lEoSa301WdhqnxkPyUc143r8NTI7Ty4m5Thz/RrzDPm8GFAbSNvLvUQnfcRFCzNcm67qQU+MpHY13yHlZJwUTqjhP22zX5S/BEKzhCpoyN1BBFqiREhdxosq7Jqu6gVPjKWanP2mXBHH94yKx096+uBP7uiX919a/UR+buAghZZiJ57FPjLf8YOZNfXyX43gjsc9OB7xnQ1hcLxiWedifzG4m+B4uQyjpbZJOSrwlD5WMgxYz/M45rif2JHLvLAzCDq6ZA3oELMgCN3FPFUqM+00348R4ThtjQd4VO8bP2HHFRH3wMvCEoh1jVWYjKgcuyX25DCHkWsO1vI0T4zlPmZVHq+XnBelfrZ26JZZxpZLimcAFWWASlyF0GOexP8yJ8ZzPAu+ud5T4xMqdy+N1FjRJmt2oFbggZ2IxFyJkGFdVeI4T4zm50I2vW73jV7iil3VVCuazumOsAnvkupFvDBAt9pmsIy/F+8HFxrO/KVbGj1S3mlalNdvQkV2TZ7bAvo62yOdShIa1vKcXIA+YlSTI9F6Pj7FqyNSaSVNS+EQBQRZ4igsRGsyyYdnO1g/eMvOhzt6HK3pSjv2gpQKCrONzLkRIMGuWy7uXfrDMzIfe9bpuxf/EDjP3vQb7uDLS+M7koMDfUZsBqJAwyWQFt3FqfKDArJ75ttjR3saPXzGvg8AqFXLprETYguXNw8EIk7sAzHbyh9uCyEXWKol8sw7Rs7kmkvnDrMm4z+N9LkUIeMrkGw7xh1FmdZEf9lKQ3zBz2he4Ih7QRwlBrob1XArlechw7RpzYnziFzP/meuZHJdLN9sfN8QBrogH5KKqEpLcjl98ledOw5VrxYnxiULUMPaeAvF/Xu2PnzZz2FlcD494UQlBFnibS6E47QzXrRMnxjfMzny0Tp7IcdZx4k/jF3bmWnjGPlyghCBns2af4lxluG73c2J8Y6KZ97zvTf5xM7Oabsyu8JJJiuyRH+NSKE09rlrAbEHc2Hf2p53qhSCPMXbUrlwJTylAEyUEOZ3V+5TG+LRhKCfGR5qbXbC6xYsL01uMX7aI6+AxsxTZI3fgUihLvsk1IpYW8pMXzHxnlvxmTbWMX9WCq+ADbRWR5JlcCkXZzhxyBVhi5jkF8TTZAYtuxq8axVXwgV/MolM+j0tQwMVQErNab6xF4i+Xm/nO47JT3iYZv4hxRX/opsgemcUcw7U3m8+p8ZURZp6z9awT5e6Qlxu95lxeGPCJDSadbf0eV3MplGS+yXot4dT4ykbzrvEyC3GedaIoMHrJPVwB33hCkT1yDpdCQcyKb67l1PiM6XnPMok9qPVzWMEiaHaYXc30/Ro1UY8PWHxTET409x15e2S9qfErPuD8+8goRfbIbH+qHuNN1iqPU+Mz+SbdvwXEpvi/ZUWQ7zB+xY+cfx85gDpKCPJ9XArlGGm4UpU5MQEwxtRztKdkCXIP4xewm4S/vKGEIFfGbi6FYjzLasjKsBc1zQQ5T68nJ+mtP78QqUCeScUC1n5LdfobrtPFnJhAeM7cdzZIKcapP2P08EzOvO9MVEKQb+RCKIZxG/pmnJhA2I1sc++ZLqHLnnjZ6NE1OfO+U4CmCghyBk/vFcO4Fm9bTkxAjLbyn5c9at10Iec9AOYosUeewoVQihvZoFYp8nCZlf/c43aH/KbRY+tw3gPhVgUEmYXP1aI5V0kxFpnf2YMoEM3dxZBfNXpsLc56IKxD5cAF+QIug1I0MlylvpyYAHnMyoP2ivPcCPKLRg+tzjkPiFcV2CNv4DIohHGG+jOcmAA5YN1aYoOuSW5vyrTzoMhX4GiPtZFVIstwjUZwYgLld1Sz8qGfxSnJCvIAw8YkzEMOjCXICFiQ2RxIHQpM+oW8yakJmK+sIskQX2Qdl5wg32f8wC2c8cAYGLAgP8glUAb2C1GX0dZ+9FJyMeR2xo9bwfkOjL2oH6ggM8dVHZabrNEsTo0C9LH2pJuTEeRLjR82j7MdIME2P72MC6AMOWDxL5UDSpaJqvvSsp0LcjXjh33M2Q6UhwIU5PqcfmV4l5kwin+bbWblS6sq/NepIJ9h/KhXONcBL/TFgQkyK4mpw8swPnQ/wKlRhI3WpXM/dVrf4iixz+hBvTnTAfMjygckyPU4+crQG7y4pTrLUNXKn/o6vTy9xOgxHTnPgTM0IEFuzKlXBuM+bs05MUoxy/IytXals8S3qUaPacRZDpwCXMfeeimO8dfhuzgxivG6lUdtLXeWkx3yEOOKyIWc5cBZj3MCEOQenHhF2GVyLWQQp0Y5ulpHksvYP9a72/ghGznHCjAlAEF+ndOuCN+brNBkTo1y7LOub3GH/ZDFlcaPWMA5VoL7fRfkhZx0RZhkskI/c2oUZKXV4d7ueHm7O+RMFipXmf24wlc5roaDnHRFML4Jls6kN0WZYRJiEhAQc2wmwGUdJ/KNHvAC51cRfkcVHwW5GydcGa4xXKFLOTHK8riVb/W0e6y3ko6pNu/5KMg5nG5FyENF5liEbs3amPvWfr2avaDFZ+xrqzoP+ZaDzOwaVfjZZI1e5NQozAarzKhvYkfZ2SEPN/pwFbqmQhzAVb4I8iecamUYb7JGn3FqlGaShX/pt9gR5G4sYKI+q6wvaEoZ13GaFaKnySqt4dQozi3mPrbFRrmh+FWMJoaB6VZnuBJGZazkJCvEJaxjEVK2Itt8j/xiYkGuYPzRMZxZxRjsoRzrmMoJVsqpjf/83sGpCcXmyczPtDytUiJFPkYcZMW3MFCAjp4J8jBOr1J8YrJOIzk1oeAuc1+bnDiKvJStfMLBbjTyRI5ZHUE1+pus1PecmlCw2eL2QLxWUhXf6nBWFeRX6ddEMjGR06ocTQ3XqiLvUYaGYeY+916iTOTBxh/cxVlVMj4l83DvEvZnU5BdJhV2W3FqQsNBNDTzusIE3fbE7cYfXMxZVZKnJIlxJQxhXQQlmWGyYk9yakK1dTI9Qh9nHbK4yPhjH3JOlaQAN0tIcuuHTZxKReltsmozOTWh4iYz/zsg/s8qZKHx5D1cbEcDF2LcFOOxm5OoMBeZ1HnbzqkJFYvNvbCPZeKblsfeEeFiRRKHew3QA5N5A1N51pqs39WcmtDR1swb/7Csa2Fc8a0N51NhPrE83KuMy9EMbXELumMIJmMBtnLKQsJbJmv6FKcmdOSY+2gDK0H+wugjdTmfSvOEhSBn4VdOUEjpzNKoEaKp2Z29kVaC/LrRR8qz4pvSFKCDhSRfhj2cohCSj+omOcj7OTkh5EMzD91oEbQQjxt/KJfzqTTbLA/37uEEhRCz1qa8ORtO8kxLDVnc2BP3Gn9kCedTcZagMjtIR4qhJmv5EqcmpJi1l9AfNU98a238kVmcTeV530KQMzCPExQyWoPXtKLFHDP//NhckOsbf2QyZzMEDLSQ5HOxkRMUInYjw3AdqyOfkxNS8nGusXdujZUxEeS0LGN3HsfZDMWCWx3utWBBmhAxg+cBEaSHWaaFbhZDFqy+GmasD/cGcIJCg9ml6SmcmhAzziyK3NhEkDNON/7AC5zLkGB9uMfQU1gw/sMaxxZOTYhZZLZD7mIiyGX/wcLlYedji5t7lbGMExQCfjVZv2s5NaFmv8nJgP6YeeJbodEH+nMuQ8TjFnvkhtjJCVKekSarN5RTE8lvPvow87563CGHnny0s5DkW3jvUnnMStGwiUDYucZZXWRxgrEhDOFMhoptqGchycM5QUqzG+UN1602/5SGntbOBDnzZGMXfpkzGTJ+RkVTQU7HfE6Qwph1mmYZ3PDTwnhtXzcR5PT/GZvCaM5k6HjLYo9ch9VJFMYsW/UTTk3oqW28ti+ZNXGqYWwK7EccRh60kOSO/PqrKIWoA+Oai+zuEnb2mGRAaQ+bCHL8KmP3/YZzGUL2m9ZgFRAYxQlSkp9Z5S2ymLZyutlsh9zF+APrOJehZB1qWBQcWsgJUpAXTdbrVU5N6HnOrADnuWZZFs8Zuy4LmoSVHKSbSnJ95iQrSEuT1fqNUxN6LjUOWOSV/YfZDnm+cVNMEr2/ygICnTk9irHd5A8ofTD8/GLmh/NM5DjrJOOu0x05lyEmH9dZSPIbnCClMKtq3ZdTE3o6mXlhP7OAxeW8sBlFNpvVYYVABfzECVKGj3COyTp9yckJOfNNfVCvbRawGMkut9HkC4uCQxezCaoSbMGtFkWh2Ng03Bw0z3haZlKePvtYbbNxl9u9nM/QY1Vw6BFOjwJ/Mmtb1h8h4aav+eo+6DBg0YGzGQHyzC5tQkDH55ygANmO+yzEWEDgTU5SqLEoibsj7VQzQX6Nxz5RZg2qmTp8NgufB8ZMk5t5vAcQFRZYNY143CzD4jix1bgQDV01KkyzcPnbOD0BsAXdE4qxwJWcqBCzEFnma7u17Glm/aabGn+kHWc0QvSwcPt3OT0+M8XiHmXR8TSnKrTMR1Wrtb3DtFOIPs74IxM4pxFij0UT1KrYwAnyjVW4yZYYCwh8x+kKKVMtiuAK6Dmxo80L0+8wvjTNMo1R+4udblEBjvjBPgxBBdtyXJ2FC0JJIYZYJJsKaLvKpZvvj682/tDNnNfIMdDCSKZyejxnpmU3l9KjK6cshGxBxwTrqt0QM0e8xLhiqnAAl5kaSU1+I/KU3xK6aenxAactdHxlmVUuIKANjVkhfjO+VstqYFHkJ5OebQICt/NOmEfswACTJvBWI51/IkPGHvS2DFUICIgpsWMs5DhenjHF1OIFC2NpwHYE0inAZGQ7FmMBgeacvFDxBS5MuKbajIzjLffH+l3GHxzL+Y0oebjawmDi6MP6FhKZgcZJibGAwLOcvtCwDb3srOmcrJNi1mhTjT+6inMcWZYk+Pp8IWZzkiSwEG2SFmMBwf7godnijEZ1Oyv6dfzfCeQ46zhtl9FH63GWI82AhMZzH29puvyj19GVGAtUQR6nMQTk2P0O9K5pb5Ai++OLjT/8KOc50uy1Ee2qhlGUhKRYhrsRdynHAndwIkOw0u3trufzsaNiidEHGn/8U851xPnElhldhC84VQ5dtLvF9RsnYzwnU2nWoZfNldbyROeYPcRM43QbprxFn1ts79RWc7Jshik6S9gZ/zU46+qSi0H271v+kVbXphzHyohtRo9oxRlPAdZaFQYsNjIxAFs5YZbMRcfEGagOxsWcUkXZhIG2PUdATDat6WY/B3kwZz0lGOFAICpjEHZwygwowExcK1GKD43enFgF2YC+liWDSoy9FhXdDI/02ho/6BPOfEqQh4sciUQNjMQ+TlsR9mCsRQ09N2MaJ1cx1qGfEzGG9pWoGHOGeM74USzFmCpMcywUdTCKF0cAAL+jL6p4IsYCOpMOlWIt+iHTyQpuF/fayqoosUP+yuhhtTj/KUSLpDJk++HPlA5S5KCT1IhxydGYhqkMq9HLaR2SyeXOiiXB0WI3q1ikOvOSlIwK6J6Stzk3YDjqeyjFjCCrxDJ0dZrE+LPeOJYc5dKNHzmE65BSJH+jLAN34hsUpsg87cd7aCsxrY0RZLX5xXlGea7okXVcLFn0xrwUQoClLi8yNMLrEc9bL8Bc9LLo280IctSY7zwkdVB7wUGCm2EE+U7jRy/leqQY97uWkMroie8jOTeL8Rjq+CbFjCCrIMZtna5YoZiYnhFziz7Y+PG8pZdqrLMoWu9kXITnIxNXLsQPeNphWiAjyGFf85lo5ny9PtVqxmQg3jQuKUNSjwckft1ugbGh7nRxELPxiO+74qLjPRqk7+RjSjKVq79OuyQmC/G50Suu4NqkIL9JPqxKRxu8Errd8jpMQBdUDVCKWYs8CArwES5xvk7f6E1jMhE/Gb3mFq5PSnK7R9HQp7BQ+Vb2e/AF+qFR4EJ8aFRPmbwVVcIUTZyv0hxxWUw2Yq3Rq3pyjVKSeR5KTGW0xXAsVk5odiEHg9BSUgRd1uhAY/SNHFwV/M74iCBvN3pdH65SitLEc6nJxt14HQsD7m19AD/gDTyIRp7etUt+sJOeX2J8tTpiHIvFYlqe0SsHcqVSlDd9k5wMNMUjmIRfcMC33y4X8/AmeuEqp9dgfR8zaYo+iHES2RTfaFfEvEQUGr32Sa5WirIHWb6LTzoa4jY8hSlYLD0zYx+WYybG4BFcj2zFRbjo2ExT9JSv0dJ57lCOhzvjI4Kcz4vTpCj3BSxFlXApOuAhDMUEfIr5WIEttg4EC7Adq7EQn+FtvIj+uAvNUStEEly84zfxjhXooqYYx2KxmDhg9PpnuGop/EVORYk6B9VRHw3QFFejLdqiLZoeHpehPqo7K4uo/OhMM/SIDXjAcXKnNkM7P+YXYqvRj9CLK5eyFAR6HYKD31C9C8cNcVRcXkAUalP12jE/0VYwD5kUpzclMeDxIY1Q+jZjAmo6W4UCbWpadsxvxLdGP0wzrmAK8wUlMeCxjEYolcVO+x0WiLe0SrEgEJONW/SQ1GU/KlEUAxzpPiYCRp9c9HMWNS7Upmo1YkGhPWX8Y23iSqYwHSiLAY6GNEBJ5GOUw6ok2owAwhTFym/exm4FpCRDKYsBjltpgFJY4vTix8fxc2NBo9c2/uH6cz1TmBzKYoCD17JkhN2GOKpOoueIhjEVyDpO7Ge/AlKc3T51jeMwGu/SAF0yz1khTZn1jCUc631j/GMu5LqmMMxFDm7Mo/m5YA96OikYtciDEpouBbmv8Y96H9c2hbmewsjS9CFkERraP8Bbo98WOzqmGuI84x+3IgucpDAPURgDG3tofkmRh+H2q/jlih5l/xFTkqPESuMfuivXOGUZTGEMaFSh8SXFGtv127Q87YWyp8XURetv9qN/xXVOUV6mNAY0LqbxJcEkVLY7w1/Eq8bUJi1uXIRToB62cq1TkjcpjQGN62h8DjmAfnZnd6XWIhYGxESzX6EpI1oUZA4fxz00PkesR3N7M7tP9FE1alx6j5xt3DlEQKATDnLVU45XKI0BjcdofA6YY7cPzCw9MxYmxNvmv0wrBi5SjhcojQGNoTQ+mxRgiL0LTNvEvbGjYuFCCLHP/Feqh6Vc/5SiH6UxoDGKxmczcny3vRmdmP6/WBgRPa1+rQwMCrhxO/GT2ymNAY3xND4bbEMrO7O50adOeB7lI89OlJCTQ0tIEZpRGgMaU2h8CVmJBnbmcpp2ZizM6JrYlOiXbImZKKRFRJ7alMaAxgc0vgQstHOQt1O/LRZ+tIu1vMQm0wQTsIt2EWHyWO0tsPEezc+SaXY6jM/W9Fg00NuJAjtmUxFdMRt5tI9IsoLCyJCFkkxFeqIZLBTPZx8biw6is3lOcslRGZ0wHhtpJxHjAwojqyEryOTEcpwb5mM8813yQScmFMeV6IOp2ECLiQhPUxgDG2/Q/Ex4L7EcL0yLx6KI3lhsTcaY6qIzhmIm1tN6Qk1HCmNg4yWanyETEp9rvJxxfCyqpMXF927MqjraoCdGYiZWMtIcOtgvJLjxFM3PgPGJuoDk63fFok32saKvWRU4p+McNEUXDMJ4zMRi7KZ9Kc1KymKAoycNsBQfJtod745g5Nikm8h3XhjduWiGzhiAUfgIC7Cee2ilYKW3IEd7GmAJvk2U6LZOqxlLGY4Wd2hrvDbCOGqjGW5DHwzHFMzFakp0gNwZLgnbJ9aJJdp8bYaYoo8TI8QoMVFMFBPFFG2GvkAs0dZYVWlRb7Dfe3GW4xzrGfshvVwstcg4XtwhVvlrlumoizbojucwCd9QoH2kADXVlKrdYomYLd7WXtAf0TrqTeMXpmWVO8tehdvMk+MV0uqK5vpd2tPibTFXbFBXkLN4E7YIG3GB5WxpX2X8K5aKZB+rdRK/BGemhwT6PgzFh/gZe2mpHn5BVESa9oif9Q/1F/X79ZbxWhX+KzkYd4KeqV+q36IN0MaKOYlLBvg51tIID7MbV1rP1RdZJ8VSGe18baTYEbzJ6rgA7dAb47CAl7gl80hgq6rt0uZrY0VPvbVe2++SifF/x2uJ6/RHxBgxR9scrHXPoBECAPLQ1tpeZpx1YoycdaJ+o/hI7FVnR1EPt2AwPsJq2rAEJ/A5YLFVz9FGat3FZboWK6PMYfYp8VriOu1h8Zr4Uqy1f3OVJerlUYjuCWq5haYhk0+yfLU2UqxTK/5WEx0xBF8gl/acJLP8WKeD4gcxRuuedol+RihyjU5Iy9Kbiq7aUDFNLPP+iLADzRDAM9a746kRvgTigjLxqloX8aZYrdrRSAM8iMm8zO2YW71bk23iCzFE3KzVyDou5Ifcp+vVtCb6baKvGCU+Fj+JXLkzVZldLDHBOmSZw91xohhcmnaD9rQ2Q2xRTZh7YArLH9lkpfyym6vF+6KfaC5ExL8vZooG2jVaJ/0BMUgbKSZqM8RsfYFYJlaKXJErcrVdRbJFcrU14jfxg77A7BvmvJT/nlaqakXRGpRLyp5GxbVNern4VaKXNlabL3aqlN05CPNRQM314UBPyxM/izf1B+KNzv4P/cEyGNLeeAYfT2krXIQso6KaBw7/1/po/3H3WpwbiTvEk2KiNl+FvXMtPIiPsYfKa8hWVHIzuyv1D8Ugra2ozuieXcqdZXxgeB7yU9YKl6K6WZ3j3aJQ7NRq0G5kxd7+pZ8jmotu2gvaVPGT2B2ULGeiEz5inK4UvZ3O5AbxjXhLPK7fop2foun57hNJfzSe229SNmh2rnVOzqW0Gc9IOzVeNX6V6Cwe18aKL8XvR76U+DKqoTtmpvBOpCS/I8Nsrv4Qv+oL9AXaDDFBH6b117poV6ZV5rGKlKBFP+M5vzMlbXAd6lr3AulAi/E1Z0M7U5yntdDu04ZqU8VPYo/3snw+BjMXAwBwm9kcLVYnPziCm5Iss5upq1LOAjegvrW39qG9BB2D/p9eW28tHhTDxcdiiVcZoOm4HTkpXkHgC/MUo1a0wyCCFg+nmAWuQQNrP32NGwPldtC6pl+qddFeEJ+I3+01Y3WSIDc8ZS+U7DAvSf9T7CganqdBi3uMZ748/kghC1yNetb++UmkGpdGkbNOjNfSOopntRlio7yU/IHYlIKCfK/5nDSnpXksyKeYhea6pYz9/ZqoR833mSfTUkIV2tCuEL21qTLKKlZE3xSLKr9nPhszaVs+BC1GmlUJ/zEl7O/nRPVTlon/o5WEVZrLaddoT4tvtTw3olwe3VPmUOUn8+zjfP0cWpT3lEs3a5XWPgXs7xtUs/bGVSlXgD6KZJ0kLtMH6jnJp9JloEcK1I/70+LLov4i7cgf9HFma/BlxO1vKipY++H69AzaR4Q445/61eLlZIsfRV2Ud6GZxc27FC/+7SPx8uKg8SrUjfS90tEJaqdom9OyaB3R3INUEz3E7GS6aGegO1ZG0h32oI1FEj7vRPlqny+arcSgiIpxIZ5I5Hvb07JpGdE+PjlT3Cu+cV5wPAP3Y1nEHGI3WloVOBxGa/H17ON/ZqW40vFTBOV4t/lFpCPXpOO1aBepYfzlxL16jvO2UTdHqMLAJqtgBcQPvBjt+x75UbPVaBq5uiu/45JE/vYnD5RTbbdcU3vFtMBRoblzfBiB+hdLrHv57oiXp334f9oh1putyMBIyfGsRHkVEOu0SrSIVDxM+bd+t0Ev7ULroMb5GIrNIXaI6Ub1ZouWAm9Gywhkj3yj+bezzyMTOX4xcROEP5hZkdKIhuL9ohJsJ4e5PLqEsv7FPvSDbn2y3Z0WEZglfmLeLTIKl5VycXPi4OBSXaMlcHdyjph4uDpGvv0qGZdjdKjqX/yAixP9Ti/RFgIUZGFeJfxa7Au5HM/BeYl9ag67zJDDpFXWxmp5TmvKpaNtKMrd70C/0p3KSu6OJ8WOph0EKsndzFenc4hbkOVjSELrExDvnXUibYAUjSqX115J5tp1TfTDd8qGMAowHjUS/xZTYsfQAgLmaDHXfIWeDG1WRQs7eUzDuB0gBpRLF6OTq4VRB/2Ua6VagI8SJxlBQExhLzwVSM8Q281XaVzoxLgAr6BiYusrFD259sQqmjci2QJFddAHX2K/Ekd4ExKV/f5rjOHuWJnzjJZW2fBjQyXHf1jdBv07VLZLu4brThLulPVXxf7ky3i2xWisDcwVfsMgO2GKQ+MJdmNQSpJftJLkN0MixgcxzFYfc21FWmWuObH3BfJ/oq/Y6qaU5yV4CO/jTx8dYT1es7wWXWLsZ+tI1cg4Xl9gJcljQiDHOfYCZRCfpJ3KFScOyDxZu09b47bw/UXoibex1MN7fgX4CS+jeYI845J3osR5XGElQ2aWzRZ6IU9hMf4T3e1ZYaH2FA/ySBJkH6u3szr/dtImqiX6YzIWY68k88/DTxiHLvYDFH/vtT7MOJ1rqyZp2douq7Vrj11KivEeDEcVe/a3RW/KdSaunES8JvbK6uCnox46YCDGYCaWYIcjs9+PFZiJ19ADV6F8cu/fp9/NyLHKaE2sj5WvwK/KRY3HINum/WlfsRMIkUDZ0/T7xa9yO14fGlVwCVqiE+7HY3gRwzEa4zEeUzEe4/E6huMF9ENXtEdTnOcsLGE0vtQzuZbKBy5uT/Rt6y1lxDgPU+xm9EAU6I8xq4fI4yjtIjHG/Jqr4iNXv41745BIcq9Eq9lZgcv7BzDevhhDrI434soS+Xvlf+ittBnOy90HOg6KEen/49qFKHBxX6I1rY7xAV5G2oNRFn0ZDcbEsqdxVYlnlEvXHhaLQiHGBdqkeAWuWOh2yfck/qN/NX4IQIx/RR9UdWKBa7UruZ7EB+IVFJflAjEhvQrXKaSS3DlxBUIdt/nY7OkgpqGt05OM18UpXEviqyyLB8WsZK9cezZ2iOe5Mw65JDezToL7S5RvwULPS8zPx8Oo7tQGf9Eu5iqSYJznFNFGjBGbVBBjbb7WJfNkrkn40c8Rf9hb8yswFjs9KaG5AE/iQudWuFv0zDqOK0iC5ai0bO0+bapV7S5Px0rxBGsEREqSzxBz7F8/uhtTpV0dycVUdE3i4pGAgJgcT+PaEXU4Oi1bu0+8J9b5dnQ3X3+UPXujSMbx4jknWT0V0B6v4vukr1n/gcnohUuTz3r/VruIq0YUpezZopn+mJgutniU0LZIe0G7hklFEQ+IXWbendq88mBrDMCbmJOwyNU+/IYcjMFDaOksf6L0WKa3ZLY7CcdO53TRUNyhvaDNEH+4OwLUNou54mX9tngtlpdPIet5L3mLqYjz0RQdcC96HRl3oRPa4vJkgxJGJavuyD6WK0XCyDHxtPiFWlvRSzyvvSE+Et+IZWKLwZn6XpErVovvxMfaG+I50VNvpdWM/5vTl6L75OvEWkUTLH8Tt3NzQKLpdieknZp2atqp/OpHSpJ5sva0OKiYGP+kt2ONCkJISpJWWXysiBQXiul609hRXBNCSCp/i6qjTQ24nsp2MSItiytBCCGxWEzUER8FIsoFYpbW8awTuQKEEFKE9AwxyNfboT+LvmlxzjshhBjvlE/QbxSzRL7Hu+JvRe94Vc42IYQk3iv/T79NfOJBBkaumCjas5o2IYQ4JO1UvaX2gliUuHBnwrFKe0PckV6FORSEEOIujHFK/Cr9UTFBLBYHHIjwHm2+eE27T29c7izOISGEyOYYPVNcpt+kPyCe1ceJ97UZ2gztK32BmKvNEJPFeDFCPKHfpV+t1dTP4GQRQghJYf4fTci7RwYvH54AAAAASUVORK5CYII=")] + +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} From fd24d0a43527172a54abd61ec2db0a3880f0d75a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Nov 2022 12:25:58 +0100 Subject: [PATCH 162/482] fix a comment in UnsafeCell::new --- library/core/src/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index e6a11218139d9..f2975d054572c 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1936,7 +1936,7 @@ impl UnsafeCell { /// Constructs a new instance of `UnsafeCell` which will wrap the specified /// value. /// - /// All access to the inner value through methods is `unsafe`. + /// All access to the inner value through `&UnsafeCell` requires `unsafe` code. /// /// # Examples /// From 338b91493f40fb1811971b09c4b3c6ac5c4ef5ee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 Nov 2022 17:22:25 +0100 Subject: [PATCH 163/482] Migrate test-arrow to CSS variables --- src/librustdoc/html/static/css/rustdoc.css | 6 ++++++ src/librustdoc/html/static/css/themes/ayu.css | 16 ++++------------ src/librustdoc/html/static/css/themes/dark.css | 13 ++++--------- src/librustdoc/html/static/css/themes/light.css | 13 ++++--------- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index c4d50ff6cbc96..66e48ba8cf1ab 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1204,6 +1204,12 @@ a.test-arrow { top: 5px; right: 5px; z-index: 1; + color: var(--test-arrow-color); + background-color: var(--test-arrow-background-color); +} +a.test-arrow:hover { + color: var(--test-arrow-hover-color); + background-color: var(--test-arrow-hover-background-color); } .example-wrap:hover .test-arrow { visibility: visible; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 762384481e695..4b88c42f2df05 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -59,6 +59,10 @@ Original by Dempfi (https://github.com/dempfi/ayu) --example-line-numbers-border-color: none; --src-line-numbers-span-color: #5c6773; --src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06); + --test-arrow-color: #788797; + --test-arrow-background-color: rgba(57, 175, 215, 0.09); + --test-arrow-hover-color: #c5c5c5; + --test-arrow-hover-background-color: rgba(57, 175, 215, 0.368); } .slider { @@ -172,18 +176,6 @@ details.rustdoc-toggle > summary::before { color: #788797; } -a.test-arrow { - font-size: 100%; - color: #788797; - border-radius: 4px; - background-color: rgba(57, 175, 215, 0.09); -} - -a.test-arrow:hover { - background-color: rgba(57, 175, 215, 0.368); - color: #c5c5c5; -} - :target { background: rgba(255, 236, 164, 0.06); border-right: 3px solid rgba(255, 180, 76, 0.85); diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 1424de5137cce..8edd8fee78d0b 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -54,6 +54,10 @@ --example-line-numbers-border-color: #4a4949; --src-line-numbers-span-color: #3b91e2; --src-line-number-highlighted-background-color: #0a042f; + --test-arrow-color: #dedede; + --test-arrow-background-color: rgba(78, 139, 202, 0.2); + --test-arrow-hover-color: #dedede; + --test-arrow-hover-background-color: #4e8bca; } .slider { @@ -94,15 +98,6 @@ details.rustdoc-toggle > summary::before { filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%); } -a.test-arrow { - color: #dedede; - background-color: rgba(78, 139, 202, 0.2); -} - -a.test-arrow:hover{ - background-color: #4e8bca; -} - :target { background-color: #494a3d; border-right: 3px solid #bb7410; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index a7ce56c95c7e4..797be8754f8d3 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -54,6 +54,10 @@ --example-line-numbers-border-color: #c7c7c7; --src-line-numbers-span-color: #c67e2d; --src-line-number-highlighted-background-color: #fdffd3; + --test-arrow-color: #f5f5f5; + --test-arrow-background-color: rgba(78, 139, 202, 0.2); + --test-arrow-hover-color: #f5f5f5; + --test-arrow-hover-background-color: #4e8bca; } .slider { @@ -89,15 +93,6 @@ body.source .example-wrap pre.rust a { filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%); } -a.test-arrow { - color: #f5f5f5; - background-color: rgba(78, 139, 202, 0.2); -} - -a.test-arrow:hover{ - background-color: #4e8bca; -} - :target { background: #FDFFD3; border-right: 3px solid #AD7C37; From f0c33e4958b0fe212afbcc80e974ce91693401a2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 Nov 2022 17:22:38 +0100 Subject: [PATCH 164/482] Extend GUI test for run button --- src/test/rustdoc-gui/run-on-hover.goml | 55 ++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc-gui/run-on-hover.goml b/src/test/rustdoc-gui/run-on-hover.goml index 6c785e1c4bbab..57d63049f28ca 100644 --- a/src/test/rustdoc-gui/run-on-hover.goml +++ b/src/test/rustdoc-gui/run-on-hover.goml @@ -1,7 +1,54 @@ // Example code blocks sometimes have a "Run" button to run them on the // Playground. That button is hidden until the user hovers over the code block. -// This test checks that it is hidden, and that it shows on hover. +// This test checks that it is hidden, and that it shows on hover. It also +// checks for its color. goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" -assert-css: (".test-arrow", {"visibility": "hidden"}) -move-cursor-to: ".example-wrap" -assert-css: (".test-arrow", {"visibility": "visible"}) +show-text: true + +define-function: ( + "check-run-button", + (theme, color, background, hover_color, hover_background), + [ + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + ("reload"), + ("assert-css", (".test-arrow", {"visibility": "hidden"})), + ("move-cursor-to", ".example-wrap"), + ("assert-css", (".test-arrow", { + "visibility": "visible", + "color": |color|, + "background-color": |background|, + "font-size": "22px", + "border-radius": "5px", + })), + ("move-cursor-to", ".test-arrow"), + ("assert-css", (".test-arrow:hover", { + "visibility": "visible", + "color": |hover_color|, + "background-color": |hover_background|, + "font-size": "22px", + "border-radius": "5px", + })), + ], +) + +call-function: ("check-run-button", { + "theme": "ayu", + "color": "rgb(120, 135, 151)", + "background": "rgba(57, 175, 215, 0.09)", + "hover_color": "rgb(197, 197, 197)", + "hover_background": "rgba(57, 175, 215, 0.37)", +}) +call-function: ("check-run-button", { + "theme": "dark", + "color": "rgb(222, 222, 222)", + "background": "rgba(78, 139, 202, 0.2)", + "hover_color": "rgb(222, 222, 222)", + "hover_background": "rgb(78, 139, 202)", +}) +call-function: ("check-run-button", { + "theme": "light", + "color": "rgb(245, 245, 245)", + "background": "rgba(78, 139, 202, 0.2)", + "hover_color": "rgb(245, 245, 245)", + "hover_background": "rgb(78, 139, 202)", +}) From 5b86c72e77ebc5e350310b2698604a4f040ceb78 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 17:54:06 +0100 Subject: [PATCH 165/482] Simplify code --- compiler/rustc_interface/src/proc_macro_decls.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 4c236c693d0fe..9bf7778bfb29c 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -4,21 +4,16 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { - let mut finder = Finder { tcx, decls: None }; + let mut decls = None; for id in tcx.hir().items() { - let attrs = finder.tcx.hir().attrs(id.hir_id()); - if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) { - finder.decls = Some(id.owner_id.def_id); + let attrs = tcx.hir().attrs(id.hir_id()); + if tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) { + decls = Some(id.owner_id.def_id); } } - finder.decls -} - -struct Finder<'tcx> { - tcx: TyCtxt<'tcx>, - decls: Option, + decls } pub(crate) fn provide(providers: &mut Providers) { From 1015226040f8b86c523f5267ad5110af5b2c73d9 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 17:54:15 +0100 Subject: [PATCH 166/482] Add internal descriptions to a few queries --- compiler/rustc_middle/src/query/mod.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 33acaed435b89..00242e7eed775 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -271,6 +271,10 @@ rustc_queries! { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } + /// Look up all native libraries this crate depends on. + /// These are assembled from the following places: + /// - `extern` blocks (depending on their `link` attributes) + /// - the `libs` (`-l`) option query native_libraries(_: CrateNum) -> Vec { arena_cache desc { "looking up the native libraries of a linked crate" } @@ -1539,6 +1543,7 @@ rustc_queries! { desc { "available upstream drop-glue for `{:?}`", substs } } + /// Returns a list of all `extern` blocks of a crate. query foreign_modules(_: CrateNum) -> FxHashMap { arena_cache desc { "looking up the foreign modules of a linked crate" } @@ -1550,9 +1555,12 @@ rustc_queries! { query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { desc { "looking up the entry function of a crate" } } + + /// Finds the `rustc_proc_macro_decls` item of a crate. query proc_macro_decls_static(_: ()) -> Option { - desc { "looking up the derive registrar for a crate" } + desc { "looking up the proc macro declarations for a crate" } } + // The macro which defines `rustc_metadata::provide_extern` depends on this query's name. // Changing the name should cause a compiler error, but in case that changes, be aware. query crate_hash(_: CrateNum) -> Svh { @@ -1560,17 +1568,24 @@ rustc_queries! { desc { "looking up the hash a crate" } separate_provide_extern } + + /// Gets the hash for the host proc macro. Used to support -Z dual-proc-macro. query crate_host_hash(_: CrateNum) -> Option { eval_always desc { "looking up the hash of a host version of a crate" } separate_provide_extern } + + /// Gets the extra data to put in each output filename for a crate. + /// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file. query extra_filename(_: CrateNum) -> String { arena_cache eval_always desc { "looking up the extra filename for a crate" } separate_provide_extern } + + /// Gets the paths where the crate came from in the file system. query crate_extern_paths(_: CrateNum) -> Vec { arena_cache eval_always @@ -1594,6 +1609,7 @@ rustc_queries! { separate_provide_extern } + /// Get the corresponding native library from the `native_libraries` query query native_library(def_id: DefId) -> Option<&'tcx NativeLib> { desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } } From 8a1a3aad01b79e1be7d277128f14b293fa1d29e0 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 6 Nov 2022 01:22:31 +0100 Subject: [PATCH 167/482] Add more nonsense to weird-exprs.rs. --- src/test/ui/weird-exprs.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs index 4066bcf3badd7..d65703ef5cae3 100644 --- a/src/test/ui/weird-exprs.rs +++ b/src/test/ui/weird-exprs.rs @@ -8,6 +8,7 @@ #![allow(unreachable_code)] #![allow(unused_braces, unused_must_use, unused_parens)] #![allow(uncommon_codepoints, confusable_idents)] +#![allow(unreachable_patterns)] #![recursion_limit = "256"] @@ -194,6 +195,15 @@ fn bathroom_stall() { assert_eq!(i, 13); } +fn closure_matching() { + let x = |_| Some(1); + let (|x| x) = match x(..) { + |_| Some(2) => |_| Some(3), + |_| _ => unreachable!(), + }; + assert!(matches!(x(..), |_| Some(4))); +} + pub fn main() { strange(); funny(); @@ -216,4 +226,5 @@ pub fn main() { 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎(); function(); bathroom_stall(); + closure_matching(); } From e774f96e3ab07cb7ee4f475bda0034ed5e3f9cb0 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 29 Oct 2022 18:03:47 +0800 Subject: [PATCH 168/482] Lint against usages of `struct_span_lint_hir`. --- compiler/rustc_middle/src/ty/context.rs | 5 ++++- compiler/rustc_passes/src/lib.rs | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e039436fe0afa..fc706b890d5fb 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2813,7 +2813,9 @@ impl<'tcx> TyCtxt<'tcx> { span: impl Into, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.struct_span_lint_hir(lint, hir_id, span, decorator.msg(), |diag| { + let msg = decorator.msg(); + let (level, src) = self.lint_level_at_node(lint, hir_id); + struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { decorator.decorate_lint(diag) }) } @@ -2823,6 +2825,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] pub fn struct_span_lint_hir( self, lint: &'static Lint, diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 15f60f626c89a..6e621b7eb5eb0 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -5,8 +5,6 @@ //! This API is completely unstable and subject to change. #![allow(rustc::potential_query_instability)] -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(iter_intersperse)] #![feature(let_chains)] From 299420b46dd374fb0c791d24236e4383b3f46be5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 00:38:43 +0000 Subject: [PATCH 169/482] Use codegen_select in vtable_trait_upcasting_coercion_new_vptr_slot --- .../rustc_trait_selection/src/traits/mod.rs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3417bb87c2049..a33534f5747fa 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -900,25 +900,13 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( def_id: unsize_trait_did, substs: tcx.mk_substs_trait(source, &[target.into()]), }; - let obligation = Obligation::new( - ObligationCause::dummy(), - ty::ParamEnv::reveal_all(), - ty::Binder::dummy(ty::TraitPredicate { - trait_ref, - constness: ty::BoundConstness::NotConst, - polarity: ty::ImplPolarity::Positive, - }), - ); - - let infcx = tcx.infer_ctxt().build(); - let mut selcx = SelectionContext::new(&infcx); - let implsrc = selcx.select(&obligation).unwrap(); - let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else { - bug!(); - }; - - implsrc_traitcasting.vtable_vptr_slot + match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { + Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { + implsrc_traitcasting.vtable_vptr_slot + } + otherwise => bug!("expected TraitUpcasting candidate, got {otherwise:?}"), + } } pub fn provide(providers: &mut ty::query::Providers) { From c183822d0e2f09929544e9db8d125cb4dc0a4821 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Jul 2022 01:53:53 +0000 Subject: [PATCH 170/482] Enforce Tuple trait on Fn traits --- library/alloc/src/boxed.rs | 31 +++ library/alloc/src/lib.rs | 1 + library/core/src/intrinsics.rs | 66 +++++++ library/core/src/ops/function.rs | 321 +++++++++++++++++++++++++++++++ 4 files changed, 419 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index b7e7d5a38a5b1..66f4c19e0f91a 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -158,6 +158,8 @@ use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter::FromIterator; use core::iter::{FusedIterator, Iterator}; +#[cfg(not(bootstrap))] +use core::marker::Tuple; use core::marker::{Destruct, Unpin, Unsize}; use core::mem; use core::ops::{ @@ -1979,6 +1981,7 @@ impl ExactSizeIterator for Box FusedIterator for Box {} +#[cfg(bootstrap)] #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> FnOnce for Box { type Output = >::Output; @@ -1988,6 +1991,17 @@ impl + ?Sized, A: Allocator> FnOnce for Box { } } +#[cfg(not(bootstrap))] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] +impl + ?Sized, A: Allocator> FnOnce for Box { + type Output = >::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + >::call_once(*self, args) + } +} + +#[cfg(bootstrap)] #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> FnMut for Box { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { @@ -1995,6 +2009,15 @@ impl + ?Sized, A: Allocator> FnMut for Box { } } +#[cfg(not(bootstrap))] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] +impl + ?Sized, A: Allocator> FnMut for Box { + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + >::call_mut(self, args) + } +} + +#[cfg(bootstrap)] #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> Fn for Box { extern "rust-call" fn call(&self, args: Args) -> Self::Output { @@ -2002,6 +2025,14 @@ impl + ?Sized, A: Allocator> Fn for Box { } } +#[cfg(not(bootstrap))] +#[stable(feature = "boxed_closure_impls", since = "1.35.0")] +impl + ?Sized, A: Allocator> Fn for Box { + extern "rust-call" fn call(&self, args: Args) -> Self::Output { + >::call(self, args) + } +} + #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index ce36b116f139b..008926666c136 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -150,6 +150,7 @@ #![feature(trusted_len)] #![feature(trusted_random_access)] #![feature(try_trait_v2)] +#![cfg_attr(not(bootstrap), feature(tuple_trait))] #![feature(unchecked_math)] #![feature(unicode_internals)] #![feature(unsize)] diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 1dc79afe83fdb..bfbd4301230ae 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -55,6 +55,8 @@ #![allow(missing_docs)] use crate::marker::DiscriminantKind; +#[cfg(not(bootstrap))] +use crate::marker::Tuple; use crate::mem; // These imports are used for simplifying intra-doc links @@ -2169,11 +2171,75 @@ extern "rust-intrinsic" { /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, /// which violates the principle that a `const fn` must behave the same at /// compile-time and at run-time. The unsafe code in crate B is fine. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] pub fn const_eval_select(arg: ARG, called_in_const: F, called_at_rt: G) -> RET where G: FnOnce, F: FnOnce; + + /// Selects which function to call depending on the context. + /// + /// If this function is evaluated at compile-time, then a call to this + /// intrinsic will be replaced with a call to `called_in_const`. It gets + /// replaced with a call to `called_at_rt` otherwise. + /// + /// # Type Requirements + /// + /// The two functions must be both function items. They cannot be function + /// pointers or closures. The first function must be a `const fn`. + /// + /// `arg` will be the tupled arguments that will be passed to either one of + /// the two functions, therefore, both functions must accept the same type of + /// arguments. Both functions must return RET. + /// + /// # Safety + /// + /// The two functions must behave observably equivalent. Safe code in other + /// crates may assume that calling a `const fn` at compile-time and at run-time + /// produces the same result. A function that produces a different result when + /// evaluated at run-time, or has any other observable side-effects, is + /// *unsound*. + /// + /// Here is an example of how this could cause a problem: + /// ```no_run + /// #![feature(const_eval_select)] + /// #![feature(core_intrinsics)] + /// use std::hint::unreachable_unchecked; + /// use std::intrinsics::const_eval_select; + /// + /// // Crate A + /// pub const fn inconsistent() -> i32 { + /// fn runtime() -> i32 { 1 } + /// const fn compiletime() -> i32 { 2 } + /// + /// unsafe { + // // ⚠ This code violates the required equivalence of `compiletime` + /// // and `runtime`. + /// const_eval_select((), compiletime, runtime) + /// } + /// } + /// + /// // Crate B + /// const X: i32 = inconsistent(); + /// let x = inconsistent(); + /// if x != X { unsafe { unreachable_unchecked(); }} + /// ``` + /// + /// This code causes Undefined Behavior when being run, since the + /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, + /// which violates the principle that a `const fn` must behave the same at + /// compile-time and at run-time. The unsafe code in crate B is fine. + #[cfg(not(bootstrap))] + #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] + pub fn const_eval_select( + arg: ARG, + called_in_const: F, + called_at_rt: G, + ) -> RET + where + G: FnOnce, + F: FnOnce; } // Some functions are defined here because they accidentally got made diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 2e0a752c815d9..7c93fd30d4ec1 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -1,3 +1,6 @@ +#[cfg(not(bootstrap))] +use crate::marker::Tuple; + /// The version of the call operator that takes an immutable receiver. /// /// Instances of `Fn` can be called repeatedly without mutating state. @@ -51,6 +54,7 @@ /// let double = |x| x * 2; /// assert_eq!(call_with_one(double), 2); /// ``` +#[cfg(bootstrap)] #[lang = "fn"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Fn"] @@ -78,6 +82,87 @@ pub trait Fn: FnMut { extern "rust-call" fn call(&self, args: Args) -> Self::Output; } +/// The version of the call operator that takes an immutable receiver. +/// +/// Instances of `Fn` can be called repeatedly without mutating state. +/// +/// *This trait (`Fn`) is not to be confused with [function pointers] +/// (`fn`).* +/// +/// `Fn` is implemented automatically by closures which only take immutable +/// references to captured variables or don't capture anything at all, as well +/// as (safe) [function pointers] (with some caveats, see their documentation +/// for more details). Additionally, for any type `F` that implements `Fn`, `&F` +/// implements `Fn`, too. +/// +/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any +/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`] +/// is expected. +/// +/// Use `Fn` as a bound when you want to accept a parameter of function-like +/// type and need to call it repeatedly and without mutating state (e.g., when +/// calling it concurrently). If you do not need such strict requirements, use +/// [`FnMut`] or [`FnOnce`] as bounds. +/// +/// See the [chapter on closures in *The Rust Programming Language*][book] for +/// some more information on this topic. +/// +/// Also of note is the special syntax for `Fn` traits (e.g. +/// `Fn(usize, bool) -> usize`). Those interested in the technical details of +/// this can refer to [the relevant section in the *Rustonomicon*][nomicon]. +/// +/// [book]: ../../book/ch13-01-closures.html +/// [function pointers]: fn +/// [nomicon]: ../../nomicon/hrtb.html +/// +/// # Examples +/// +/// ## Calling a closure +/// +/// ``` +/// let square = |x| x * x; +/// assert_eq!(square(5), 25); +/// ``` +/// +/// ## Using a `Fn` parameter +/// +/// ``` +/// fn call_with_one(func: F) -> usize +/// where F: Fn(usize) -> usize { +/// func(1) +/// } +/// +/// let double = |x| x * 2; +/// assert_eq!(call_with_one(double), 2); +/// ``` +#[cfg(not(bootstrap))] +#[lang = "fn"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "Fn"] +#[rustc_paren_sugar] +#[rustc_on_unimplemented( + on( + Args = "()", + note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`" + ), + on( + _Self = "unsafe fn", + note = "unsafe function cannot be called generically without an unsafe block", + // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string + label = "call the function in a closure: `|| unsafe {{ /* code */ }}`" + ), + message = "expected a `{Fn}<{Args}>` closure, found `{Self}`", + label = "expected an `Fn<{Args}>` closure, found `{Self}`" +)] +#[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use = "closures are lazy and do nothing unless called"] +#[const_trait] +pub trait Fn: FnMut { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + /// The version of the call operator that takes a mutable receiver. /// /// Instances of `FnMut` can be called repeatedly and may mutate state. @@ -139,6 +224,7 @@ pub trait Fn: FnMut { /// /// assert_eq!(x, 5); /// ``` +#[cfg(bootstrap)] #[lang = "fn_mut"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "FnMut"] @@ -166,6 +252,95 @@ pub trait FnMut: FnOnce { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; } +/// The version of the call operator that takes a mutable receiver. +/// +/// Instances of `FnMut` can be called repeatedly and may mutate state. +/// +/// `FnMut` is implemented automatically by closures which take mutable +/// references to captured variables, as well as all types that implement +/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of +/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F` +/// implements `FnMut`, too. +/// +/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be +/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of +/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected. +/// +/// Use `FnMut` as a bound when you want to accept a parameter of function-like +/// type and need to call it repeatedly, while allowing it to mutate state. +/// If you don't want the parameter to mutate state, use [`Fn`] as a +/// bound; if you don't need to call it repeatedly, use [`FnOnce`]. +/// +/// See the [chapter on closures in *The Rust Programming Language*][book] for +/// some more information on this topic. +/// +/// Also of note is the special syntax for `Fn` traits (e.g. +/// `Fn(usize, bool) -> usize`). Those interested in the technical details of +/// this can refer to [the relevant section in the *Rustonomicon*][nomicon]. +/// +/// [book]: ../../book/ch13-01-closures.html +/// [function pointers]: fn +/// [nomicon]: ../../nomicon/hrtb.html +/// +/// # Examples +/// +/// ## Calling a mutably capturing closure +/// +/// ``` +/// let mut x = 5; +/// { +/// let mut square_x = || x *= x; +/// square_x(); +/// } +/// assert_eq!(x, 25); +/// ``` +/// +/// ## Using a `FnMut` parameter +/// +/// ``` +/// fn do_twice(mut func: F) +/// where F: FnMut() +/// { +/// func(); +/// func(); +/// } +/// +/// let mut x: usize = 1; +/// { +/// let add_two_to_x = || x += 2; +/// do_twice(add_two_to_x); +/// } +/// +/// assert_eq!(x, 5); +/// ``` +#[cfg(not(bootstrap))] +#[lang = "fn_mut"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "FnMut"] +#[rustc_paren_sugar] +#[rustc_on_unimplemented( + on( + Args = "()", + note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`" + ), + on( + _Self = "unsafe fn", + note = "unsafe function cannot be called generically without an unsafe block", + // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string + label = "call the function in a closure: `|| unsafe {{ /* code */ }}`" + ), + message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`", + label = "expected an `FnMut<{Args}>` closure, found `{Self}`" +)] +#[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use = "closures are lazy and do nothing unless called"] +#[const_trait] +pub trait FnMut: FnOnce { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + /// The version of the call operator that takes a by-value receiver. /// /// Instances of `FnOnce` can be called, but might not be callable multiple @@ -219,6 +394,7 @@ pub trait FnMut: FnOnce { /// /// // `consume_and_return_x` can no longer be invoked at this point /// ``` +#[cfg(bootstrap)] #[lang = "fn_once"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "FnOnce"] @@ -251,6 +427,93 @@ pub trait FnOnce { extern "rust-call" fn call_once(self, args: Args) -> Self::Output; } +/// The version of the call operator that takes a by-value receiver. +/// +/// Instances of `FnOnce` can be called, but might not be callable multiple +/// times. Because of this, if the only thing known about a type is that it +/// implements `FnOnce`, it can only be called once. +/// +/// `FnOnce` is implemented automatically by closures that might consume captured +/// variables, as well as all types that implement [`FnMut`], e.g., (safe) +/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]). +/// +/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of +/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected. +/// +/// Use `FnOnce` as a bound when you want to accept a parameter of function-like +/// type and only need to call it once. If you need to call the parameter +/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate +/// state, use [`Fn`]. +/// +/// See the [chapter on closures in *The Rust Programming Language*][book] for +/// some more information on this topic. +/// +/// Also of note is the special syntax for `Fn` traits (e.g. +/// `Fn(usize, bool) -> usize`). Those interested in the technical details of +/// this can refer to [the relevant section in the *Rustonomicon*][nomicon]. +/// +/// [book]: ../../book/ch13-01-closures.html +/// [function pointers]: fn +/// [nomicon]: ../../nomicon/hrtb.html +/// +/// # Examples +/// +/// ## Using a `FnOnce` parameter +/// +/// ``` +/// fn consume_with_relish(func: F) +/// where F: FnOnce() -> String +/// { +/// // `func` consumes its captured variables, so it cannot be run more +/// // than once. +/// println!("Consumed: {}", func()); +/// +/// println!("Delicious!"); +/// +/// // Attempting to invoke `func()` again will throw a `use of moved +/// // value` error for `func`. +/// } +/// +/// let x = String::from("x"); +/// let consume_and_return_x = move || x; +/// consume_with_relish(consume_and_return_x); +/// +/// // `consume_and_return_x` can no longer be invoked at this point +/// ``` +#[cfg(not(bootstrap))] +#[lang = "fn_once"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "FnOnce"] +#[rustc_paren_sugar] +#[rustc_on_unimplemented( + on( + Args = "()", + note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`" + ), + on( + _Self = "unsafe fn", + note = "unsafe function cannot be called generically without an unsafe block", + // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string + label = "call the function in a closure: `|| unsafe {{ /* code */ }}`" + ), + message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`", + label = "expected an `FnOnce<{Args}>` closure, found `{Self}`" +)] +#[fundamental] // so that regex can rely that `&str: !FnMut` +#[must_use = "closures are lazy and do nothing unless called"] +#[const_trait] +pub trait FnOnce { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + #[stable(feature = "fn_once_output", since = "1.12.0")] + type Output; + + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +#[cfg(bootstrap)] mod impls { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] @@ -310,3 +573,61 @@ mod impls { } } } + +#[cfg(not(bootstrap))] +mod impls { + use crate::marker::Tuple; + + #[stable(feature = "rust1", since = "1.0.0")] + impl Fn for &F + where + F: Fn, + { + extern "rust-call" fn call(&self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl FnMut for &F + where + F: Fn, + { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl FnOnce for &F + where + F: Fn, + { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: A) -> F::Output { + (*self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl FnMut for &mut F + where + F: FnMut, + { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (*self).call_mut(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl FnOnce for &mut F + where + F: FnMut, + { + type Output = F::Output; + extern "rust-call" fn call_once(self, args: A) -> F::Output { + (*self).call_mut(args) + } + } +} From 2e7e1a31975f266941f131e9d40e510047a76ca2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Jul 2022 03:41:53 +0000 Subject: [PATCH 171/482] Enforce rust-check ABI in signatures, calls --- .../rustc_hir_analysis/src/check/wfcheck.rs | 22 +++++++++++ compiler/rustc_hir_typeck/src/callee.rs | 16 ++++++++ compiler/rustc_hir_typeck/src/check.rs | 37 ------------------- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 1 + compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_middle/src/traits/mod.rs | 2 + .../src/traits/error_reporting/suggestions.rs | 3 +- 7 files changed, 44 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0117bdd0ba81c..3ec8f9f5d14ea 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -21,6 +21,7 @@ use rustc_middle::ty::{GenericArgKind, InternalSubsts}; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::spec::abi::Abi; use rustc_trait_selection::autoderef::Autoderef; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; @@ -1542,6 +1543,27 @@ fn check_fn_or_method<'tcx>( sig.output(), hir_decl.output.span(), ); + + if sig.abi == Abi::RustCall { + let span = tcx.def_span(def_id); + let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None; + let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 }); + // Check that the argument is a tuple + if let Some(ty) = inputs.next() { + wfcx.register_bound( + ObligationCause::new(span, wfcx.body_id, ObligationCauseCode::RustCall), + wfcx.param_env, + *ty, + tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), + ); + } else { + tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); + } + // No more inputs other than the `self` type and the tuple type + if inputs.next().is_some() { + tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); + } + } } /// Basically `check_associated_type_bounds`, but separated for now and should be diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 000f4c9b68427..2b019c8c9b7a5 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -468,6 +468,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_id, ); + if fn_sig.abi == abi::Abi::RustCall { + let sp = arg_exprs.last().map_or(call_expr.span, |expr| expr.span); + if let Some(ty) = fn_sig.inputs().last().copied() { + self.register_bound( + ty, + self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)), + traits::ObligationCause::new(sp, self.body_id, traits::RustCall), + ); + } else { + self.tcx.sess.span_err( + sp, + "functions with the \"rust-call\" ABI must take a single non-self tuple argument", + ); + } + } + fn_sig.output() } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 80147d9009113..37af6e79c3ef5 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -6,13 +6,11 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ImplicitSelfKind, ItemKind, Node}; use rustc_hir_analysis::check::fn_maybe_err; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; -use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use std::cell::RefCell; @@ -56,41 +54,6 @@ pub(super) fn check_fn<'a, 'tcx>( fn_maybe_err(tcx, span, fn_sig.abi); - if fn_sig.abi == Abi::RustCall { - let expected_args = if let ImplicitSelfKind::None = decl.implicit_self { 1 } else { 2 }; - - let err = || { - let item = match tcx.hir().get(fn_id) { - Node::Item(hir::Item { kind: ItemKind::Fn(header, ..), .. }) => Some(header), - Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(header, ..), .. - }) => Some(header), - Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(header, ..), - .. - }) => Some(header), - // Closures are RustCall, but they tuple their arguments, so shouldn't be checked - Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => None, - node => bug!("Item being checked wasn't a function/closure: {:?}", node), - }; - - if let Some(header) = item { - tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); - } - }; - - if fn_sig.inputs().len() != expected_args { - err() - } else { - // FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on - // This will probably require wide-scale changes to support a TupleKind obligation - // We can't resolve this without knowing the type of the param - if !matches!(fn_sig.inputs()[expected_args - 1].kind(), ty::Tuple(_) | ty::Param(_)) { - err() - } - } - } - if body.generator_kind.is_some() && can_be_generator.is_some() { let yield_ty = fcx .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index e1955d838f253..2239a33a8e9f0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -136,6 +136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, Some(method.def_id), ); + method.sig.output() } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d1762598a5206..624443d9594c9 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -458,7 +458,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<' /// # fn f(x: (isize, isize)) {} /// f((1, 2)); /// ``` -#[derive(Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq, PartialEq)] enum TupleArgumentsFlag { DontTupleArguments, TupleArguments, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 07ee758b32c1f..a29f0722ff705 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -438,6 +438,8 @@ pub enum ObligationCauseCode<'tcx> { }, AscribeUserTypeProvePredicate(Span), + + RustCall, } /// The 'location' at which we try to perform HIR-based wf checking. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d7606d88803dc..0f4aa87b43f5e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2407,7 +2407,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::CheckAssociatedTypeBounds { .. } | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } - | ObligationCauseCode::AscribeUserTypeProvePredicate(..) => {} + | ObligationCauseCode::AscribeUserTypeProvePredicate(..) + | ObligationCauseCode::RustCall => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } From f9787e829afe07ba249ab2bb7f69b95cffc07652 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Jul 2022 05:37:48 +0000 Subject: [PATCH 172/482] Adjust diagnostics, bless tests --- .../rustc_hir_analysis/src/check/wfcheck.rs | 10 ++- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- .../src/traits/error_reporting/mod.rs | 26 ++++-- .../ui/abi/issues/issue-22565-rust-call.rs | 13 ++- .../abi/issues/issue-22565-rust-call.stderr | 33 ++++--- src/test/ui/abi/rustcall-generic.rs | 4 +- .../borrow-immutable-upvar-mutation.rs | 6 +- .../borrow-immutable-upvar-mutation.stderr | 24 ++--- .../ui/borrowck/borrowck-move-by-capture.rs | 6 +- src/test/ui/c-variadic/issue-86053-1.stderr | 4 +- .../ui/cannot-mutate-captured-non-mut-var.rs | 4 +- src/test/ui/chalkify/closure.stderr | 88 +++++++++++++++---- src/test/ui/closures/issue-78720.stderr | 4 +- src/test/ui/error-codes/E0059.stderr | 12 ++- src/test/ui/feature-gates/feature-gate-abi.rs | 3 + .../ui/feature-gates/feature-gate-abi.stderr | 68 +++++++------- src/test/ui/issues/issue-12127.rs | 4 +- src/test/ui/issues/issue-23024.stderr | 2 +- src/test/ui/issues/issue-7607-1.stderr | 4 +- .../lang-items/lang-item-missing-generator.rs | 6 +- .../lang-item-missing-generator.stderr | 11 ++- .../unboxed-closures-vtable-mismatch.rs | 4 +- ...type-move-out-of-closure-env-issue-1965.rs | 4 +- .../overloaded/overloaded-calls-nontuple.rs | 17 ++-- .../overloaded-calls-nontuple.stderr | 47 +++++++--- src/test/ui/span/issue-11925.rs | 4 +- src/test/ui/typeck/issue-83693.stderr | 4 +- .../unboxed-closure-illegal-move.rs | 8 +- .../unboxed-closures-mutate-upvar.rs | 6 +- .../unboxed-closures-mutate-upvar.stderr | 4 +- ...nboxed-closures-static-call-wrong-trait.rs | 4 +- 31 files changed, 279 insertions(+), 157 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3ec8f9f5d14ea..416b555db5c5e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1557,11 +1557,17 @@ fn check_fn_or_method<'tcx>( tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), ); } else { - tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); + tcx.sess.span_err( + hir_decl.inputs.last().map_or(span, |input| input.span), + "functions with the \"rust-call\" ABI must take a single non-self tuple argument", + ); } // No more inputs other than the `self` type and the tuple type if inputs.next().is_some() { - tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); + tcx.sess.span_err( + hir_decl.inputs.last().map_or(span, |input| input.span), + "functions with the \"rust-call\" ABI must take a single non-self tuple argument", + ); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 2239a33a8e9f0..4066cca8a4bd4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -215,7 +215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "cannot use call notation; the first type parameter \ for the function trait is neither a tuple nor unit" ) - .emit(); + .delay_as_bug(); (self.err_args(provided_args.len()), None) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index dacce5cd2f605..46c03757e600a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -700,6 +700,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } + if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() { + match obligation.cause.code().peel_derives() { + ObligationCauseCode::RustCall => { + err.set_primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); + } + ObligationCauseCode::BindingObligation(def_id, _) + | ObligationCauseCode::ItemObligation(def_id) + if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() => + { + err.code(rustc_errors::error_code!(E0059)); + err.set_primary_message(format!( + "type parameter to bare `{}` trait must be a tuple", + tcx.def_path_str(*def_id) + )); + } + _ => {} + } + } + if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait() && predicate_is_const { @@ -848,12 +867,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } - let is_fn_trait = [ - self.tcx.lang_items().fn_trait(), - self.tcx.lang_items().fn_mut_trait(), - self.tcx.lang_items().fn_once_trait(), - ] - .contains(&Some(trait_ref.def_id())); + let is_fn_trait = ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some(); let is_target_feature_fn = if let ty::FnDef(def_id, _) = *trait_ref.skip_binder().self_ty().kind() { diff --git a/src/test/ui/abi/issues/issue-22565-rust-call.rs b/src/test/ui/abi/issues/issue-22565-rust-call.rs index a08e0bfb5e5da..a572666c8887f 100644 --- a/src/test/ui/abi/issues/issue-22565-rust-call.rs +++ b/src/test/ui/abi/issues/issue-22565-rust-call.rs @@ -1,32 +1,31 @@ #![feature(unboxed_closures)] extern "rust-call" fn b(_i: i32) {} -//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument that is a tuple +//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument trait Tr { extern "rust-call" fn a(); + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument extern "rust-call" fn b() {} - //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument } struct Foo; impl Foo { extern "rust-call" fn bar() {} - //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument } impl Tr for Foo { extern "rust-call" fn a() {} - //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument } -fn main () { +fn main() { b(10); - Foo::bar(); - ::a(); ::b(); } diff --git a/src/test/ui/abi/issues/issue-22565-rust-call.stderr b/src/test/ui/abi/issues/issue-22565-rust-call.stderr index 3eee10bc5e951..9d205b444fad4 100644 --- a/src/test/ui/abi/issues/issue-22565-rust-call.stderr +++ b/src/test/ui/abi/issues/issue-22565-rust-call.stderr @@ -1,26 +1,33 @@ -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/issue-22565-rust-call.rs:3:1 | LL | extern "rust-call" fn b(_i: i32) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32` -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple - --> $DIR/issue-22565-rust-call.rs:9:5 - | -LL | extern "rust-call" fn b() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple - --> $DIR/issue-22565-rust-call.rs:16:5 +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:17:5 | LL | extern "rust-call" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple - --> $DIR/issue-22565-rust-call.rs:21:5 +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:22:5 | LL | extern "rust-call" fn a() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:7:5 + | +LL | extern "rust-call" fn a(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/issue-22565-rust-call.rs:10:5 + | +LL | extern "rust-call" fn b() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/abi/rustcall-generic.rs b/src/test/ui/abi/rustcall-generic.rs index 411c98e10313d..6eaccc436b699 100644 --- a/src/test/ui/abi/rustcall-generic.rs +++ b/src/test/ui/abi/rustcall-generic.rs @@ -2,9 +2,9 @@ // check-pass //[opt] compile-flags: -Zmir-opt-level=3 -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -extern "rust-call" fn foo(_: T) {} +extern "rust-call" fn foo(_: T) {} fn main() { foo(()); diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs index e2f016614bf86..a3350024e7567 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs @@ -1,4 +1,4 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] // Tests that we can't assign to or mutably borrow upvars from `Fn` // closures (issue #17780) @@ -7,10 +7,10 @@ fn set(x: &mut usize) { *x = 5; } -fn to_fn>(f: F) -> F { +fn to_fn>(f: F) -> F { f } -fn to_fn_mut>(f: F) -> F { +fn to_fn_mut>(f: F) -> F { f } diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr index 093589ed0921f..a0eaf1f163b02 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr @@ -1,8 +1,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:21:27 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _f = to_fn(|| x = 42); | ----- -- ^^^^^^ cannot assign @@ -13,8 +13,8 @@ LL | let _f = to_fn(|| x = 42); error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:24:31 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _g = to_fn(|| set(&mut y)); | ----- -- ^^^^^^ cannot borrow as mutable @@ -25,8 +25,8 @@ LL | let _g = to_fn(|| set(&mut y)); error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:29:22 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | to_fn(|| z = 42); | ----- -- ^^^^^^ cannot assign @@ -37,8 +37,8 @@ LL | to_fn(|| z = 42); error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:36:32 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _f = to_fn(move || x = 42); | ----- ------- ^^^^^^ cannot assign @@ -49,8 +49,8 @@ LL | let _f = to_fn(move || x = 42); error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:39:36 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _g = to_fn(move || set(&mut y)); | ----- ------- ^^^^^^ cannot borrow as mutable @@ -61,8 +61,8 @@ LL | let _g = to_fn(move || set(&mut y)); error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:44:27 | -LL | fn to_fn>(f: F) -> F { - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | to_fn(move || z = 42); | ----- ------- ^^^^^^ cannot assign diff --git a/src/test/ui/borrowck/borrowck-move-by-capture.rs b/src/test/ui/borrowck/borrowck-move-by-capture.rs index f26edef17f349..6f0eb1870f327 100644 --- a/src/test/ui/borrowck/borrowck-move-by-capture.rs +++ b/src/test/ui/borrowck/borrowck-move-by-capture.rs @@ -1,7 +1,7 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -fn to_fn_mut>(f: F) -> F { f } -fn to_fn_once>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } pub fn main() { let bar: Box<_> = Box::new(3); diff --git a/src/test/ui/c-variadic/issue-86053-1.stderr b/src/test/ui/c-variadic/issue-86053-1.stderr index 60b379faf4e06..075bd1fc488e6 100644 --- a/src/test/ui/c-variadic/issue-86053-1.stderr +++ b/src/test/ui/c-variadic/issue-86053-1.stderr @@ -66,8 +66,8 @@ LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here | help: a trait with a similar name exists | diff --git a/src/test/ui/cannot-mutate-captured-non-mut-var.rs b/src/test/ui/cannot-mutate-captured-non-mut-var.rs index a83884acb1d29..952dab25bf9dc 100644 --- a/src/test/ui/cannot-mutate-captured-non-mut-var.rs +++ b/src/test/ui/cannot-mutate-captured-non-mut-var.rs @@ -1,8 +1,8 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] use std::io::Read; -fn to_fn_once>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } fn main() { let x = 1; diff --git a/src/test/ui/chalkify/closure.stderr b/src/test/ui/chalkify/closure.stderr index 515e0cf01429d..ca62ad834bc7f 100644 --- a/src/test/ui/chalkify/closure.stderr +++ b/src/test/ui/chalkify/closure.stderr @@ -1,22 +1,80 @@ -error[E0382]: borrow of moved value: `b` - --> $DIR/closure.rs:28:5 +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:6:5 + | +LL | t(); + | ^^^ the trait `Tuple` is not implemented for `()` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:12:5 + | +LL | b(); + | ^^^ the trait `Tuple` is not implemented for `()` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:16:5 + | +LL | c(); + | ^^^ the trait `Tuple` is not implemented for `()` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:17:5 | -LL | let mut c = b; - | - value moved here -... LL | b(); - | ^ value borrowed here after move + | ^^^ the trait `Tuple` is not implemented for `()` | -note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment - --> $DIR/closure.rs:21:9 +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:23:5 + | +LL | b(); + | ^^^ the trait `Tuple` is not implemented for `()` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:27:5 + | +LL | c(); + | ^^^ the trait `Tuple` is not implemented for `()` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ + +error[E0277]: `()` is not a tuple + --> $DIR/closure.rs:28:5 + | +LL | b(); + | ^^^ `()` is not a tuple | -LL | a = 1; - | ^ -help: consider mutably borrowing `b` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | -LL | let mut c = &mut b; - | ++++ +LL | fn main() -> () where (): Tuple { + | +++++++++++++++ -error: aborting due to previous error +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0382`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/closures/issue-78720.stderr b/src/test/ui/closures/issue-78720.stderr index 3dd1387729833..da3f539a0071d 100644 --- a/src/test/ui/closures/issue-78720.stderr +++ b/src/test/ui/closures/issue-78720.stderr @@ -12,8 +12,8 @@ LL | _func: F, | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here | help: a trait with a similar name exists | diff --git a/src/test/ui/error-codes/E0059.stderr b/src/test/ui/error-codes/E0059.stderr index a1b8aeaedbb8b..f331d0142260e 100644 --- a/src/test/ui/error-codes/E0059.stderr +++ b/src/test/ui/error-codes/E0059.stderr @@ -1,8 +1,14 @@ -error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit - --> $DIR/E0059.rs:3:41 +error[E0059]: type parameter to bare `Fn` trait must be a tuple + --> $DIR/E0059.rs:3:11 | LL | fn foo>(f: F) -> F::Output { f(3) } - | ^^^^ + | ^^^^^^^ the trait `Tuple` is not implemented for `i32` + | +note: required by a bound in `Fn` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ^^^^^ required by this bound in `Fn` error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs index 855263595d0ba..15b674c62e44d 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.rs +++ b/src/test/ui/feature-gates/feature-gate-abi.rs @@ -9,6 +9,9 @@ #[lang="sized"] trait Sized { } +#[lang="tuple_trait"] +trait Tuple { } + // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr index bcca39c8fb808..33ec250f09067 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi.stderr @@ -1,5 +1,5 @@ error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:13:8 + --> $DIR/feature-gate-abi.rs:16:8 | LL | extern "rust-intrinsic" fn f1() {} | ^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:15:8 + --> $DIR/feature-gate-abi.rs:18:8 | LL | extern "platform-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:17:8 + --> $DIR/feature-gate-abi.rs:20:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | extern "rust-call" fn f4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:18:8 + --> $DIR/feature-gate-abi.rs:21:8 | LL | extern "efiapi" fn f10() {} | ^^^^^^^^ @@ -34,7 +34,7 @@ LL | extern "efiapi" fn f10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:22:12 + --> $DIR/feature-gate-abi.rs:25:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | extern "rust-intrinsic" fn m1(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:24:12 + --> $DIR/feature-gate-abi.rs:27:12 | LL | extern "platform-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | extern "platform-intrinsic" fn m2(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:26:12 + --> $DIR/feature-gate-abi.rs:29:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | extern "rust-call" fn m4(_: ()); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:27:12 + --> $DIR/feature-gate-abi.rs:30:12 | LL | extern "efiapi" fn m10(); | ^^^^^^^^ @@ -69,7 +69,7 @@ LL | extern "efiapi" fn m10(); = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:29:12 + --> $DIR/feature-gate-abi.rs:32:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | extern "rust-call" fn dm4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:30:12 + --> $DIR/feature-gate-abi.rs:33:12 | LL | extern "efiapi" fn dm10() {} | ^^^^^^^^ @@ -87,7 +87,7 @@ LL | extern "efiapi" fn dm10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:37:12 + --> $DIR/feature-gate-abi.rs:40:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | extern "rust-intrinsic" fn m1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:39:12 + --> $DIR/feature-gate-abi.rs:42:12 | LL | extern "platform-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | extern "platform-intrinsic" fn m2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:41:12 + --> $DIR/feature-gate-abi.rs:44:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | extern "rust-call" fn m4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:42:12 + --> $DIR/feature-gate-abi.rs:45:12 | LL | extern "efiapi" fn m10() {} | ^^^^^^^^ @@ -122,7 +122,7 @@ LL | extern "efiapi" fn m10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:47:12 + --> $DIR/feature-gate-abi.rs:50:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | extern "rust-intrinsic" fn im1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:49:12 + --> $DIR/feature-gate-abi.rs:52:12 | LL | extern "platform-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | extern "platform-intrinsic" fn im2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:51:12 + --> $DIR/feature-gate-abi.rs:54:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | extern "rust-call" fn im4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:52:12 + --> $DIR/feature-gate-abi.rs:55:12 | LL | extern "efiapi" fn im10() {} | ^^^^^^^^ @@ -157,7 +157,7 @@ LL | extern "efiapi" fn im10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:56:18 + --> $DIR/feature-gate-abi.rs:59:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:57:18 + --> $DIR/feature-gate-abi.rs:60:18 | LL | type A2 = extern "platform-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | type A2 = extern "platform-intrinsic" fn(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:58:18 + --> $DIR/feature-gate-abi.rs:61:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | type A4 = extern "rust-call" fn(_: ()); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:59:19 + --> $DIR/feature-gate-abi.rs:62:19 | LL | type A10 = extern "efiapi" fn(); | ^^^^^^^^ @@ -192,7 +192,7 @@ LL | type A10 = extern "efiapi" fn(); = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:62:8 + --> $DIR/feature-gate-abi.rs:65:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | extern "rust-intrinsic" {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:63:8 + --> $DIR/feature-gate-abi.rs:66:8 | LL | extern "platform-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | extern "platform-intrinsic" {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:64:8 + --> $DIR/feature-gate-abi.rs:67:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -218,7 +218,7 @@ LL | extern "rust-call" {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:65:8 + --> $DIR/feature-gate-abi.rs:68:8 | LL | extern "efiapi" {} | ^^^^^^^^ @@ -227,49 +227,49 @@ LL | extern "efiapi" {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:22:32 + --> $DIR/feature-gate-abi.rs:25:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:24:36 + --> $DIR/feature-gate-abi.rs:27:36 | LL | extern "platform-intrinsic" fn m2(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:13:33 + --> $DIR/feature-gate-abi.rs:16:33 | LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:15:37 + --> $DIR/feature-gate-abi.rs:18:37 | LL | extern "platform-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:37:37 + --> $DIR/feature-gate-abi.rs:40:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:39:41 + --> $DIR/feature-gate-abi.rs:42:41 | LL | extern "platform-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:47:38 + --> $DIR/feature-gate-abi.rs:50:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:49:42 + --> $DIR/feature-gate-abi.rs:52:42 | LL | extern "platform-intrinsic" fn im2() {} | ^^ diff --git a/src/test/ui/issues/issue-12127.rs b/src/test/ui/issues/issue-12127.rs index 8b30ddc2de67e..199d542e816f4 100644 --- a/src/test/ui/issues/issue-12127.rs +++ b/src/test/ui/issues/issue-12127.rs @@ -1,6 +1,6 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -fn to_fn_once>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } fn do_it(x: &isize) { } fn main() { diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 73f93c51d34e8..dc8b34a70c324 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -16,7 +16,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); note: trait defined here, with 1 generic parameter: `Args` --> $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { +LL | pub trait Fn: FnMut { | ^^ ---- help: add missing generic argument | diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr index ecff8b42b0ea7..f1ab0ad26d708 100644 --- a/src/test/ui/issues/issue-7607-1.stderr +++ b/src/test/ui/issues/issue-7607-1.stderr @@ -6,8 +6,8 @@ LL | impl Fo { | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error: aborting due to previous error diff --git a/src/test/ui/lang-items/lang-item-missing-generator.rs b/src/test/ui/lang-items/lang-item-missing-generator.rs index 0c329542928c5..9b9aff38e524e 100644 --- a/src/test/ui/lang-items/lang-item-missing-generator.rs +++ b/src/test/ui/lang-items/lang-item-missing-generator.rs @@ -1,12 +1,14 @@ // error-pattern: requires `generator` lang_item -#![feature(no_core, lang_items, unboxed_closures)] +#![feature(no_core, lang_items, unboxed_closures, tuple_trait)] #![no_core] #[lang = "sized"] pub trait Sized { } +#[lang = "tuple_trait"] pub trait Tuple { } + #[lang = "fn_once"] #[rustc_paren_sugar] -pub trait FnOnce { +pub trait FnOnce { type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; diff --git a/src/test/ui/lang-items/lang-item-missing-generator.stderr b/src/test/ui/lang-items/lang-item-missing-generator.stderr index fa13bf0b12719..a24fdb5fb6506 100644 --- a/src/test/ui/lang-items/lang-item-missing-generator.stderr +++ b/src/test/ui/lang-items/lang-item-missing-generator.stderr @@ -1,8 +1,15 @@ +error[E0635]: unknown feature `tuple_trait` + --> $DIR/lang-item-missing-generator.rs:2:51 + | +LL | #![feature(no_core, lang_items, unboxed_closures, tuple_trait)] + | ^^^^^^^^^^^ + error: requires `generator` lang_item - --> $DIR/lang-item-missing-generator.rs:15:17 + --> $DIR/lang-item-missing-generator.rs:17:17 | LL | pub fn abc() -> impl FnOnce(f32) { | ^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0635`. diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs index 8dbe3472ea893..307104e47a186 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -1,8 +1,8 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures,tuple_trait)] use std::ops::FnMut; -fn to_fn_mut>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } fn call_it isize>(y: isize, mut f: F) -> isize { //~^ NOTE required by this bound in `call_it` diff --git a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs index 76b7aab542de8..490d91ac118cb 100644 --- a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs +++ b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs @@ -1,6 +1,6 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -fn to_fn>(f: F) -> F { f } +fn to_fn>(f: F) -> F { f } fn test(_x: Box) {} diff --git a/src/test/ui/overloaded/overloaded-calls-nontuple.rs b/src/test/ui/overloaded/overloaded-calls-nontuple.rs index 07d44ff82b133..32a3b93e0a1e5 100644 --- a/src/test/ui/overloaded/overloaded-calls-nontuple.rs +++ b/src/test/ui/overloaded/overloaded-calls-nontuple.rs @@ -8,22 +8,23 @@ struct S { } impl FnMut for S { + //~^ ERROR type parameter to bare `FnMut` trait must be a tuple extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument self.x + self.y + z } - //~^^^ ERROR functions with the "rust-call" ABI must take a single non-self argument } impl FnOnce for S { + //~^ ERROR type parameter to bare `FnOnce` trait must be a tuple type Output = isize; - extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) } - //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument + extern "rust-call" fn call_once(mut self, z: isize) -> isize { + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument + self.call_mut(z) + } } fn main() { - let mut s = S { - x: 1, - y: 2, - }; - drop(s(3)) //~ ERROR cannot use call notation + let mut s = S { x: 1, y: 2 }; + drop(s(3)) } diff --git a/src/test/ui/overloaded/overloaded-calls-nontuple.stderr b/src/test/ui/overloaded/overloaded-calls-nontuple.stderr index 8f299bc9434f3..794535aeb1105 100644 --- a/src/test/ui/overloaded/overloaded-calls-nontuple.stderr +++ b/src/test/ui/overloaded/overloaded-calls-nontuple.stderr @@ -1,21 +1,40 @@ -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple - --> $DIR/overloaded-calls-nontuple.rs:11:5 +error[E0059]: type parameter to bare `FnMut` trait must be a tuple + --> $DIR/overloaded-calls-nontuple.rs:10:6 | -LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl FnMut for S { + | ^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | +note: required by a bound in `FnMut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait FnMut: FnOnce { + | ^^^^^ required by this bound in `FnMut` + +error[E0059]: type parameter to bare `FnOnce` trait must be a tuple + --> $DIR/overloaded-calls-nontuple.rs:18:6 + | +LL | impl FnOnce for S { + | ^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | +note: required by a bound in `FnOnce` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait FnOnce { + | ^^^^^ required by this bound in `FnOnce` -error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple - --> $DIR/overloaded-calls-nontuple.rs:19:5 +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/overloaded-calls-nontuple.rs:12:5 | -LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` -error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit - --> $DIR/overloaded-calls-nontuple.rs:28:10 +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/overloaded-calls-nontuple.rs:21:5 | -LL | drop(s(3)) - | ^^^^ +LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0059`. +Some errors have detailed explanations: E0059, E0277. +For more information about an error, try `rustc --explain E0059`. diff --git a/src/test/ui/span/issue-11925.rs b/src/test/ui/span/issue-11925.rs index d9c08fbdd0f15..cac9fd5bfb68d 100644 --- a/src/test/ui/span/issue-11925.rs +++ b/src/test/ui/span/issue-11925.rs @@ -1,6 +1,6 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -fn to_fn_once>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } fn main() { let r = { diff --git a/src/test/ui/typeck/issue-83693.stderr b/src/test/ui/typeck/issue-83693.stderr index 0d8bbf1ce98c1..1e45c2d35dfdc 100644 --- a/src/test/ui/typeck/issue-83693.stderr +++ b/src/test/ui/typeck/issue-83693.stderr @@ -6,8 +6,8 @@ LL | impl F { | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error[E0412]: cannot find type `TestResult` in this scope --> $DIR/issue-83693.rs:9:22 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs index ed8d721146133..7377359b6b0c6 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs @@ -1,12 +1,12 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] // Tests that we can't move out of an unboxed closure environment // if the upvar is captured by ref or the closure takes self by // reference. -fn to_fn>(f: F) -> F { f } -fn to_fn_mut>(f: F) -> F { f } -fn to_fn_once>(f: F) -> F { f } +fn to_fn>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } fn main() { // By-ref cases diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs index 57e6d30658ce5..c57312b438749 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs @@ -2,12 +2,12 @@ // as `mut` through a closure. Also test that we CAN mutate a moved copy, // unless this is a `Fn` closure. Issue #16749. -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] use std::mem; -fn to_fn>(f: F) -> F { f } -fn to_fn_mut>(f: F) -> F { f } +fn to_fn>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } fn a() { let n = 0; diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr index d6e74b5b8b914..26f97b51913df 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr @@ -28,8 +28,8 @@ LL | n += 1; error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutate-upvar.rs:53:9 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` ... LL | let mut f = to_fn(move || { | ----- ------- in this closure diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs index 0e727b11cd21e..7289d9322d050 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs @@ -1,6 +1,6 @@ -#![feature(unboxed_closures)] +#![feature(unboxed_closures, tuple_trait)] -fn to_fn_mut>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } fn main() { let mut_ = to_fn_mut(|x| x); From 0fada8b9a01d9d90f6743aee4ccbe8aeccbd3492 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Jul 2022 05:43:26 +0000 Subject: [PATCH 173/482] Bless chalk tests --- .../src/traits/error_reporting/mod.rs | 3 +- src/test/ui/chalkify/closure.rs | 5 ++-- src/test/ui/chalkify/closure.stderr | 18 ++++++------ src/test/ui/chalkify/trait-objects.rs | 3 +- src/test/ui/chalkify/trait-objects.stderr | 28 +++++++++++++++++++ 5 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/chalkify/trait-objects.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 46c03757e600a..54281f9120547 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -867,7 +867,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } - let is_fn_trait = ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some(); + let is_fn_trait = + ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some(); let is_target_feature_fn = if let ty::FnDef(def_id, _) = *trait_ref.skip_binder().self_ty().kind() { diff --git a/src/test/ui/chalkify/closure.rs b/src/test/ui/chalkify/closure.rs index 81114d491d78e..408e8802d862c 100644 --- a/src/test/ui/chalkify/closure.rs +++ b/src/test/ui/chalkify/closure.rs @@ -1,4 +1,5 @@ -// check-fail +// known-bug: unknown +// FIXME(chalk): Chalk needs support for the Tuple trait // compile-flags: -Z chalk fn main() -> () { @@ -25,7 +26,7 @@ fn main() -> () { let mut c = b; c(); - b(); //~ ERROR + b(); // FIXME: reenable when this is fixed ~ ERROR // FIXME(chalk): this doesn't quite work /* diff --git a/src/test/ui/chalkify/closure.stderr b/src/test/ui/chalkify/closure.stderr index ca62ad834bc7f..bcee0cab96ae7 100644 --- a/src/test/ui/chalkify/closure.stderr +++ b/src/test/ui/chalkify/closure.stderr @@ -1,5 +1,5 @@ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:6:5 + --> $DIR/closure.rs:7:5 | LL | t(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -10,7 +10,7 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:12:5 + --> $DIR/closure.rs:13:5 | LL | b(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -21,7 +21,7 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:16:5 + --> $DIR/closure.rs:17:5 | LL | c(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -32,7 +32,7 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:17:5 + --> $DIR/closure.rs:18:5 | LL | b(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -43,7 +43,7 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:23:5 + --> $DIR/closure.rs:24:5 | LL | b(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -54,7 +54,7 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:27:5 + --> $DIR/closure.rs:28:5 | LL | c(); | ^^^ the trait `Tuple` is not implemented for `()` @@ -65,10 +65,10 @@ LL | fn main() -> () where (): Tuple { | +++++++++++++++ error[E0277]: `()` is not a tuple - --> $DIR/closure.rs:28:5 + --> $DIR/closure.rs:29:5 | -LL | b(); - | ^^^ `()` is not a tuple +LL | b(); // FIXME: reenable when this is fixed ~ ERROR + | ^^^ the trait `Tuple` is not implemented for `()` | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | diff --git a/src/test/ui/chalkify/trait-objects.rs b/src/test/ui/chalkify/trait-objects.rs index d56abc42bf540..30929e943bd7f 100644 --- a/src/test/ui/chalkify/trait-objects.rs +++ b/src/test/ui/chalkify/trait-objects.rs @@ -1,4 +1,5 @@ -// check-pass +// known-bug: unknown +// FIXME(chalk): Chalk needs support for the Tuple trait // compile-flags: -Z chalk use std::fmt::Display; diff --git a/src/test/ui/chalkify/trait-objects.stderr b/src/test/ui/chalkify/trait-objects.stderr new file mode 100644 index 0000000000000..098bd2d3226e5 --- /dev/null +++ b/src/test/ui/chalkify/trait-objects.stderr @@ -0,0 +1,28 @@ +error: the type `&dyn Fn(i32) -> _` is not well-formed (chalk) + --> $DIR/trait-objects.rs:11:12 + | +LL | let f: &dyn Fn(i32) -> _ = &|x| x + x; + | ^^^^^^^^^^^^^^^^^ + +error[E0277]: `(i32,)` is not a tuple + --> $DIR/trait-objects.rs:12:5 + | +LL | f(2); + | ^^^^ the trait `Tuple` is not implemented for `(i32,)` + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn main() where (i32,): Tuple { + | +++++++++++++++++++ + +error[E0277]: expected a `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32` + --> $DIR/trait-objects.rs:12:5 + | +LL | f(2); + | ^^^^ expected an `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32` + | + = help: the trait `Fn<(i32,)>` is not implemented for `dyn Fn(i32) -> i32` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. From 29c85b2cf03a52426b2744b63c382138341e55f8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Oct 2022 06:57:01 +0000 Subject: [PATCH 174/482] Merge conflicts and rebase onto master --- library/core/src/const_closure.rs | 30 +++++++++++++++++++ library/core/src/ops/function.rs | 3 -- src/test/ui/function-pointer/unsized-ret.rs | 3 +- .../ui/function-pointer/unsized-ret.stderr | 12 ++++---- src/test/ui/parser/kw-in-trait-bounds.stderr | 16 +++++----- .../non-tupled-arg-mismatch.rs | 2 +- .../non-tupled-arg-mismatch.stderr | 20 ++++++------- 7 files changed, 56 insertions(+), 30 deletions(-) diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index 9e9c02093be20..151c8e6d8986a 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -1,4 +1,6 @@ use crate::marker::Destruct; +#[cfg(not(bootstrap))] +use crate::marker::Tuple; /// Struct representing a closure with mutably borrowed data. /// @@ -44,6 +46,7 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, macro_rules! impl_fn_mut_tuple { ($($var:ident)*) => { + #[cfg(bootstrap)] #[allow(unused_parens)] impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const FnOnce for ConstFnMutClosure<($(&'a mut $var),*), Function> @@ -56,6 +59,7 @@ macro_rules! impl_fn_mut_tuple { self.call_mut(args) } } + #[cfg(bootstrap)] #[allow(unused_parens)] impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const FnMut for ConstFnMutClosure<($(&'a mut $var),*), Function> @@ -68,6 +72,32 @@ macro_rules! impl_fn_mut_tuple { (self.func)(($($var),*), args) } } + #[cfg(not(bootstrap))] + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const + FnOnce for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, + { + type Output = ClosureReturnValue; + + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } + } + #[cfg(not(bootstrap))] + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const + FnMut for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, + { + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + #[allow(non_snake_case)] + let ($($var),*) = &mut self.data; + (self.func)(($($var),*), args) + } + } }; } impl_fn_mut_tuple!(A); diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 7c93fd30d4ec1..8d4b0a7ccacdb 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -75,7 +75,6 @@ use crate::marker::Tuple; )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -#[cfg_attr(not(bootstrap), const_trait)] pub trait Fn: FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -245,7 +244,6 @@ pub trait Fn: FnMut { )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -#[cfg_attr(not(bootstrap), const_trait)] pub trait FnMut: FnOnce { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -415,7 +413,6 @@ pub trait FnMut: FnOnce { )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -#[cfg_attr(not(bootstrap), const_trait)] pub trait FnOnce { /// The returned type after the call operator is used. #[lang = "fn_once_output"] diff --git a/src/test/ui/function-pointer/unsized-ret.rs b/src/test/ui/function-pointer/unsized-ret.rs index 60af5769d6ddb..79009c5cb6c07 100644 --- a/src/test/ui/function-pointer/unsized-ret.rs +++ b/src/test/ui/function-pointer/unsized-ret.rs @@ -1,7 +1,8 @@ #![feature(fn_traits)] #![feature(unboxed_closures)] +#![feature(tuple_trait)] -fn foo, T>(f: Option, t: T) { +fn foo, T:std::marker::Tuple>(f: Option, t: T) { let y = (f.unwrap()).call(t); } diff --git a/src/test/ui/function-pointer/unsized-ret.stderr b/src/test/ui/function-pointer/unsized-ret.stderr index bec3e2aa3fe6f..40bf7a3898acc 100644 --- a/src/test/ui/function-pointer/unsized-ret.stderr +++ b/src/test/ui/function-pointer/unsized-ret.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-ret.rs:9:27 + --> $DIR/unsized-ret.rs:10:27 | LL | foo:: str, _>(None, ()); | --------------------- ^^^^ doesn't have a size known at compile-time @@ -9,13 +9,13 @@ LL | foo:: str, _>(None, ()); = help: within `fn() -> str`, the trait `Sized` is not implemented for `str` = note: required because it appears within the type `fn() -> str` note: required by a bound in `foo` - --> $DIR/unsized-ret.rs:4:11 + --> $DIR/unsized-ret.rs:5:11 | -LL | fn foo, T>(f: Option, t: T) { +LL | fn foo, T:std::marker::Tuple>(f: Option, t: T) { | ^^^^^ required by this bound in `foo` error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time - --> $DIR/unsized-ret.rs:12:66 + --> $DIR/unsized-ret.rs:13:66 | LL | foo:: fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),)); | ------------------------------------------------------------ ^^^^ doesn't have a size known at compile-time @@ -25,9 +25,9 @@ LL | foo:: fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&() = help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)` = note: required because it appears within the type `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)` note: required by a bound in `foo` - --> $DIR/unsized-ret.rs:4:11 + --> $DIR/unsized-ret.rs:5:11 | -LL | fn foo, T>(f: Option, t: T) { +LL | fn foo, T:std::marker::Tuple>(f: Option, t: T) { | ^^^^^ required by this bound in `foo` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/kw-in-trait-bounds.stderr b/src/test/ui/parser/kw-in-trait-bounds.stderr index 28196c7ce2de8..546ad84eeee7b 100644 --- a/src/test/ui/parser/kw-in-trait-bounds.stderr +++ b/src/test/ui/parser/kw-in-trait-bounds.stderr @@ -94,8 +94,8 @@ LL | fn _f(_: impl fn(), _: &dyn fn()) | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error[E0405]: cannot find trait `r#fn` in this scope --> $DIR/kw-in-trait-bounds.rs:17:4 @@ -105,8 +105,8 @@ LL | G: fn(), | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error[E0405]: cannot find trait `r#fn` in this scope --> $DIR/kw-in-trait-bounds.rs:3:27 @@ -116,8 +116,8 @@ LL | fn _f(_: impl fn(), _: &dyn fn()) | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error[E0405]: cannot find trait `r#fn` in this scope --> $DIR/kw-in-trait-bounds.rs:3:41 @@ -127,8 +127,8 @@ LL | fn _f(_: impl fn(), _: &dyn fn()) | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | pub trait Fn: FnMut { - | ------------------------------- similarly named trait `Fn` defined here +LL | pub trait Fn: FnMut { + | -------------------------------------- similarly named trait `Fn` defined here error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:24:10 diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs index 925463d6deedc..d2e486002272c 100644 --- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs +++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs @@ -1,8 +1,8 @@ #![feature(unboxed_closures)] fn a>(f: F) {} +//~^ ERROR type parameter to bare `Fn` trait must be a tuple fn main() { a(|_: usize| {}); - //~^ ERROR mismatched types } diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index 9a24fb8c2beec..1c18eb0fc4905 100644 --- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -1,17 +1,15 @@ -error[E0308]: mismatched types - --> $DIR/non-tupled-arg-mismatch.rs:6:5 - | -LL | a(|_: usize| {}); - | ^ types differ - | - = note: expected trait `Fn` - found trait `Fn<(usize,)>` -note: required by a bound in `a` +error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/non-tupled-arg-mismatch.rs:3:9 | LL | fn a>(f: F) {} - | ^^^^^^^^^ required by this bound in `a` + | ^^^^^^^^^ the trait `Tuple` is not implemented for `usize` + | +note: required by a bound in `Fn` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ^^^^^ required by this bound in `Fn` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0059`. From 8a97aef61838d664be838bfa99ae692af87c806e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Oct 2022 19:41:54 +0000 Subject: [PATCH 175/482] Bless more tests --- src/test/codegen/avr/avr-func-addrspace.rs | 16 +++++----------- src/test/incremental/hashes/extern_mods.rs | 4 ++-- .../by-value-trait-objects-rust-call.rs | 3 ++- .../by-value-trait-objects-rust-call2.rs | 3 ++- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index a038dfe76f707..cbbcfad3ef483 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -19,6 +19,8 @@ pub trait Sized { } pub trait Copy { } #[lang = "receiver"] pub trait Receiver { } +#[lang = "tuple_trait"] +pub trait Tuple { } pub struct Result { _a: T, _b: E } @@ -29,7 +31,7 @@ impl Copy for &usize {} pub unsafe fn drop_in_place(_: *mut T) {} #[lang = "fn_once"] -pub trait FnOnce { +pub trait FnOnce { #[lang = "fn_once_output"] type Output; @@ -37,24 +39,16 @@ pub trait FnOnce { } #[lang = "fn_mut"] -pub trait FnMut : FnOnce { +pub trait FnMut : FnOnce { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; } #[lang = "fn"] -pub trait Fn: FnOnce { +pub trait Fn: FnOnce { /// Performs the call operation. extern "rust-call" fn call(&self, args: Args) -> Self::Output; } -impl<'a, A, R> FnOnce for &'a fn(A) -> R { - type Output = R; - - extern "rust-call" fn call_once(self, args: A) -> R { - (*self)(args) - } -} - pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box; pub static mut STORAGE_BAR: u32 = 12; diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs index ff79acc7f6392..3121abbea369b 100644 --- a/src/test/incremental/hashes/extern_mods.rs +++ b/src/test/incremental/hashes/extern_mods.rs @@ -128,7 +128,7 @@ extern "C" { // Change calling convention --------------------------------------------------- #[cfg(any(cfail1,cfail4))] extern "C" { - pub fn change_calling_convention(c: i32); + pub fn change_calling_convention(c: (i32,)); } #[cfg(not(any(cfail1,cfail4)))] @@ -137,7 +137,7 @@ extern "C" { #[rustc_clean(cfg = "cfail5", except = "hir_owner,hir_owner_nodes")] #[rustc_clean(cfg = "cfail6")] extern "rust-call" { - pub fn change_calling_convention(c: i32); + pub fn change_calling_convention(c: (i32,)); } // Make function public -------------------------------------------------------- diff --git a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs index 7f365ce2bbaf3..ece4dea9aaf6f 100644 --- a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs +++ b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs @@ -1,7 +1,8 @@ #![feature(unsized_locals)] #![feature(unboxed_closures)] +#![feature(tuple_trait)] -pub trait FnOnce { +pub trait FnOnce { type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; } diff --git a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs index a78b897d19414..94df2b0b83f0c 100644 --- a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs +++ b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs @@ -1,7 +1,8 @@ #![feature(unsized_locals)] #![feature(unboxed_closures)] +#![feature(tuple_trait)] -pub trait FnOnce { +pub trait FnOnce { type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; } From 4513ee825cb1857aafd4b23dc01f702c835347cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:10:36 +0100 Subject: [PATCH 176/482] rustdoc: render late-bound lifetimes in generic parameter list of cross-crate functions and methods --- src/librustdoc/clean/inline.rs | 16 ++++++++++++++-- src/librustdoc/clean/mod.rs | 20 ++++++++++++++++++-- src/librustdoc/clean/simplify.rs | 5 ++--- src/test/rustdoc/issue-20727.rs | 2 +- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 841c4f9d53005..bfbe143c202a6 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -243,10 +243,22 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box { let sig = cx.tcx.fn_sig(did); - let predicates = cx.tcx.predicates_of(did); + let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { + Some(clean::GenericParamDef { + name, + kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() }, + }) + } + _ => None, + }); + + let predicates = cx.tcx.explicit_predicates_of(did); let (generics, decl) = clean::enter_impl_trait(cx, |cx| { // NOTE: generics need to be cleaned before the decl! - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + // FIXME: This does not place parameters in source order (late-bound ones come last) + generics.params.extend(late_bound_regions); let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig); (generics, decl) }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 16e2d9a3cfc38..5cc7d866449a4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1144,12 +1144,28 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } } ty::AssocKind::Fn => { - let generics = clean_ty_generics( + let sig = tcx.fn_sig(assoc_item.def_id); + + let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + if name != kw::UnderscoreLifetime => + { + Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: Vec::new() }, + }) + } + _ => None, + }); + + let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), tcx.explicit_predicates_of(assoc_item.def_id), ); - let sig = tcx.fn_sig(assoc_item.def_id); + // FIXME: This does not place parameters in source order (late-bound ones come last) + generics.params.extend(late_bound_regions); + let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig); if assoc_item.fn_has_self_parameter { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 1c184f9b2695c..cd9dab1b1d570 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -99,9 +99,8 @@ pub(crate) fn merge_bounds( let last = trait_ref.trait_.segments.last_mut().expect("segments were empty"); trait_ref.generic_params.append(&mut bound_params); - // Since the parameters (probably) originate from `tcx.collect_*_late_bound_regions` which - // returns a hash set, sort them alphabetically to guarantee a stable and deterministic - // output (and to fully deduplicate them). + // Sort parameters (likely) originating from a hashset alphabetically to + // produce predictable output (and to allow for full deduplication). trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str())); trait_ref.generic_params.dedup_by_key(|p| p.name); diff --git a/src/test/rustdoc/issue-20727.rs b/src/test/rustdoc/issue-20727.rs index f7acffcb4e56a..c1a98cd57daf8 100644 --- a/src/test/rustdoc/issue-20727.rs +++ b/src/test/rustdoc/issue-20727.rs @@ -19,6 +19,6 @@ pub mod reexport { // @has - '//*[@class="rust trait"]' 'trait Deref {' // @has - '//*[@class="rust trait"]' 'type Target: ?Sized;' // @has - '//*[@class="rust trait"]' \ - // "fn deref(&'a self) -> &'a Self::Target;" + // "fn deref<'a>(&'a self) -> &'a Self::Target;" pub use issue_20727::Deref; } From df23cd664a5f5c2b64ccc6368683601d862f37d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:13:54 +0100 Subject: [PATCH 177/482] rustdoc: render unnamed arguments as underscores in cross-crate functions & function pointers for consistency with the way we display local definitions (cleaned from HIR, not from rustc_middle). --- src/librustdoc/clean/mod.rs | 20 ++++++++++++------- src/librustdoc/html/format.rs | 11 ++++------ .../inline_cross/assoc_item_trait_bounds.rs | 2 +- src/test/rustdoc/inline_cross/impl_trait.rs | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5cc7d866449a4..261907ad6d1a5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -957,12 +957,14 @@ fn clean_args_from_types_and_names<'tcx>( values: types .iter() .enumerate() - .map(|(i, ty)| { - let mut name = names.get(i).map_or(kw::Empty, |ident| ident.name); - if name.is_empty() { - name = kw::Underscore; - } - Argument { name, type_: clean_ty(ty, cx), is_const: false } + .map(|(i, ty)| Argument { + type_: clean_ty(ty, cx), + name: names + .get(i) + .map(|ident| ident.name) + .filter(|ident| !ident.is_empty()) + .unwrap_or(kw::Underscore), + is_const: false, }) .collect(), } @@ -1024,7 +1026,11 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( .iter() .map(|t| Argument { type_: clean_middle_ty(*t, cx, None), - name: names.next().map_or(kw::Empty, |i| i.name), + name: names + .next() + .map(|i| i.name) + .filter(|i| !i.is_empty()) + .unwrap_or(kw::Underscore), is_const: false, }) .collect(), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 06db3fb0ec400..a5c3d35b1b594 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1232,9 +1232,8 @@ impl clean::Arguments { ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { for (i, input) in self.values.iter().enumerate() { - if !input.name.is_empty() { - write!(f, "{}: ", input.name)?; - } + write!(f, "{}: ", input.name)?; + if f.alternate() { write!(f, "{:#}", input.type_.print(cx))?; } else { @@ -1367,10 +1366,8 @@ impl clean::FnDecl { args.push_str("const "); args_plain.push_str("const "); } - if !input.name.is_empty() { - write!(args, "{}: ", input.name); - write!(args_plain, "{}: ", input.name); - } + write!(args, "{}: ", input.name); + write!(args_plain, "{}: ", input.name); if f.alternate() { write!(args, "{:#}", input.type_.print(cx)); diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs index 5f4712aab5b19..b58605b9f1cb7 100644 --- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs @@ -33,7 +33,7 @@ extern crate assoc_item_trait_bounds as aux; // @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]' // // @has - '//*[@id="tymethod.make"]' \ -// "fn make(F, impl FnMut(&str) -> bool)\ +// "fn make(_: F, _: impl FnMut(&str) -> bool)\ // where \ // F: FnOnce(u32) -> String, \ // Self::Out2<()>: Protocol" diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index 6c1cf8252a9d6..9c4f646592038 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -29,7 +29,7 @@ pub use impl_trait_aux::func4; // @has impl_trait/fn.func5.html // @has - '//pre[@class="rust fn"]' "func5(" // @has - '//pre[@class="rust fn"]' "_f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other = ()>," -// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>" +// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>" // @!has - '//pre[@class="rust fn"]' 'where' pub use impl_trait_aux::func5; From 498538fc80c588eb95a11d4d69b877300648d674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:17:34 +0100 Subject: [PATCH 178/482] rustdoc: move cross-crate lifetime/outlives bounds on GAT params from where-clause to param declaration site I've overlooked this in #103190. --- src/librustdoc/clean/mod.rs | 11 ++++++++++- .../rustdoc/inline_cross/assoc_item_trait_bounds.rs | 4 ++++ .../inline_cross/auxiliary/assoc_item_trait_bounds.rs | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 261907ad6d1a5..d7c7a2cf83ee6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1303,7 +1303,16 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( .. }) = generics.params.iter_mut().find(|param| ¶m.name == arg) { - param_bounds.extend(mem::take(bounds)); + param_bounds.append(bounds); + } else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } = &mut pred + && let Some(GenericParamDef { + kind: GenericParamDefKind::Lifetime { outlives: param_bounds }, + .. + }) = generics.params.iter_mut().find(|param| ¶m.name == arg) { + param_bounds.extend(bounds.drain(..).map(|bound| match bound { + GenericBound::Outlives(lifetime) => lifetime, + _ => unreachable!(), + })); } else { where_predicates.push(pred); } diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs index b58605b9f1cb7..db2491b87b4d6 100644 --- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs @@ -38,3 +38,7 @@ extern crate assoc_item_trait_bounds as aux; // F: FnOnce(u32) -> String, \ // Self::Out2<()>: Protocol" pub use aux::Main; + +// @has main/trait.Aid.html +// @has - '//*[@id="associatedtype.Result"]' "type Result<'inter: 'src>" +pub use aux::Aid; diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs index d326e61daea26..6644c8e414789 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs @@ -42,5 +42,5 @@ pub trait Helper { } pub trait Aid<'src> { - type Result<'inter>; + type Result<'inter: 'src>; } From ccff7efc9c1c88a3b42c3a12fa4ec43d48b65ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:20:44 +0100 Subject: [PATCH 179/482] rustdoc: render `for<>` param lists of cross-crate trait-object types --- src/librustdoc/clean/mod.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d7c7a2cf83ee6..c40c5d14a66a3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -12,7 +12,7 @@ pub(crate) mod utils; use rustc_ast as ast; use rustc_attr as attr; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -1711,8 +1711,25 @@ pub(crate) fn clean_middle_ty<'tcx>( }) .collect(); + let late_bound_regions: FxIndexSet<_> = obj + .iter() + .flat_map(|pb| pb.bound_vars()) + .filter_map(|br| match br { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + if name != kw::UnderscoreLifetime => + { + Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }) + } + _ => None, + }) + .collect(); + let late_bound_regions = late_bound_regions.into_iter().collect(); + let path = external_path(cx, did, false, bindings, substs); - bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() }); + bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions }); DynTrait(bounds, lifetime) } From f5b8333be662a3bd855d772ce35f71ac1ebf90d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:23:25 +0100 Subject: [PATCH 180/482] rustdoc: render the return type of cross-crate `Fn`-family trait bounds in trait-object types --- src/librustdoc/clean/utils.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index df20dc3fc3f7e..824d98113c8f3 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -4,7 +4,7 @@ use crate::clean::render_macro_matchers::render_macro_matcher; use crate::clean::{ clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, - PathSegment, Primitive, PrimitiveType, Type, TypeBinding, + PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind, }; use crate::core::DocContext; use crate::html::format::visibility_to_src_with_space; @@ -113,12 +113,12 @@ fn external_generic_args<'tcx>( ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::>().into(), _ => return GenericArgs::AngleBracketed { args: args.into(), bindings }, }; - let output = None; - // FIXME(#20299) return type comes from a projection now - // match types[1].kind { - // ty::Tuple(ref v) if v.is_empty() => None, // -> () - // _ => Some(types[1].clean(cx)) - // }; + let output = bindings.into_iter().next().and_then(|binding| match binding.kind { + TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => { + Some(Box::new(ty)) + } + _ => None, + }); GenericArgs::Parenthesized { inputs, output } } else { GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() } From e3f912417854af9b55ffd29a5fdf5499e4819f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:25:04 +0100 Subject: [PATCH 181/482] rustdoc: add test for cross-crate trait-object types as well as some FIXMEs --- src/librustdoc/clean/mod.rs | 3 ++ src/test/rustdoc/assoc-consts.rs | 1 + .../inline_cross/auxiliary/dyn_trait.rs | 17 ++++++++++ src/test/rustdoc/inline_cross/dyn_trait.rs | 31 +++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs create mode 100644 src/test/rustdoc/inline_cross/dyn_trait.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c40c5d14a66a3..43d856ea87636 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1684,6 +1684,9 @@ pub(crate) fn clean_middle_ty<'tcx>( inline::record_extern_fqn(cx, did, ItemType::Trait); + // FIXME(fmease): Hide the trait-object lifetime bound if it coincides with its default + // to partially address #44306. Follow the rules outlined at + // https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes let lifetime = clean_middle_region(*reg); let mut bounds = dids .map(|did| { diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs index a3e10ee5555a0..3da19a13e5331 100644 --- a/src/test/rustdoc/assoc-consts.rs +++ b/src/test/rustdoc/assoc-consts.rs @@ -46,6 +46,7 @@ pub fn f(_: &(ToString + 'static)) {} impl Bar { // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \ // "const F: fn(_: &(dyn ToString + 'static))" + // FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)" pub const F: fn(_: &(ToString + 'static)) = f; } diff --git a/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs new file mode 100644 index 0000000000000..9ac2e3d96debd --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs @@ -0,0 +1,17 @@ +pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool; + +pub type Ty1<'obj> = dyn std::fmt::Display + 'obj; + +pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>; + +pub type Ty3<'s> = &'s dyn ToString; + +pub fn func0(_: &(dyn Fn() + '_)) {} + +pub fn func1<'func>(_: &(dyn Fn() + 'func)) {} + +pub trait Container<'r> { + type Item<'a, 'ctx>; +} + +pub trait Shape<'a> {} diff --git a/src/test/rustdoc/inline_cross/dyn_trait.rs b/src/test/rustdoc/inline_cross/dyn_trait.rs new file mode 100644 index 0000000000000..fa760540e4365 --- /dev/null +++ b/src/test/rustdoc/inline_cross/dyn_trait.rs @@ -0,0 +1,31 @@ +#![crate_name = "user"] + +// aux-crate:dyn_trait=dyn_trait.rs +// edition:2021 + +// @has user/type.Ty0.html +// @has - '//*[@class="item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static" +// FIXME(fmease): Hide default lifetime bound `'static` +pub use dyn_trait::Ty0; + +// @has user/type.Ty1.html +// @has - '//*[@class="item-decl"]//code' "dyn Display + 'obj" +pub use dyn_trait::Ty1; + +// @has user/type.Ty2.html +// @has - '//*[@class="item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>" +pub use dyn_trait::Ty2; + +// @has user/type.Ty3.html +// @has - '//*[@class="item-decl"]//code' "&'s (dyn ToString + 's)" +// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString" +pub use dyn_trait::Ty3; + +// @has user/fn.func0.html +// @has - '//pre[@class="rust fn"]' "func0(_: &dyn Fn())" +// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))" +pub use dyn_trait::func0; + +// @has user/fn.func1.html +// @has - '//pre[@class="rust fn"]' "func1<'func>(_: &(dyn Fn() + 'func))" +pub use dyn_trait::func1; From 979d15140ddde24b2ffa338afba16d73392d5709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 2 Nov 2022 15:56:28 +0100 Subject: [PATCH 182/482] rustdoc: create helper `GenericParamDef::lifetime` --- src/librustdoc/clean/auto_trait.rs | 5 +---- src/librustdoc/clean/inline.rs | 5 +---- src/librustdoc/clean/mod.rs | 22 ++++++---------------- src/librustdoc/clean/simplify.rs | 5 +---- src/librustdoc/clean/types.rs | 4 ++++ 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 84e77e69ecff3..85bd8446640dd 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -336,10 +336,7 @@ where match br { // We only care about named late bound regions, as we need to add them // to the 'for<>' section - ty::BrNamed(_, name) => Some(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, - }), + ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)), _ => None, } }) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index bfbe143c202a6..8a5463c10f210 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -245,10 +245,7 @@ fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box { - Some(clean::GenericParamDef { - name, - kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() }, - }) + Some(clean::GenericParamDef::lifetime(name)) } _ => None, }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 43d856ea87636..19276b9b187a0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -182,10 +182,9 @@ fn clean_poly_trait_ref_with_bindings<'tcx>( .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, - }), + ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => { + Some(GenericParamDef::lifetime(name)) + } _ => None, }) .collect(); @@ -741,10 +740,7 @@ fn clean_ty_generics<'tcx>( p.get_bound_params() .into_iter() .flatten() - .map(|param| GenericParamDef { - name: param.0, - kind: GenericParamDefKind::Lifetime { outlives: Vec::new() }, - }) + .map(|param| GenericParamDef::lifetime(param.0)) .collect(), )); } @@ -1156,10 +1152,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { - Some(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime { outlives: Vec::new() }, - }) + Some(GenericParamDef::lifetime(name)) } _ => None, }); @@ -1721,10 +1714,7 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { - Some(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, - }) + Some(GenericParamDef::lifetime(name)) } _ => None, }) diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index cd9dab1b1d570..7d97d2994e460 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -51,10 +51,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec Self { + Self { name, kind: GenericParamDefKind::Lifetime { outlives: Vec::new() } } + } + pub(crate) fn is_synthetic_type_param(&self) -> bool { match self.kind { GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, From a0d42574beb65ec2fc596454449c053ed835ac0b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 12:02:33 +1100 Subject: [PATCH 183/482] Make underscore_literal_suffix a hard error. It's been a warning for 5.5 years. Time to make it a hard error. Closes #42326. --- compiler/rustc_lexer/src/lib.rs | 9 ++++++--- compiler/rustc_parse/src/lexer/mod.rs | 12 +----------- .../ui/parser/underscore-suffix-for-string.rs | 17 +++++++++++++---- .../parser/underscore-suffix-for-string.stderr | 13 ++++++++----- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 51515976e4ee9..dd2c09cae02fd 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -88,7 +88,9 @@ pub enum TokenKind { /// tokens. UnknownPrefix, - /// Examples: `"12_u8"`, `"1.0e-40"`, `b"123`. + /// Examples: `12u8`, `1.0e-40`, `b"123"`. Note that `_` is an invalid + /// suffix, but may be present here on string and float literals. Users of + /// this type will need to check for and reject that case. /// /// See [LiteralKind] for more details. Literal { kind: LiteralKind, suffix_start: u32 }, @@ -840,12 +842,13 @@ impl Cursor<'_> { self.eat_decimal_digits() } - // Eats the suffix of the literal, e.g. "_u8". + // Eats the suffix of the literal, e.g. "u8". fn eat_literal_suffix(&mut self) { self.eat_identifier(); } - // Eats the identifier. + // Eats the identifier. Note: succeeds on `_`, which isn't a valid + // identifer. fn eat_identifier(&mut self) { if !is_id_start(self.first()) { return; diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 462bce16ad717..de8f1c00c1295 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -175,20 +175,10 @@ impl<'a> StringReader<'a> { if string == "_" { self.sess .span_diagnostic - .struct_span_warn( + .struct_span_err( self.mk_sp(suffix_start, self.pos), "underscore literal suffix is not allowed", ) - .warn( - "this was previously accepted by the compiler but is \ - being phased out; it will become a hard error in \ - a future release!", - ) - .note( - "see issue #42326 \ - \ - for more information", - ) .emit(); None } else { diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs index 2e0ebe2cfa446..bd260752e04d6 100644 --- a/src/test/ui/parser/underscore-suffix-for-string.rs +++ b/src/test/ui/parser/underscore-suffix-for-string.rs @@ -1,8 +1,17 @@ -// check-pass +macro_rules! sink { + ($tt:tt) => {()} +} fn main() { let _ = "Foo"_; - //~^ WARNING underscore literal suffix is not allowed - //~| WARNING this was previously accepted - //~| NOTE issue #42326 + //~^ ERROR underscore literal suffix is not allowed + + // This is ok, because `__` is a valid identifier and the macro consumes it + // before proper parsing happens. + let _ = sink!("Foo"__); + + // This is not ok, even as an input to a macro, because the `_` suffix is + // never allowed. + sink!("Foo"_); + //~^ ERROR underscore literal suffix is not allowed } diff --git a/src/test/ui/parser/underscore-suffix-for-string.stderr b/src/test/ui/parser/underscore-suffix-for-string.stderr index 00c7657f17bd3..2fe2c130eb211 100644 --- a/src/test/ui/parser/underscore-suffix-for-string.stderr +++ b/src/test/ui/parser/underscore-suffix-for-string.stderr @@ -1,11 +1,14 @@ -warning: underscore literal suffix is not allowed - --> $DIR/underscore-suffix-for-string.rs:4:18 +error: underscore literal suffix is not allowed + --> $DIR/underscore-suffix-for-string.rs:6:18 | LL | let _ = "Foo"_; | ^ + +error: underscore literal suffix is not allowed + --> $DIR/underscore-suffix-for-string.rs:15:16 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: see issue #42326 for more information +LL | sink!("Foo"_); + | ^ -warning: 1 warning emitted +error: aborting due to 2 previous errors From b36600297e8f8a8a78cb0d5a2f7b28e16fc5e530 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 6 Nov 2022 14:01:46 +0530 Subject: [PATCH 184/482] Add type_array to BaseTypeMethods Moved type_array function to rustc_codegen_ssa::BaseTypeMethods trait. This allows using normal alloca function to create arrays as suggested in https://github.com/rust-lang/rust/pull/104022. Signed-off-by: Ayush Singh --- compiler/rustc_codegen_gcc/src/type_.rs | 42 +++++++++---------- compiler/rustc_codegen_llvm/src/type_.rs | 8 ++-- .../rustc_codegen_ssa/src/traits/type_.rs | 1 + 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index 68bdb8d4e55f4..862ed62c68b2a 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -201,6 +201,27 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn val_ty(&self, value: RValue<'gcc>) -> Type<'gcc> { value.get_type() } + + fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { + if let Some(struct_type) = ty.is_struct() { + if struct_type.get_field_count() == 0 { + // NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a + // size of usize::MAX in test_binary_search, we workaround this by setting the size to + // zero for ZSTs. + // FIXME(antoyo): fix gccjit API. + len = 0; + } + } + + // NOTE: see note above. Some other test uses usize::MAX. + if len == u64::MAX { + len = 0; + } + + let len: i32 = len.try_into().expect("array len"); + + self.context.new_array_type(None, ty, len) + } } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { @@ -227,27 +248,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_opaque_struct_type(None, name) } - pub fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { - if let Some(struct_type) = ty.is_struct() { - if struct_type.get_field_count() == 0 { - // NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a - // size of usize::MAX in test_binary_search, we workaround this by setting the size to - // zero for ZSTs. - // FIXME(antoyo): fix gccjit API. - len = 0; - } - } - - // NOTE: see note above. Some other test uses usize::MAX. - if len == u64::MAX { - len = 0; - } - - let len: i32 = len.try_into().expect("array len"); - - self.context.new_array_type(None, ty, len) - } - pub fn type_bool(&self) -> Type<'gcc> { self.context.new_type::() } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index eeb38d4ecf591..5eec7dc613028 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -127,10 +127,6 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } - - pub(crate) fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { - unsafe { llvm::LLVMRustArrayType(ty, len) } - } } impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -231,6 +227,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn val_ty(&self, v: &'ll Value) -> &'ll Type { common::val_ty(v) } + + fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { + unsafe { llvm::LLVMRustArrayType(ty, len) } + } } impl Type { diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index bdc6a91cf6ab5..86481d5d758d6 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -22,6 +22,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn type_f32(&self) -> Self::Type; fn type_f64(&self) -> Self::Type; + fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; fn type_kind(&self, ty: Self::Type) -> TypeKind; From d0acc4e7a6279ad7fca19ff1063fa48135acd84d Mon Sep 17 00:00:00 2001 From: ripytide <62516857+ripytide@users.noreply.github.com> Date: Sun, 6 Nov 2022 15:25:00 +0000 Subject: [PATCH 185/482] Vec: IntoIterator signature consistency Also makes the code dryer. --- library/alloc/src/vec/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 834c8f58cb2a9..766006939fa48 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2780,7 +2780,7 @@ impl IntoIterator for Vec { /// assert_eq!(v_iter.next(), None); /// ``` #[inline] - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> Self::IntoIter { unsafe { let mut me = ManuallyDrop::new(self); let alloc = ManuallyDrop::new(ptr::read(me.allocator())); @@ -2808,7 +2808,7 @@ impl<'a, T, A: Allocator> IntoIterator for &'a Vec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; - fn into_iter(self) -> slice::Iter<'a, T> { + fn into_iter(self) -> Self::IntoIter { self.iter() } } @@ -2818,7 +2818,7 @@ impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; - fn into_iter(self) -> slice::IterMut<'a, T> { + fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } From af11901f9044bfe83b7bdcdcdfe825d468442b9a Mon Sep 17 00:00:00 2001 From: Rejyr Date: Sun, 6 Nov 2022 11:22:29 -0500 Subject: [PATCH 186/482] fix: typo --- compiler/rustc_middle/src/lint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index af70b0c6470e5..1c081b17cf2b7 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -276,7 +276,7 @@ pub fn explain_lint_level_source( /// The innermost function for emitting lints. /// -/// If you are loocking to implement a lint, look for higher level functions, +/// If you are looking to implement a lint, look for higher level functions, /// for example: /// - [`TyCtxt::emit_spanned_lint`] /// - [`TyCtxt::struct_span_lint_hir`] From 36fb60fb95cc40a8bb3da69333a7b253ddb9b8d8 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 6 Nov 2022 09:55:16 -0700 Subject: [PATCH 187/482] rustdoc: remove unused CSS `#sidebar-filler` This hack was removed in 6a5f8b1aef1417d7dc85b5d0a229d2db1930eb7c, but the CSS was left in. --- src/librustdoc/html/static/css/rustdoc.css | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 66e48ba8cf1ab..ee3f4e7c471b8 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1804,21 +1804,6 @@ in storage.js display: block; } - /* Because of ios, we need to actually have a full height sidebar title so the - * actual sidebar can show up. But then we need to make it transparent so we don't - * hide content. The filler just allows to create the background for the sidebar - * title. But because of the absolute position, I had to lower the z-index. - */ - #sidebar-filler { - position: fixed; - left: 45px; - width: calc(100% - 45px); - top: 0; - height: 45px; - z-index: -1; - border-bottom: 1px solid; - } - #main-content > details.rustdoc-toggle > summary::before, #main-content > div > details.rustdoc-toggle > summary::before { left: -11px; From 02f6ce681cc1e1e91441b4c3ec30a97e5a8167cb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 6 Nov 2022 18:20:28 +0100 Subject: [PATCH 188/482] Migrate rust logo filter to CSS variables --- src/librustdoc/html/static/css/rustdoc.css | 4 ++++ src/librustdoc/html/static/css/themes/ayu.css | 11 ++++------- src/librustdoc/html/static/css/themes/dark.css | 11 ++++------- src/librustdoc/html/static/css/themes/light.css | 7 +------ 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index ee3f4e7c471b8..a38c0e42ab455 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -378,6 +378,10 @@ img { object-fit: contain; } +.rust-logo { + filter: var(--rust-logo-filter); +} + .sidebar, .mobile-topbar, .sidebar-menu-toggle { background-color: var(--sidebar-background-color); } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 4b88c42f2df05..bf8a60affaa22 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -63,6 +63,10 @@ Original by Dempfi (https://github.com/dempfi/ayu) --test-arrow-background-color: rgba(57, 175, 215, 0.09); --test-arrow-hover-color: #c5c5c5; --test-arrow-hover-background-color: rgba(57, 175, 215, 0.368); + --rust-logo-filter: drop-shadow(1px 0 0px #fff) + drop-shadow(0 1px 0 #fff) + drop-shadow(-1px 0 0 #fff) + drop-shadow(0 -1px 0 #fff); } .slider { @@ -104,13 +108,6 @@ pre, .rustdoc.source .example-wrap { color: #e6e1cf; } -.rust-logo { - filter: drop-shadow(1px 0 0px #fff) - drop-shadow(0 1px 0 #fff) - drop-shadow(-1px 0 0 #fff) - drop-shadow(0 -1px 0 #fff); -} - .sidebar .current, .sidebar a:hover { color: #ffb44c; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 8edd8fee78d0b..ac6e527848f61 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -58,6 +58,10 @@ --test-arrow-background-color: rgba(78, 139, 202, 0.2); --test-arrow-hover-color: #dedede; --test-arrow-hover-background-color: #4e8bca; + --rust-logo-filter: drop-shadow(1px 0 0px #fff) + drop-shadow(0 1px 0 #fff) + drop-shadow(-1px 0 0 #fff) + drop-shadow(0 -1px 0 #fff); } .slider { @@ -70,13 +74,6 @@ input:focus + .slider { box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); } -.rust-logo { - filter: drop-shadow(1px 0 0px #fff) - drop-shadow(0 1px 0 #fff) - drop-shadow(-1px 0 0 #fff) - drop-shadow(0 -1px 0 #fff) -} - .content .item-info::before { color: #ccc; } body.source .example-wrap pre.rust a { diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 797be8754f8d3..608fc5aba7fd3 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -58,6 +58,7 @@ --test-arrow-background-color: rgba(78, 139, 202, 0.2); --test-arrow-hover-color: #f5f5f5; --test-arrow-hover-background-color: #4e8bca; + --rust-logo-filter: initial; } .slider { @@ -70,12 +71,6 @@ input:focus + .slider { box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); } -.rust-logo { - /* This rule exists to force other themes to explicitly style the logo. - * Rustdoc has a custom linter for this purpose. - */ -} - .content .item-info::before { color: #ccc; } body.source .example-wrap pre.rust a { From 527e95aa591e9aa6cf5397aee0387ca1e16fc263 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 6 Nov 2022 20:20:43 +0100 Subject: [PATCH 189/482] Extend rust-logo GUI test to check there is no filter for other logos --- src/test/rustdoc-gui/rust-logo.goml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml index 6c8dc85941931..816cc9abd693d 100644 --- a/src/test/rustdoc-gui/rust-logo.goml +++ b/src/test/rustdoc-gui/rust-logo.goml @@ -17,6 +17,15 @@ define-function: ( ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), ("reload"), ("assert-css", (".rust-logo", {"filter": |filter|})), + // Now we check that the non-rust logos don't have a CSS filter set. + ("goto", "file://" + |DOC_PATH| + "/huge_logo/index.html"), + // Changing theme on the new page (again...). + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + ("reload"), + // Check there is no rust logo + ("assert-false", ".rust-logo"), + // Check there is no filter. + ("assert-css", (".sidebar .logo-container img", {"filter": "none"})), ], ) From efd91159a52143ddb64ecda0897ed4cb4dc0f488 Mon Sep 17 00:00:00 2001 From: Tim Neumann Date: Sun, 6 Nov 2022 19:03:22 +0000 Subject: [PATCH 190/482] LLVM 16: Update RISCV data layout --- compiler/rustc_codegen_llvm/src/context.rs | 4 ++++ compiler/rustc_target/src/spec/riscv64gc_unknown_freebsd.rs | 2 +- compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs | 2 +- compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs | 2 +- compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs | 2 +- .../rustc_target/src/spec/riscv64imac_unknown_none_elf.rs | 2 +- 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 79ddfd884dfac..c22ec128dacb0 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -158,6 +158,10 @@ pub unsafe fn create_module<'ll>( if sess.target.arch == "s390x" { target_data_layout = target_data_layout.replace("-v128:64", ""); } + + if sess.target.arch == "riscv64" { + target_data_layout = target_data_layout.replace("-n32:64-", "-n64-"); + } } // Ensure the data-layout values hardcoded remain the defaults. diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_freebsd.rs index 0539eca6c1fce..8281bac10f88f 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_freebsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { Target { llvm_target: "riscv64-unknown-freebsd".into(), pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "riscv64".into(), options: TargetOptions { code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs index 7d1bf228c3702..90dccb28063dc 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { Target { llvm_target: "riscv64-unknown-linux-gnu".into(), pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "riscv64".into(), options: TargetOptions { code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs index f04f8a48bc81f..1a56c78e68524 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { Target { llvm_target: "riscv64-unknown-linux-musl".into(), pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "riscv64".into(), options: TargetOptions { code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 67806d578c8e4..409b0b2696152 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs @@ -3,7 +3,7 @@ use crate::spec::{RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), llvm_target: "riscv64".into(), pointer_width: 64, arch: "riscv64".into(), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs index cd10f3afaac06..ade9d77624bdb 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_openbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { Target { llvm_target: "riscv64-unknown-openbsd".into(), pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "riscv64".into(), options: TargetOptions { code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs index f371e09bed74d..87aba9171b416 100644 --- a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs @@ -3,7 +3,7 @@ use crate::spec::{RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), llvm_target: "riscv64".into(), pointer_width: 64, arch: "riscv64".into(), From 7c61b9299530b62bac2ad95acd97a87f42290461 Mon Sep 17 00:00:00 2001 From: yancy Date: Sun, 6 Nov 2022 23:05:16 +0100 Subject: [PATCH 191/482] rustdoc: Add an example for round that is different from truncate --- library/std/src/f32.rs | 2 ++ library/std/src/f64.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index dafcd87674412..4127c4056f24e 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -77,9 +77,11 @@ impl f32 { /// ``` /// let f = 3.3_f32; /// let g = -3.3_f32; + /// let h = -3.7_f32; /// /// assert_eq!(f.round(), 3.0); /// assert_eq!(g.round(), -3.0); + /// assert_eq!(h.round(), -4.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 77048f9a28f25..cc64258da60d1 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -77,9 +77,11 @@ impl f64 { /// ``` /// let f = 3.3_f64; /// let g = -3.3_f64; + /// let h = -3.7_f64; /// /// assert_eq!(f.round(), 3.0); /// assert_eq!(g.round(), -3.0); + /// assert_eq!(h.round(), -4.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] From b0c16cef0f1e6a439f4ab26cc04b1a6788651b81 Mon Sep 17 00:00:00 2001 From: CastilloDel Date: Fri, 28 Oct 2022 12:20:45 +0200 Subject: [PATCH 192/482] Remove #![allow(rustc::potential_query_instability)] from rustc_infer Change reported_violations to use IndexSet It is being used to iterate and to insert, without a lot of lookups so hopefully it won't be a perf hit Change MiniGraph.nodes to use IndexSet It is being used to iterate and to insert, without performing lookups so hopefully it won't be a perf hit Change RegionConstraintData.givens to a FxIndexSet This might result in a perf hit. Remove was being used in `givens`, and `FxIndexSet` doesn't allow calling remove without losing the fixed iteration order. So it was necessary to change remove to `shift_remove`, but this method is slower. Change OpaqueTypesVisitor to use stable sets and maps This could also be a perf hit. Make TraitObject visitor use a stable set --- .../rustc_borrowck/src/diagnostics/region_errors.rs | 8 ++++---- .../rustc_infer/src/infer/error_reporting/mod.rs | 12 ++++++------ .../nice_region_error/mismatched_static_lifetime.rs | 4 ++-- .../nice_region_error/static_impl_trait.rs | 12 ++++++------ .../infer/error_reporting/nice_region_error/util.rs | 2 ++ .../src/infer/lexical_region_resolve/mod.rs | 3 +++ .../src/infer/region_constraints/leak_check.rs | 7 ++++--- .../rustc_infer/src/infer/region_constraints/mod.rs | 4 ++-- compiler/rustc_infer/src/lib.rs | 1 - .../rustc_infer/src/traits/error_reporting/mod.rs | 4 ++-- 10 files changed, 31 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 196ddbe8d5046..76f249dac5181 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -2,7 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] //! Error reporting machinery for lifetime errors. -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -276,7 +276,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn get_impl_ident_and_self_ty_from_trait( &self, def_id: DefId, - trait_objects: &FxHashSet, + trait_objects: &FxIndexSet, ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { let tcx = self.infcx.tcx; match tcx.hir().get_if_local(def_id) { @@ -830,7 +830,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; debug!(?param); - let mut visitor = TraitObjectVisitor(FxHashSet::default()); + let mut visitor = TraitObjectVisitor(FxIndexSet::default()); visitor.visit_ty(param.param_ty); let Some((ident, self_ty)) = @@ -843,7 +843,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn suggest_constrain_dyn_trait_in_impl( &self, err: &mut Diagnostic, - found_dids: &FxHashSet, + found_dids: &FxIndexSet, ident: Ident, self_ty: &hir::Ty<'_>, ) -> bool { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 9ff703e521ff6..e4a76fbd45130 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ StatementAsExpression, }; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; @@ -1498,9 +1498,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { values = None; } struct OpaqueTypesVisitor<'tcx> { - types: FxHashMap>, - expected: FxHashMap>, - found: FxHashMap>, + types: FxIndexMap>, + expected: FxIndexMap>, + found: FxIndexMap>, ignore_span: Span, tcx: TyCtxt<'tcx>, } @@ -1538,7 +1538,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, err: &mut Diagnostic, target: &str, - types: &FxHashMap>, + types: &FxIndexMap>, ) { for (key, values) in types.iter() { let count = values.len(); @@ -3254,7 +3254,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if blk.expr.is_some() { return false; } - let mut shadowed = FxHashSet::default(); + let mut shadowed = FxIndexSet::default(); let mut candidate_idents = vec![]; let mut find_compatible_candidates = |pat: &hir::Pat<'_>| { if let hir::PatKind::Binding(_, hir_id, ident, _) = &pat.kind diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index c5f2a1a3f7dce..1067ccda20ca0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -9,7 +9,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::ObligationCauseCode; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; @@ -73,7 +73,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Next, let's figure out the set of trait objects with implicit static bounds let ty = self.tcx().type_of(*impl_def_id); - let mut v = super::static_impl_trait::TraitObjectVisitor(FxHashSet::default()); + let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(ty); let mut traits = vec![]; for matching_def_id in v.0 { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9bf755d7fcdf9..b4efe8da12592 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -4,7 +4,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, Visitor}; @@ -236,7 +236,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // lifetime as above, but called using a fully-qualified path to the method: // `Foo::qux(bar)`. - let mut v = TraitObjectVisitor(FxHashSet::default()); + let mut v = TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(param.param_ty); if let Some((ident, self_ty)) = self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0) @@ -408,7 +408,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { fn get_impl_ident_and_self_ty_from_trait( &self, def_id: DefId, - trait_objects: &FxHashSet, + trait_objects: &FxIndexSet, ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { let tcx = self.tcx(); match tcx.hir().get_if_local(def_id) { @@ -490,7 +490,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return false; }; - let mut v = TraitObjectVisitor(FxHashSet::default()); + let mut v = TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(ty); // Get the `Ident` of the method being called and the corresponding `impl` (to point at @@ -506,7 +506,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { fn suggest_constrain_dyn_trait_in_impl( &self, err: &mut Diagnostic, - found_dids: &FxHashSet, + found_dids: &FxIndexSet, ident: Ident, self_ty: &hir::Ty<'_>, ) -> bool { @@ -538,7 +538,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime. -pub struct TraitObjectVisitor(pub FxHashSet); +pub struct TraitObjectVisitor(pub FxIndexSet); impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index f1461d7010d5b..fd26d7d29c5ee 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -149,6 +149,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { region: ty::BoundRegionKind, ) -> bool { let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty); + // We are only checking is any region meets the condition so order doesn't matter + #[allow(rustc::potential_query_instability)] late_bound_regions.iter().any(|r| *r == region) } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 5f13b2b3deb1b..ba990acfe6fc4 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -842,6 +842,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // are placeholders as upper bounds, but the universe of the // variable `'a`, or some variable that `'a` has to outlive, doesn't // permit those placeholders. + // + // We only iterate to find the min, which means it doesn't cause reproducibility issues + #[allow(rustc::potential_query_instability)] let min_universe = lower_vid_bounds .into_iter() .map(|vid| self.var_infos[vid].universe) diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 90858e3072ac0..22b4bbb17d47f 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -1,6 +1,7 @@ use super::*; use crate::infer::CombinedSnapshot; use rustc_data_structures::{ + fx::FxIndexMap, graph::{scc::Sccs, vec_graph::VecGraph}, undo_log::UndoLogs, }; @@ -371,7 +372,7 @@ rustc_index::newtype_index! { /// an edge `R1 -> R2` in the graph. struct MiniGraph<'tcx> { /// Map from a region to the index of the node in the graph. - nodes: FxHashMap, LeakCheckNode>, + nodes: FxIndexMap, LeakCheckNode>, /// Map from node index to SCC, and stores the successors of each SCC. All /// the regions in the same SCC are equal to one another, and if `S1 -> S2`, @@ -388,7 +389,7 @@ impl<'tcx> MiniGraph<'tcx> { where 'tcx: 'a, { - let mut nodes = FxHashMap::default(); + let mut nodes = FxIndexMap::default(); let mut edges = Vec::new(); // Note that if `R2: R1`, we get a callback `r1, r2`, so `target` is first parameter. @@ -438,7 +439,7 @@ impl<'tcx> MiniGraph<'tcx> { } fn add_node( - nodes: &mut FxHashMap, LeakCheckNode>, + nodes: &mut FxIndexMap, LeakCheckNode>, r: ty::Region<'tcx>, ) -> LeakCheckNode { let l = nodes.len(); diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 67b3da687200e..985c5d360db8e 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::{ InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin, }; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; @@ -125,7 +125,7 @@ pub struct RegionConstraintData<'tcx> { /// we record the fact that `'a <= 'b` is implied by the fn /// signature, and then ignore the constraint when solving /// equations. This is a bit of a hack but seems to work. - pub givens: FxHashSet<(Region<'tcx>, ty::RegionVid)>, + pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>, } /// Represents a constraint that influences the inference process. diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index e040634edb088..4c119a443555e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -12,7 +12,6 @@ //! //! This API is completely unstable and subject to change. -#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index f8b5009a58d4b..4d53519581b37 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -1,7 +1,7 @@ use super::ObjectSafetyViolation; use crate::infer::InferCtxt; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -56,7 +56,7 @@ pub fn report_object_safety_error<'tcx>( ); err.span_label(span, format!("`{}` cannot be made into an object", trait_str)); - let mut reported_violations = FxHashSet::default(); + let mut reported_violations = FxIndexSet::default(); let mut multi_span = vec![]; let mut messages = vec![]; for violation in violations { From ac24d4204262b330a94cd98af67100dc82f66092 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 3 Sep 2022 18:06:25 -0400 Subject: [PATCH 193/482] Add a codegen test for rust-lang/rust#96152 --- src/test/assembly/strict_provenance.rs | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/test/assembly/strict_provenance.rs diff --git a/src/test/assembly/strict_provenance.rs b/src/test/assembly/strict_provenance.rs new file mode 100644 index 0000000000000..01f1957d5f667 --- /dev/null +++ b/src/test/assembly/strict_provenance.rs @@ -0,0 +1,37 @@ +// assembly-output: emit-asm +// compile-flags: -Copt-level=1 +// only-x86_64 +// min-llvm-version: 15.0 +#![crate_type = "rlib"] + +// CHECK-LABEL: old_style +// CHECK: movq %{{.*}}, %rax +// CHECK: orq $1, %rax +// CHECK: retq +#[no_mangle] +pub fn old_style(a: *mut u8) -> *mut u8 { + (a as usize | 1) as *mut u8 +} + +// CHECK-LABEL: cheri_compat +// CHECK: movq %{{.*}}, %rax +// CHECK: orq $1, %rax +// CHECK: retq +#[no_mangle] +pub fn cheri_compat(a: *mut u8) -> *mut u8 { + let old = a as usize; + let new = old | 1; + let diff = new.wrapping_sub(old); + a.wrapping_add(diff) +} + +// CHECK-LABEL: definitely_not_a_null_pointer +// CHECK: movq %{{.*}}, %rax +// CHECK: orq $1, %rax +// CHECK: retq +#[no_mangle] +pub fn definitely_not_a_null_pointer(a: *mut u8) -> *mut u8 { + let old = a as usize; + let new = old | 1; + a.wrapping_sub(old).wrapping_add(new) +} From f49f1fb6ae60273f0358fec6e84e1de9fd052434 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Sun, 30 Oct 2022 11:50:00 +0100 Subject: [PATCH 194/482] Mention const and lifetime parameters in error E0207 Error Index for E0207 must mention const and lifetime parameters. In addition, add code examples for these situations. Fixes #80862 --- .../src/error_codes/E0207.md | 75 ++++++++++++++++++- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0207.md b/compiler/rustc_error_codes/src/error_codes/E0207.md index 8a7923ac93f98..95e7c9fc76ce2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0207.md +++ b/compiler/rustc_error_codes/src/error_codes/E0207.md @@ -1,4 +1,5 @@ -A type parameter that is specified for `impl` is not constrained. +A type, const or lifetime parameter that is specified for `impl` is not +constrained. Erroneous code example: @@ -14,8 +15,8 @@ impl Foo { } ``` -Any type parameter of an `impl` must meet at least one of -the following criteria: +Any type or const parameter of an `impl` must meet at least one of the +following criteria: - it appears in the _implementing type_ of the impl, e.g. `impl Foo` - for a trait impl, it appears in the _implemented trait_, e.g. @@ -23,6 +24,9 @@ the following criteria: - it is bound as an associated type, e.g. `impl SomeTrait for T where T: AnotherTrait` +Any unconstrained lifetime parameter of an `impl` is not supported if the +lifetime parameter is used by an associated type. + ### Error example 1 Suppose we have a struct `Foo` and we would like to define some methods for it. @@ -32,7 +36,6 @@ The problem is that the parameter `T` does not appear in the implementing type (`Foo`) of the impl. In this case, we can fix the error by moving the type parameter from the `impl` to the method `get`: - ``` struct Foo; @@ -128,6 +131,70 @@ impl Maker> for FooMaker { } ``` +### Error example 3 + +Suppose we have a struct `Foo` and we would like to define some methods for it. +The following code example has a definition which leads to a compiler error: + +```compile_fail,E0207 +struct Foo; + +impl Foo { + // error: the const parameter `T` is not constrained by the impl trait, self + // type, or predicates [E0207] + fn get(&self) -> i32 { + i32::default() + } +} +``` + +The problem is that the const parameter `T` does not appear in the implementing +type (`Foo`) of the impl. In this case, we can fix the error by moving the type +parameter from the `impl` to the method `get`: + + +``` +struct Foo; + +// Move the const parameter from the impl to the method +impl Foo { + fn get(&self) -> i32 { + i32::default() + } +} +``` + +### Error example 4 + +Suppose we have a struct `Foo` and a struct `Bar` that uses lifetime `'a`. We +would like to implement trait `Contains` for `Foo`. The trait `Contains` have +the associated type `B`. The following code example has a definition which +leads to a compiler error: + +```compile_fail,E0207 +struct Foo; +struct Bar<'a>; + +trait Contains { + type B; + + fn get(&self) -> i32; +} + +impl<'a> Contains for Foo { + type B = Bar<'a>; + + // error: the lifetime parameter `'a` is not constrained by the impl trait, + // self type, or predicates [E0207] + fn get(&self) -> i32 { + i32::default() + } +} +``` + +Please note that unconstrained lifetime parameters are not supported if they are +being used by an associated type. + ### Additional information For more information, please see [RFC 447]. From fff77f6f45e9029fca1dfa1e50b80fe1f8c23fca Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 4 Nov 2022 21:16:20 +0000 Subject: [PATCH 195/482] Don't silently eat label before block in block-like expr --- .../rustc_parse/src/parser/diagnostics.rs | 12 +- src/test/ui/parser/label-after-block-like.rs | 43 +++++ .../ui/parser/label-after-block-like.stderr | 176 ++++++++++++++++++ 3 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/parser/label-after-block-like.rs create mode 100644 src/test/ui/parser/label-after-block-like.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7dc4fd0044f1f..c609aa93da3a7 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2468,11 +2468,15 @@ impl<'a> Parser<'a> { } pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool { - let Some(label) = self.eat_label().filter(|_| { - self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace) - }) else { + // Check for `'a : {` + if !(self.check_lifetime() + && self.look_ahead(1, |tok| tok.kind == token::Colon) + && self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Brace))) + { return false; - }; + } + let label = self.eat_label().expect("just checked if a label exists"); + self.bump(); // eat `:` let span = label.ident.span.to(self.prev_token.span); let mut err = self.struct_span_err(span, "block label not supported here"); err.span_label(span, "not supported here"); diff --git a/src/test/ui/parser/label-after-block-like.rs b/src/test/ui/parser/label-after-block-like.rs new file mode 100644 index 0000000000000..55f3f8f9f5f03 --- /dev/null +++ b/src/test/ui/parser/label-after-block-like.rs @@ -0,0 +1,43 @@ +fn a() { + if let () = () 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn b() { + if true 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn c() { + loop 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn d() { + while true 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn e() { + while let () = () 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn f() { + for _ in 0..0 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn g() { + unsafe 'a {} + //~^ ERROR labeled expression must be followed by `:` + //~| ERROR expected `{`, found `'a` +} + +fn main() {} diff --git a/src/test/ui/parser/label-after-block-like.stderr b/src/test/ui/parser/label-after-block-like.stderr new file mode 100644 index 0000000000000..8ff50b124b32b --- /dev/null +++ b/src/test/ui/parser/label-after-block-like.stderr @@ -0,0 +1,176 @@ +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:2:20 + | +LL | if let () = () 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:2:20 + | +LL | if let () = () 'a {} + | ^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/label-after-block-like.rs:2:8 + | +LL | if let () = () 'a {} + | ^^^^^^^^^^^ +help: try placing this code inside a block + | +LL | if let () = () { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:8:13 + | +LL | if true 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:8:13 + | +LL | if true 'a {} + | ^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/label-after-block-like.rs:8:8 + | +LL | if true 'a {} + | ^^^^ +help: try placing this code inside a block + | +LL | if true { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:14:10 + | +LL | loop 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:14:10 + | +LL | loop 'a {} + | ---- ^^ expected `{` + | | + | while parsing this `loop` expression + | +help: try placing this code inside a block + | +LL | loop { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:20:16 + | +LL | while true 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:20:16 + | +LL | while true 'a {} + | ----- ---- ^^ expected `{` + | | | + | | this `while` condition successfully parsed + | while parsing the body of this `while` expression + | +help: try placing this code inside a block + | +LL | while true { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:26:23 + | +LL | while let () = () 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:26:23 + | +LL | while let () = () 'a {} + | ----- ----------- ^^ expected `{` + | | | + | | this `while` condition successfully parsed + | while parsing the body of this `while` expression + | +help: try placing this code inside a block + | +LL | while let () = () { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:32:19 + | +LL | for _ in 0..0 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:32:19 + | +LL | for _ in 0..0 'a {} + | ^^ expected `{` + | +help: try placing this code inside a block + | +LL | for _ in 0..0 { 'a {} } + | + + + +error: labeled expression must be followed by `:` + --> $DIR/label-after-block-like.rs:38:12 + | +LL | unsafe 'a {} + | ---^^ + | | | + | | help: add `:` after the label + | the label + | + = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them + +error: expected `{`, found `'a` + --> $DIR/label-after-block-like.rs:38:12 + | +LL | unsafe 'a {} + | ------ ^^ expected `{` + | | + | while parsing this `unsafe` expression + | +help: try placing this code inside a block + | +LL | unsafe { 'a {} } + | + + + +error: aborting due to 14 previous errors + From 9cc7127140e4fce2781384df4fa223bc42ae06fb Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 5 Nov 2022 09:58:13 -0300 Subject: [PATCH 196/482] Move some tests to more reasonable directories --- src/test/ui/{issues => consts}/issue-54954.rs | 0 src/test/ui/{issues => consts}/issue-54954.stderr | 0 src/test/ui/{issues => dropck}/issue-54943-1.rs | 0 src/test/ui/{issues => dropck}/issue-54943-2.rs | 0 src/test/ui/{issues => match}/issue-12552.rs | 0 src/test/ui/{issues => match}/issue-12552.stderr | 0 src/test/ui/{issues => nll}/issue-54943.rs | 0 src/test/ui/{issues => nll}/issue-54943.stderr | 0 src/test/ui/{issues => typeck}/issue-10969.rs | 0 src/test/ui/{issues => typeck}/issue-10969.stderr | 0 src/test/ui/{issues => typeck}/issue-50687-ice-on-borrow.rs | 0 src/test/ui/{issues => typeck}/issue-50687-ice-on-borrow.stderr | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{issues => consts}/issue-54954.rs (100%) rename src/test/ui/{issues => consts}/issue-54954.stderr (100%) rename src/test/ui/{issues => dropck}/issue-54943-1.rs (100%) rename src/test/ui/{issues => dropck}/issue-54943-2.rs (100%) rename src/test/ui/{issues => match}/issue-12552.rs (100%) rename src/test/ui/{issues => match}/issue-12552.stderr (100%) rename src/test/ui/{issues => nll}/issue-54943.rs (100%) rename src/test/ui/{issues => nll}/issue-54943.stderr (100%) rename src/test/ui/{issues => typeck}/issue-10969.rs (100%) rename src/test/ui/{issues => typeck}/issue-10969.stderr (100%) rename src/test/ui/{issues => typeck}/issue-50687-ice-on-borrow.rs (100%) rename src/test/ui/{issues => typeck}/issue-50687-ice-on-borrow.stderr (100%) diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/consts/issue-54954.rs similarity index 100% rename from src/test/ui/issues/issue-54954.rs rename to src/test/ui/consts/issue-54954.rs diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/consts/issue-54954.stderr similarity index 100% rename from src/test/ui/issues/issue-54954.stderr rename to src/test/ui/consts/issue-54954.stderr diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/dropck/issue-54943-1.rs similarity index 100% rename from src/test/ui/issues/issue-54943-1.rs rename to src/test/ui/dropck/issue-54943-1.rs diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/dropck/issue-54943-2.rs similarity index 100% rename from src/test/ui/issues/issue-54943-2.rs rename to src/test/ui/dropck/issue-54943-2.rs diff --git a/src/test/ui/issues/issue-12552.rs b/src/test/ui/match/issue-12552.rs similarity index 100% rename from src/test/ui/issues/issue-12552.rs rename to src/test/ui/match/issue-12552.rs diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/match/issue-12552.stderr similarity index 100% rename from src/test/ui/issues/issue-12552.stderr rename to src/test/ui/match/issue-12552.stderr diff --git a/src/test/ui/issues/issue-54943.rs b/src/test/ui/nll/issue-54943.rs similarity index 100% rename from src/test/ui/issues/issue-54943.rs rename to src/test/ui/nll/issue-54943.rs diff --git a/src/test/ui/issues/issue-54943.stderr b/src/test/ui/nll/issue-54943.stderr similarity index 100% rename from src/test/ui/issues/issue-54943.stderr rename to src/test/ui/nll/issue-54943.stderr diff --git a/src/test/ui/issues/issue-10969.rs b/src/test/ui/typeck/issue-10969.rs similarity index 100% rename from src/test/ui/issues/issue-10969.rs rename to src/test/ui/typeck/issue-10969.rs diff --git a/src/test/ui/issues/issue-10969.stderr b/src/test/ui/typeck/issue-10969.stderr similarity index 100% rename from src/test/ui/issues/issue-10969.stderr rename to src/test/ui/typeck/issue-10969.stderr diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.rs b/src/test/ui/typeck/issue-50687-ice-on-borrow.rs similarity index 100% rename from src/test/ui/issues/issue-50687-ice-on-borrow.rs rename to src/test/ui/typeck/issue-50687-ice-on-borrow.rs diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr b/src/test/ui/typeck/issue-50687-ice-on-borrow.stderr similarity index 100% rename from src/test/ui/issues/issue-50687-ice-on-borrow.stderr rename to src/test/ui/typeck/issue-50687-ice-on-borrow.stderr From 24bf85bac64555ada94b631bbed07a6d1a82094a Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 5 Nov 2022 09:59:27 -0300 Subject: [PATCH 197/482] Tidy --- src/tools/tidy/src/ui_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index aee36f061c5d1..2b82e9b3f998c 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -9,8 +9,8 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 941; -const ISSUES_ENTRY_LIMIT: usize = 2117; +const ROOT_ENTRY_LIMIT: usize = 939; +const ISSUES_ENTRY_LIMIT: usize = 2105; fn check_entries(path: &Path, bad: &mut bool) { for dir in Walk::new(&path.join("test/ui")) { From 8423bda5b5a3a09549c008d5c98e819259da4be7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Nov 2022 01:59:03 +0000 Subject: [PATCH 198/482] Normalize signature when deducing closure signature from supertraits --- compiler/rustc_hir_typeck/src/closure.rs | 10 +++++++--- .../supertrait-hint-references-assoc-ty.rs | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/closures/supertrait-hint-references-assoc-ty.rs diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 09df50c76b738..3001e79947672 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -10,6 +10,7 @@ use rustc_hir_analysis::astconv::AstConv; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; +use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, Ty}; @@ -22,7 +23,7 @@ use std::cmp; use std::iter; /// What signature do we *expect* the closure to have from context? -#[derive(Debug)] +#[derive(Debug, Clone, TypeFoldable, TypeVisitable)] struct ExpectedSig<'tcx> { /// Span that gave us this expectation, if we know that. cause_span: Option, @@ -241,9 +242,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if expected_sig.is_none() && let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() { - expected_sig = self.deduce_sig_from_projection( + expected_sig = self.normalize_associated_types_in( + obligation.cause.span, + self.deduce_sig_from_projection( Some(obligation.cause.span), - bound_predicate.rebind(proj_predicate), + bound_predicate.rebind(proj_predicate), + ), ); } diff --git a/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs b/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs new file mode 100644 index 0000000000000..270bf14c35eca --- /dev/null +++ b/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs @@ -0,0 +1,17 @@ +// check-pass + +pub trait Fn0: Fn(i32) -> Self::Out { + type Out; +} + +impl ()> Fn0 for F { + type Out = (); +} + +pub fn closure_typer(_: impl Fn0) {} + +fn main() { + closure_typer(move |x| { + let _: i64 = x.into(); + }); +} From 73e547f24a78f312218608899c467f4925915ee1 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 6 Nov 2022 20:58:16 +0900 Subject: [PATCH 199/482] return `None` when def_kind is `DefKind::Use` --- src/librustdoc/passes/collect_intra_doc_links.rs | 3 ++- src/test/rustdoc-ui/issue-103997.rs | 6 ++++++ src/test/rustdoc-ui/issue-103997.stderr | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc-ui/issue-103997.rs create mode 100644 src/test/rustdoc-ui/issue-103997.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 0bd0dbbeb702c..37a28b6b7bd84 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -402,6 +402,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) .and_then(|self_id| match tcx.def_kind(self_id) { DefKind::Impl => self.def_id_to_res(self_id), + DefKind::Use => None, def_kind => Some(Res::Def(def_kind, self_id)), }) } @@ -1772,7 +1773,6 @@ fn resolution_failure( // Otherwise, it must be an associated item or variant let res = partial_res.expect("None case was handled by `last_found_module`"); - let name = res.name(tcx); let kind = match res { Res::Def(kind, _) => Some(kind), Res::Primitive(_) => None, @@ -1814,6 +1814,7 @@ fn resolution_failure( } else { "associated item" }; + let name = res.name(tcx); let note = format!( "the {} `{}` has no {} named `{}`", res.descr(), diff --git a/src/test/rustdoc-ui/issue-103997.rs b/src/test/rustdoc-ui/issue-103997.rs new file mode 100644 index 0000000000000..36f42fb15f7e4 --- /dev/null +++ b/src/test/rustdoc-ui/issue-103997.rs @@ -0,0 +1,6 @@ +// check-pass + +pub fn foo() {} + +/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo` +pub use foo as bar; diff --git a/src/test/rustdoc-ui/issue-103997.stderr b/src/test/rustdoc-ui/issue-103997.stderr new file mode 100644 index 0000000000000..c06db91496f86 --- /dev/null +++ b/src/test/rustdoc-ui/issue-103997.stderr @@ -0,0 +1,10 @@ +warning: unresolved link to `Self::foo` + --> $DIR/issue-103997.rs:5:13 + | +LL | /// [`foo`](Self::foo) + | ^^^^^^^^^ no item named `Self` in scope + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + From fee805b100708b7907e5c28694aec50a8275cd6e Mon Sep 17 00:00:00 2001 From: wanghaha-dev Date: Mon, 7 Nov 2022 14:33:33 +0800 Subject: [PATCH 200/482] Modify comment syntax error --- compiler/rustc_macros/src/diagnostics/error.rs | 4 ++-- library/alloc/src/collections/mod.rs | 2 +- .../ui/conditional-compilation/cfg_accessible-not_sure.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index 0b1ededa77510..4612f54e4b176 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -84,7 +84,7 @@ pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic { } } -/// Emit a error diagnostic for an invalid attribute (optionally performing additional decoration +/// Emit an error diagnostic for an invalid attribute (optionally performing additional decoration /// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. /// /// For methods that return a `Result<_, DiagnosticDeriveError>`: @@ -126,7 +126,7 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag } } -/// Emit a error diagnostic for an invalid nested attribute (optionally performing additional +/// Emit an error diagnostic for an invalid nested attribute (optionally performing additional /// decoration using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. /// /// For methods that return a `Result<_, DiagnosticDeriveError>`: diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 161a375736c65..3e0b0f735508e 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -139,7 +139,7 @@ impl Display for TryReserveError { " because the computed capacity exceeded the collection's maximum" } TryReserveErrorKind::AllocError { .. } => { - " because the memory allocator returned a error" + " because the memory allocator returned an error" } }; fmt.write_str(reason) diff --git a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs index d68acd2451fba..99a7949db173c 100644 --- a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs +++ b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs @@ -46,7 +46,7 @@ const C: bool = true; trait Trait {} impl dyn Trait { fn existing() {} } -// FIXME: Should be a error for edition > 2015 +// FIXME: Should be an error for edition > 2015 #[cfg_accessible(Trait::existing)] //~ ERROR not sure const A: bool = true; #[cfg_accessible(Trait::unresolved)] //~ ERROR not sure From da0b28e7fe1cb38c791c8e73f457c859d5aa0252 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Oct 2022 10:28:46 +0100 Subject: [PATCH 201/482] skip bootstrap target sanity checks when testing Miri --- src/bootstrap/sanity.rs | 10 ++++++++++ .../docker/host-x86_64/x86_64-gnu-tools/checktools.sh | 11 ++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index e905517253c0a..9890480709bd7 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -155,6 +155,11 @@ than building it. continue; } + // Some environments don't want or need these tools, such as when testing Miri. + if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { + continue; + } + if !build.config.dry_run { cmd_finder.must_have(build.cc(*target)); if let Some(ar) = build.ar(*target) { @@ -212,6 +217,11 @@ than building it. } } + // Some environments don't want or need these tools, such as when testing Miri. + if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { + continue; + } + if need_cmake && target.contains("msvc") { // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh index d87384556106d..7dde6370904bb 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh @@ -27,10 +27,7 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt python3 "$X_PY" test --stage 2 src/tools/miri # We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc. # Also cover some other targets (on both of these hosts) via cross-testing. -# -# Currently disabled -- we end up pulling in a cross-compile of LLVM (maybe -# just overly eager sanity checks), but in any case this won't work when -# building LLVM as of this comment. -#python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc -#FIXME(https://github.com/rust-lang/rust/issues/103519): macOS testing is currently disabled -# python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin +export BOOTSTRAP_SKIP_TARGET_SANITY=1 # we don't need `cc` for these targets +python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc +python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin +unset BOOTSTRAP_SKIP_TARGET_SANITY From f22ad71cb7cdf61addb925894d353ff1bfe38345 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Nov 2022 09:14:49 +0100 Subject: [PATCH 202/482] add FIXME to replace this env var in the future --- src/bootstrap/sanity.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 9890480709bd7..bdfd5fe5c421c 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -156,6 +156,9 @@ than building it. } // Some environments don't want or need these tools, such as when testing Miri. + // FIXME: it would be better to refactor this code to split necessary setup from pure sanity + // checks, and have a regular flag for skipping the latter. Also see + // . if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { continue; } @@ -218,6 +221,9 @@ than building it. } // Some environments don't want or need these tools, such as when testing Miri. + // FIXME: it would be better to refactor this code to split necessary setup from pure sanity + // checks, and have a regular flag for skipping the latter. Also see + // . if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { continue; } From 5d2c545365e1dc4d06f2e25bd52a7fcaf68a79ef Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 3 Nov 2022 10:10:15 -0700 Subject: [PATCH 203/482] std: sync "Dependencies of the `backtrace` crate" with `backtrace` Compare: https://github.com/rust-lang/backtrace-rs/blob/07872f28cd8a65c3c7428811548dc85f1f2fb05b/Cargo.toml#L43 https://github.com/rust-lang/rust/blob/160b19429523ea44c4c3b7cad4233b2a35f58b8f/library/std/Cargo.toml#L26 --- Cargo.lock | 76 ++++++++++++++---------------------------- library/std/Cargo.toml | 6 ++-- 2 files changed, 28 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f230f50212a3b..28684a310a3c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,40 +4,31 @@ version = 3 [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "compiler_builtins", - "gimli 0.25.0", + "gimli", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli 0.26.1", -] - [[package]] name = "adler" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" -dependencies = [ - "compiler_builtins", - "rustc-std-workspace-core", -] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] [[package]] name = "ahash" @@ -185,12 +176,12 @@ version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ - "addr2line 0.17.0", + "addr2line", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide 0.5.3", - "object 0.29.0", + "object", "rustc-demangle", ] @@ -1545,25 +1536,17 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] -[[package]] -name = "gimli" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" -dependencies = [ - "compiler_builtins", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", -] - [[package]] name = "gimli" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" dependencies = [ + "compiler_builtins", "fallible-iterator", "indexmap", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", "stable_deref_trait", ] @@ -2233,9 +2216,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" dependencies = [ "adler 0.2.3", - "compiler_builtins", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", ] [[package]] @@ -2245,6 +2225,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler 1.0.2", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -2346,29 +2329,20 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "compiler_builtins", - "memchr", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", -] - [[package]] name = "object" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ + "compiler_builtins", "crc32fast", "flate2", "hashbrown", "indexmap", "memchr", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -3305,7 +3279,7 @@ dependencies = [ "cstr", "libc", "measureme", - "object 0.29.0", + "object", "rustc-demangle", "rustc_ast", "rustc_attr", @@ -3339,7 +3313,7 @@ dependencies = [ "itertools", "jobserver", "libc", - "object 0.29.0", + "object", "pathdiff", "regex", "rustc_arena", @@ -4698,7 +4672,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" name = "std" version = "0.0.0" dependencies = [ - "addr2line 0.16.0", + "addr2line", "alloc", "cfg-if 1.0.0", "compiler_builtins", @@ -4708,8 +4682,8 @@ dependencies = [ "hashbrown", "hermit-abi 0.2.6", "libc", - "miniz_oxide 0.4.0", - "object 0.26.2", + "miniz_oxide 0.5.3", + "object", "panic_abort", "panic_unwind", "profiler_builtins", @@ -4926,9 +4900,9 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6cb0c7868d7f90407531108ab03263d9452a8811b7cdd87675343a40d4aa254" dependencies = [ - "gimli 0.26.1", + "gimli", "hashbrown", - "object 0.29.0", + "object", "tracing", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index bc10b12ec2af9..daa6976c30143 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -23,11 +23,11 @@ hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate -addr2line = { version = "0.16.0", optional = true, default-features = false } +addr2line = { version = "0.17.0", optional = true, default-features = false } rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] } -miniz_oxide = { version = "0.4.0", optional = true, default-features = false } +miniz_oxide = { version = "0.5.0", optional = true, default-features = false } [dependencies.object] -version = "0.26.1" +version = "0.29.0" optional = true default-features = false features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] From 1e02dc84bd7dcf17627fa35268266e39dcbcd6fb Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 5 Nov 2022 09:02:10 -0700 Subject: [PATCH 204/482] rustdoc: use `ThinVec` and `Box` to shrink `clean::ItemKind` --- src/librustdoc/clean/inline.rs | 4 ++-- src/librustdoc/clean/mod.rs | 8 ++++---- src/librustdoc/clean/types.rs | 14 +++++++------- src/librustdoc/clean/utils.rs | 4 ++-- src/librustdoc/json/conversions.rs | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8a5463c10f210..3fc4aae923a60 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -3,7 +3,7 @@ use std::iter::once; use std::sync::Arc; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; @@ -605,7 +605,7 @@ fn build_module_items( clean::ImportSource { path: clean::Path { res, - segments: vec![clean::PathSegment { + segments: thin_vec![clean::PathSegment { name: prim_ty.as_sym(), args: clean::GenericArgs::AngleBracketed { args: Default::default(), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 19276b9b187a0..56a873e3e8236 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -226,7 +226,7 @@ pub(crate) fn clean_middle_const<'tcx>( // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { type_: clean_middle_ty(constant.ty(), cx, None), - kind: ConstantKind::TyConst { expr: constant.to_string() }, + kind: ConstantKind::TyConst { expr: constant.to_string().into() }, } } @@ -1215,7 +1215,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( true } (GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind { - ConstantKind::TyConst { expr } => expr == param.name.as_str(), + ConstantKind::TyConst { expr } => **expr == *param.name.as_str(), _ => false, }, _ => false, @@ -1554,7 +1554,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } }; - Array(Box::new(clean_ty(ty, cx)), length) + Array(Box::new(clean_ty(ty, cx)), length.into()) } TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()), TyKind::OpaqueDef(item_id, _, _) => { @@ -1626,7 +1626,7 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::Array(ty, mut n) => { n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); let n = print_const(cx, n); - Array(Box::new(clean_middle_ty(ty, cx, None)), n) + Array(Box::new(clean_middle_ty(ty, cx, None)), n.into()) } ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(clean_middle_ty(mt.ty, cx, None))), ty::Ref(r, ty, mutbl) => BorrowedRef { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bbedfdd0eafe0..3d13f7463cbb0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1625,7 +1625,7 @@ pub(crate) enum Type { /// An array type. /// /// The `String` field is a stringified version of the array's length parameter. - Array(Box, String), + Array(Box, Box), /// A raw pointer type: `*const i32`, `*mut i32` RawPointer(Mutability, Box), /// A reference type: `&i32`, `&'a mut Foo` @@ -2210,7 +2210,7 @@ impl Span { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) struct Path { pub(crate) res: Res, - pub(crate) segments: Vec, + pub(crate) segments: ThinVec, } impl Path { @@ -2360,7 +2360,7 @@ pub(crate) enum ConstantKind { /// /// Note that `ty::Const` includes generic parameters, and may not always be uniquely identified /// by a DefId. So this field must be different from `Extern`. - TyConst { expr: String }, + TyConst { expr: Box }, /// A constant (expression) that's not an item or associated item. These are usually found /// nested inside types (e.g., array lengths) or expressions (e.g., repeat counts), and also /// used to define explicit discriminant values for enum variants. @@ -2388,7 +2388,7 @@ impl Constant { impl ConstantKind { pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String { match *self { - ConstantKind::TyConst { ref expr } => expr.clone(), + ConstantKind::TyConst { ref expr } => expr.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { print_const_expr(tcx, body) @@ -2574,13 +2574,13 @@ mod size_asserts { // tidy-alphabetical-start static_assert_size!(Crate, 72); // frequently moved by-value static_assert_size!(DocFragment, 32); - static_assert_size!(GenericArg, 48); + static_assert_size!(GenericArg, 32); static_assert_size!(GenericArgs, 32); static_assert_size!(GenericParamDef, 56); static_assert_size!(Generics, 16); static_assert_size!(Item, 56); - static_assert_size!(ItemKind, 88); + static_assert_size!(ItemKind, 64); static_assert_size!(PathSegment, 40); - static_assert_size!(Type, 48); + static_assert_size!(Type, 32); // tidy-alphabetical-end } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 824d98113c8f3..38e946002c034 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::Write as _; use std::mem; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; #[cfg(test)] mod tests; @@ -136,7 +136,7 @@ pub(super) fn external_path<'tcx>( let name = cx.tcx.item_name(did); Path { res: Res::Def(def_kind, did), - segments: vec![PathSegment { + segments: thin_vec![PathSegment { name, args: external_generic_args(cx, did, has_self, bindings, substs), }], diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index cb8b7c18029f0..091a1ba70cab7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -485,7 +485,7 @@ impl FromWithTcx for Type { BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))), Tuple(t) => Type::Tuple(t.into_tcx(tcx)), Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))), - Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s }, + Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s.to_string() }, ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)), Infer => Type::Infer, RawPointer(mutability, type_) => Type::RawPointer { From a9fd2304d57e0f0a5adc122a9209556a6b034537 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 5 Nov 2022 16:55:40 -0700 Subject: [PATCH 205/482] rustdoc: print usize with less string manipulation --- src/librustdoc/clean/utils.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 38e946002c034..21f8fbe36f173 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -242,19 +242,13 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { s } - _ => { - let mut s = n.to_string(); - // array lengths are obviously usize - if s.ends_with("_usize") { - let n = s.len() - "_usize".len(); - s.truncate(n); - if s.ends_with(": ") { - let n = s.len() - ": ".len(); - s.truncate(n); - } - } - s + // array lengths are obviously usize + ty::ConstKind::Value(ty::ValTree::Leaf(scalar)) + if *n.ty().kind() == ty::Uint(ty::UintTy::Usize) => + { + scalar.to_string() } + _ => n.to_string(), } } From 233cf342496a43f25bab9762e18caafe1790b240 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 20:20:38 +0100 Subject: [PATCH 206/482] Remove one lifetime from `QueryKeyStringBuilder` --- .../rustc_query_impl/src/profiling_support.rs | 51 ++++++------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 2cc311d48c8f6..81114f2cd82c3 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -19,18 +19,18 @@ impl QueryKeyStringCache { } } -struct QueryKeyStringBuilder<'p, 'c, 'tcx> { +struct QueryKeyStringBuilder<'p, 'tcx> { profiler: &'p SelfProfiler, tcx: TyCtxt<'tcx>, - string_cache: &'c mut QueryKeyStringCache, + string_cache: &'p mut QueryKeyStringCache, } -impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { +impl<'p, 'tcx> QueryKeyStringBuilder<'p, 'tcx> { fn new( profiler: &'p SelfProfiler, tcx: TyCtxt<'tcx>, - string_cache: &'c mut QueryKeyStringCache, - ) -> QueryKeyStringBuilder<'p, 'c, 'tcx> { + string_cache: &'p mut QueryKeyStringCache, + ) -> QueryKeyStringBuilder<'p, 'tcx> { QueryKeyStringBuilder { profiler, tcx, string_cache } } @@ -99,7 +99,7 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { } trait IntoSelfProfilingString { - fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId; + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId; } // The default implementation of `IntoSelfProfilingString` just uses `Debug` @@ -109,7 +109,7 @@ trait IntoSelfProfilingString { impl IntoSelfProfilingString for T { default fn to_self_profile_string( &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, + builder: &mut QueryKeyStringBuilder<'_, '_>, ) -> StringId { let s = format!("{:?}", self); builder.profiler.alloc_string(&s[..]) @@ -117,60 +117,42 @@ impl IntoSelfProfilingString for T { } impl IntoSelfProfilingString for T { - fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { + fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { self.spec_to_self_profile_string(builder) } } #[rustc_specialization_trait] trait SpecIntoSelfProfilingString: Debug { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId; + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId; } impl SpecIntoSelfProfilingString for DefId { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { builder.def_id_to_string_id(*self) } } impl SpecIntoSelfProfilingString for CrateNum { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { builder.def_id_to_string_id(self.as_def_id()) } } impl SpecIntoSelfProfilingString for DefIndex { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: *self }) } } impl SpecIntoSelfProfilingString for LocalDefId { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: self.local_def_index }) } } impl SpecIntoSelfProfilingString for WithOptConstParam { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { // We print `WithOptConstParam` values as tuples to make them shorter // and more readable, without losing information: // @@ -205,10 +187,7 @@ where T0: SpecIntoSelfProfilingString, T1: SpecIntoSelfProfilingString, { - fn spec_to_self_profile_string( - &self, - builder: &mut QueryKeyStringBuilder<'_, '_, '_>, - ) -> StringId { + fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { let val0 = self.0.to_self_profile_string(builder); let val1 = self.1.to_self_profile_string(builder); From 905810da30057f0663fdc2d75f63d2050474e904 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 20:26:41 +0100 Subject: [PATCH 207/482] Rename `incremental_verify_ich_cold` to `incremental_verify_ich_failed` --- .../rustc_query_system/src/query/plumbing.rs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 0f7abe84231b6..f2abbdae5837f 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -585,7 +585,11 @@ fn incremental_verify_ich( debug!("END verify_ich({:?})", dep_node); if Some(new_hash) != old_hash { - incremental_verify_ich_cold(tcx.sess(), DebugArg::from(&dep_node), DebugArg::from(&result)); + incremental_verify_ich_failed( + tcx.sess(), + DebugArg::from(&dep_node), + DebugArg::from(&result), + ); } } @@ -631,13 +635,7 @@ impl std::fmt::Debug for DebugArg<'_> { // different implementations for LLVM to chew on (and filling up the final // binary, too). #[cold] -fn incremental_verify_ich_cold(sess: &Session, dep_node: DebugArg<'_>, result: DebugArg<'_>) { - let run_cmd = if let Some(crate_name) = &sess.opts.crate_name { - format!("`cargo clean -p {}` or `cargo clean`", crate_name) - } else { - "`cargo clean`".to_string() - }; - +fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: DebugArg<'_>) { // When we emit an error message and panic, we try to debug-print the `DepNode` // and query result. Unfortunately, this can cause us to run additional queries, // which may result in another fingerprint mismatch while we're in the middle @@ -653,6 +651,12 @@ fn incremental_verify_ich_cold(sess: &Session, dep_node: DebugArg<'_>, result: D if old_in_panic { sess.emit_err(crate::error::Reentrant); } else { + let run_cmd = if let Some(crate_name) = &sess.opts.crate_name { + format!("`cargo clean -p {}` or `cargo clean`", crate_name) + } else { + "`cargo clean`".to_string() + }; + sess.emit_err(crate::error::IncrementCompilation { run_cmd, dep_node: format!("{:?}", dep_node), From c41b2b0e786fe77a4e3986b5eeb88432b842e5ab Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 20:40:42 +0100 Subject: [PATCH 208/482] Improve tracing logging --- .../rustc_query_system/src/dep_graph/graph.rs | 53 +++++-------------- .../rustc_query_system/src/dep_graph/mod.rs | 3 +- .../rustc_query_system/src/query/plumbing.rs | 4 +- 3 files changed, 17 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 8ff56132749df..7109c1ac9a202 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -598,6 +598,7 @@ impl DepGraph { } } + #[instrument(skip(self, tcx, data, parent_dep_node_index), level = "debug")] fn try_mark_parent_green>( &self, tcx: Ctxt, @@ -613,11 +614,7 @@ impl DepGraph { // This dependency has been marked as green before, we are // still fine and can continue with checking the other // dependencies. - debug!( - "try_mark_previous_green({:?}) --- found dependency {:?} to \ - be immediately green", - dep_node, dep_dep_node, - ); + debug!("dependency {dep_dep_node:?} was immediately green"); return Some(()); } Some(DepNodeColor::Red) => { @@ -625,10 +622,7 @@ impl DepGraph { // compared to the previous compilation session. We cannot // mark the DepNode as green and also don't need to bother // with checking any of the other dependencies. - debug!( - "try_mark_previous_green({:?}) - END - dependency {:?} was immediately red", - dep_node, dep_dep_node, - ); + debug!("dependency {dep_dep_node:?} was immediately red"); return None; } None => {} @@ -638,33 +632,24 @@ impl DepGraph { // an eval_always node, let's try to mark it green recursively. if !tcx.dep_context().is_eval_always(dep_dep_node.kind) { debug!( - "try_mark_previous_green({:?}) --- state of dependency {:?} ({}) \ - is unknown, trying to mark it green", - dep_node, dep_dep_node, dep_dep_node.hash, + "state of dependency {:?} ({}) is unknown, trying to mark it green", + dep_dep_node, dep_dep_node.hash, ); let node_index = self.try_mark_previous_green(tcx, data, parent_dep_node_index, dep_dep_node); + if node_index.is_some() { - debug!( - "try_mark_previous_green({:?}) --- managed to MARK dependency {:?} as green", - dep_node, dep_dep_node - ); + debug!("managed to MARK dependency {dep_dep_node:?} as green",); return Some(()); } } // We failed to mark it green, so we try to force the query. - debug!( - "try_mark_previous_green({:?}) --- trying to force dependency {:?}", - dep_node, dep_dep_node - ); + debug!("trying to force dependency {dep_dep_node:?}"); if !tcx.dep_context().try_force_from_dep_node(*dep_dep_node) { // The DepNode could not be forced. - debug!( - "try_mark_previous_green({:?}) - END - dependency {:?} could not be forced", - dep_node, dep_dep_node - ); + debug!("dependency {dep_dep_node:?} could not be forced"); return None; } @@ -672,17 +657,11 @@ impl DepGraph { match dep_dep_node_color { Some(DepNodeColor::Green(_)) => { - debug!( - "try_mark_previous_green({:?}) --- managed to FORCE dependency {:?} to green", - dep_node, dep_dep_node - ); + debug!("managed to FORCE dependency {dep_dep_node:?} to green"); return Some(()); } Some(DepNodeColor::Red) => { - debug!( - "try_mark_previous_green({:?}) - END - dependency {:?} was red after forcing", - dep_node, dep_dep_node - ); + debug!("dependency {dep_dep_node:?} was red after forcing",); return None; } None => {} @@ -702,14 +681,12 @@ impl DepGraph { // invalid state will not be persisted to the // incremental compilation cache because of // compilation errors being present. - debug!( - "try_mark_previous_green({:?}) - END - dependency {:?} resulted in compilation error", - dep_node, dep_dep_node - ); + debug!("dependency {dep_dep_node:?} resulted in compilation error",); return None; } /// Try to mark a dep-node which existed in the previous compilation session as green. + #[instrument(skip(self, tcx, data, prev_dep_node_index), level = "debug")] fn try_mark_previous_green>( &self, tcx: Ctxt, @@ -717,8 +694,6 @@ impl DepGraph { prev_dep_node_index: SerializedDepNodeIndex, dep_node: &DepNode, ) -> Option { - debug!("try_mark_previous_green({:?}) - BEGIN", dep_node); - #[cfg(not(parallel_compiler))] { debug_assert!(!self.dep_node_exists(dep_node)); @@ -772,7 +747,7 @@ impl DepGraph { // Multiple threads can all write the same color here data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); - debug!("try_mark_previous_green({:?}) - END - successfully marked as green", dep_node); + debug!("successfully marked {dep_node:?} as green"); Some(dep_node_index) } diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index da2075fd5aada..e370c6990a413 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -52,9 +52,8 @@ pub trait DepContext: Copy { } /// Try to force a dep node to execute and see if it's green. + #[instrument(skip(self), level = "debug")] fn try_force_from_dep_node(self, dep_node: DepNode) -> bool { - debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node); - let cb = self.dep_kind_info(dep_node.kind); if let Some(f) = cb.force_from_dep_node { f(self, dep_node); diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index f2abbdae5837f..e9972a5420941 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -563,6 +563,7 @@ where Some((result, dep_node_index)) } +#[instrument(skip(tcx, result, query), level = "debug")] fn incremental_verify_ich( tcx: CTX::DepContext, result: &V, @@ -577,12 +578,11 @@ fn incremental_verify_ich( dep_node, ); - debug!("BEGIN verify_ich({:?})", dep_node); let new_hash = query.hash_result.map_or(Fingerprint::ZERO, |f| { tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) }); + let old_hash = tcx.dep_graph().prev_fingerprint_of(dep_node); - debug!("END verify_ich({:?})", dep_node); if Some(new_hash) != old_hash { incremental_verify_ich_failed( From 31199e33f9c9cedca26af207b4e7e201e16a457a Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 20:58:10 +0100 Subject: [PATCH 209/482] Rename `tcx` to `qcx` when it's a `QueryContext` --- .../rustc_query_system/src/dep_graph/graph.rs | 38 ++--- compiler/rustc_query_system/src/query/job.rs | 4 +- .../rustc_query_system/src/query/plumbing.rs | 146 +++++++++--------- 3 files changed, 94 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 7109c1ac9a202..e856e39bf212a 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -573,10 +573,10 @@ impl DepGraph { /// a node index can be found for that node. pub fn try_mark_green>( &self, - tcx: Ctxt, + qcx: Ctxt, dep_node: &DepNode, ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { - debug_assert!(!tcx.dep_context().is_eval_always(dep_node.kind)); + debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind)); // Return None if the dep graph is disabled let data = self.data.as_ref()?; @@ -592,16 +592,16 @@ impl DepGraph { // in the previous compilation session too, so we can try to // mark it as green by recursively marking all of its // dependencies green. - self.try_mark_previous_green(tcx, data, prev_index, &dep_node) + self.try_mark_previous_green(qcx, data, prev_index, &dep_node) .map(|dep_node_index| (prev_index, dep_node_index)) } } } - #[instrument(skip(self, tcx, data, parent_dep_node_index), level = "debug")] + #[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")] fn try_mark_parent_green>( &self, - tcx: Ctxt, + qcx: Ctxt, data: &DepGraphData, parent_dep_node_index: SerializedDepNodeIndex, dep_node: &DepNode, @@ -630,14 +630,14 @@ impl DepGraph { // We don't know the state of this dependency. If it isn't // an eval_always node, let's try to mark it green recursively. - if !tcx.dep_context().is_eval_always(dep_dep_node.kind) { + if !qcx.dep_context().is_eval_always(dep_dep_node.kind) { debug!( "state of dependency {:?} ({}) is unknown, trying to mark it green", dep_dep_node, dep_dep_node.hash, ); let node_index = - self.try_mark_previous_green(tcx, data, parent_dep_node_index, dep_dep_node); + self.try_mark_previous_green(qcx, data, parent_dep_node_index, dep_dep_node); if node_index.is_some() { debug!("managed to MARK dependency {dep_dep_node:?} as green",); @@ -647,7 +647,7 @@ impl DepGraph { // We failed to mark it green, so we try to force the query. debug!("trying to force dependency {dep_dep_node:?}"); - if !tcx.dep_context().try_force_from_dep_node(*dep_dep_node) { + if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node) { // The DepNode could not be forced. debug!("dependency {dep_dep_node:?} could not be forced"); return None; @@ -667,7 +667,7 @@ impl DepGraph { None => {} } - if !tcx.dep_context().sess().has_errors_or_delayed_span_bugs() { + if !qcx.dep_context().sess().has_errors_or_delayed_span_bugs() { panic!("try_mark_previous_green() - Forcing the DepNode should have set its color") } @@ -686,10 +686,10 @@ impl DepGraph { } /// Try to mark a dep-node which existed in the previous compilation session as green. - #[instrument(skip(self, tcx, data, prev_dep_node_index), level = "debug")] + #[instrument(skip(self, qcx, data, prev_dep_node_index), level = "debug")] fn try_mark_previous_green>( &self, - tcx: Ctxt, + qcx: Ctxt, data: &DepGraphData, prev_dep_node_index: SerializedDepNodeIndex, dep_node: &DepNode, @@ -701,14 +701,14 @@ impl DepGraph { } // We never try to mark eval_always nodes as green - debug_assert!(!tcx.dep_context().is_eval_always(dep_node.kind)); + debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind)); debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node); let prev_deps = data.previous.edge_targets_from(prev_dep_node_index); for &dep_dep_node_index in prev_deps { - self.try_mark_parent_green(tcx, data, dep_dep_node_index, dep_node)? + self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node)? } // If we got here without hitting a `return` that means that all @@ -720,7 +720,7 @@ impl DepGraph { // We allocating an entry for the node in the current dependency graph and // adding all the appropriate edges imported from the previous graph let dep_node_index = data.current.promote_node_and_deps_to_current( - tcx.dep_context().profiler(), + qcx.dep_context().profiler(), &data.previous, prev_dep_node_index, ); @@ -729,7 +729,7 @@ impl DepGraph { // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere // Maybe store a list on disk and encode this fact in the DepNodeState - let side_effects = tcx.load_side_effects(prev_dep_node_index); + let side_effects = qcx.load_side_effects(prev_dep_node_index); #[cfg(not(parallel_compiler))] debug_assert!( @@ -740,7 +740,7 @@ impl DepGraph { ); if !side_effects.is_empty() { - self.emit_side_effects(tcx, data, dep_node_index, side_effects); + self.emit_side_effects(qcx, data, dep_node_index, side_effects); } // ... and finally storing a "Green" entry in the color map. @@ -757,7 +757,7 @@ impl DepGraph { #[inline(never)] fn emit_side_effects>( &self, - tcx: Ctxt, + qcx: Ctxt, data: &DepGraphData, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects, @@ -769,9 +769,9 @@ impl DepGraph { // must process side effects // Promote the previous diagnostics to the current session. - tcx.store_side_effects(dep_node_index, side_effects.clone()); + qcx.store_side_effects(dep_node_index, side_effects.clone()); - let handle = tcx.dep_context().sess().diagnostic(); + let handle = qcx.dep_context().sess().diagnostic(); for mut diagnostic in side_effects.diagnostics { handle.emit_diagnostic(&mut diagnostic); diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index ed65393f57e4d..bd21b5465e2f4 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -597,7 +597,7 @@ pub(crate) fn report_cycle<'a>( } pub fn print_query_stack( - tcx: CTX, + qcx: CTX, mut current_query: Option, handler: &Handler, num_frames: Option, @@ -606,7 +606,7 @@ pub fn print_query_stack( // a panic hook, which means that the global `Handler` may be in a weird // state if it was responsible for triggering the panic. let mut i = 0; - let query_map = tcx.try_collect_active_jobs(); + let query_map = qcx.try_collect_active_jobs(); while let Some(query) = current_query { if Some(i) == num_frames { diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index e9972a5420941..6348bc6b3afaf 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -64,7 +64,7 @@ where pub fn try_collect_active_jobs( &self, - tcx: CTX, + qcx: CTX, make_query: fn(CTX, K) -> QueryStackFrame, jobs: &mut QueryMap, ) -> Option<()> { @@ -76,7 +76,7 @@ where for shard in shards.iter() { for (k, v) in shard.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(tcx, k.clone()); + let query = make_query(qcx, k.clone()); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -90,7 +90,7 @@ where // really hurt much.) for (k, v) in self.active.try_lock()?.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(tcx, k.clone()); + let query = make_query(qcx, k.clone()); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -120,7 +120,7 @@ where #[cold] #[inline(never)] fn mk_cycle( - tcx: CTX, + qcx: CTX, cycle_error: CycleError, handler: HandleCycleError, cache: &dyn crate::query::QueryStorage, @@ -130,8 +130,8 @@ where V: std::fmt::Debug + Value, R: Clone, { - let error = report_cycle(tcx.dep_context().sess(), &cycle_error); - let value = handle_cycle_error(*tcx.dep_context(), &cycle_error, error, handler); + let error = report_cycle(qcx.dep_context().sess(), &cycle_error); + let value = handle_cycle_error(*qcx.dep_context(), &cycle_error, error, handler); cache.store_nocache(value) } @@ -177,7 +177,7 @@ where /// for some compile-time benchmarks. #[inline(always)] fn try_start<'b, CTX>( - tcx: &'b CTX, + qcx: &'b CTX, state: &'b QueryState, span: Span, key: K, @@ -193,8 +193,8 @@ where match lock.entry(key) { Entry::Vacant(entry) => { - let id = tcx.next_job_id(); - let job = tcx.current_query_job(); + let id = qcx.next_job_id(); + let job = qcx.current_query_job(); let job = QueryJob::new(id, span, job); let key = entry.key().clone(); @@ -213,8 +213,8 @@ where // If we are single-threaded we know that we have cycle error, // so we just return the error. return TryGetJob::Cycle(id.find_cycle_in_stack( - tcx.try_collect_active_jobs().unwrap(), - &tcx.current_query_job(), + qcx.try_collect_active_jobs().unwrap(), + &qcx.current_query_job(), span, )); } @@ -223,7 +223,7 @@ where // For parallel queries, we'll block and wait until the query running // in another thread has completed. Record how long we wait in the // self-profiler. - let query_blocked_prof_timer = tcx.dep_context().profiler().query_blocked(); + let query_blocked_prof_timer = qcx.dep_context().profiler().query_blocked(); // Get the latch out let latch = job.latch(); @@ -232,7 +232,7 @@ where // With parallel queries we might just have to wait on some other // thread. - let result = latch.wait_on(tcx.current_query_job(), span); + let result = latch.wait_on(qcx.current_query_job(), span); match result { Ok(()) => TryGetJob::JobCompleted(query_blocked_prof_timer), @@ -357,7 +357,7 @@ where } fn try_execute_query( - tcx: CTX, + qcx: CTX, state: &QueryState, cache: &C, span: Span, @@ -371,14 +371,14 @@ where C::Value: Value, CTX: QueryContext, { - match JobOwner::<'_, C::Key>::try_start(&tcx, state, span, key.clone()) { + match JobOwner::<'_, C::Key>::try_start(&qcx, state, span, key.clone()) { TryGetJob::NotYetStarted(job) => { - let (result, dep_node_index) = execute_job(tcx, key, dep_node, query, job.id); + let (result, dep_node_index) = execute_job(qcx, key, dep_node, query, job.id); let result = job.complete(cache, result, dep_node_index); (result, Some(dep_node_index)) } TryGetJob::Cycle(error) => { - let result = mk_cycle(tcx, error, query.handle_cycle_error, cache); + let result = mk_cycle(qcx, error, query.handle_cycle_error, cache); (result, None) } #[cfg(parallel_compiler)] @@ -387,8 +387,8 @@ where .lookup(&key, |value, index| (value.clone(), index)) .unwrap_or_else(|_| panic!("value must be in cache after waiting")); - if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) { - tcx.dep_context().profiler().query_cache_hit(index.into()); + if std::intrinsics::unlikely(qcx.dep_context().profiler().enabled()) { + qcx.dep_context().profiler().query_cache_hit(index.into()); } query_blocked_prof_timer.finish_with_query_invocation_id(index.into()); @@ -398,7 +398,7 @@ where } fn execute_job( - tcx: CTX, + qcx: CTX, key: K, mut dep_node_opt: Option>, query: &QueryVTable, @@ -409,13 +409,13 @@ where V: Debug, CTX: QueryContext, { - let dep_graph = tcx.dep_context().dep_graph(); + let dep_graph = qcx.dep_context().dep_graph(); // Fast path for when incr. comp. is off. if !dep_graph.is_fully_enabled() { - let prof_timer = tcx.dep_context().profiler().query_provider(); - let result = tcx.start_query(job_id, query.depth_limit, None, || { - query.compute(*tcx.dep_context(), key) + let prof_timer = qcx.dep_context().profiler().query_provider(); + let result = qcx.start_query(job_id, query.depth_limit, None, || { + query.compute(*qcx.dep_context(), key) }); let dep_node_index = dep_graph.next_virtual_depnode_index(); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -425,33 +425,33 @@ where if !query.anon && !query.eval_always { // `to_dep_node` is expensive for some `DepKind`s. let dep_node = - dep_node_opt.get_or_insert_with(|| query.to_dep_node(*tcx.dep_context(), &key)); + dep_node_opt.get_or_insert_with(|| query.to_dep_node(*qcx.dep_context(), &key)); // The diagnostics for this query will be promoted to the current session during // `try_mark_green()`, so we can ignore them here. - if let Some(ret) = tcx.start_query(job_id, false, None, || { - try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query) + if let Some(ret) = qcx.start_query(job_id, false, None, || { + try_load_from_disk_and_cache_in_memory(qcx, &key, &dep_node, query) }) { return ret; } } - let prof_timer = tcx.dep_context().profiler().query_provider(); + let prof_timer = qcx.dep_context().profiler().query_provider(); let diagnostics = Lock::new(ThinVec::new()); let (result, dep_node_index) = - tcx.start_query(job_id, query.depth_limit, Some(&diagnostics), || { + qcx.start_query(job_id, query.depth_limit, Some(&diagnostics), || { if query.anon { - return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || { - query.compute(*tcx.dep_context(), key) + return dep_graph.with_anon_task(*qcx.dep_context(), query.dep_kind, || { + query.compute(*qcx.dep_context(), key) }); } // `to_dep_node` is expensive for some `DepKind`s. let dep_node = - dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key)); + dep_node_opt.unwrap_or_else(|| query.to_dep_node(*qcx.dep_context(), &key)); - dep_graph.with_task(dep_node, *tcx.dep_context(), key, query.compute, query.hash_result) + dep_graph.with_task(dep_node, *qcx.dep_context(), key, query.compute, query.hash_result) }); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -461,9 +461,9 @@ where if std::intrinsics::unlikely(!side_effects.is_empty()) { if query.anon { - tcx.store_side_effects_for_anon_node(dep_node_index, side_effects); + qcx.store_side_effects_for_anon_node(dep_node_index, side_effects); } else { - tcx.store_side_effects(dep_node_index, side_effects); + qcx.store_side_effects(dep_node_index, side_effects); } } @@ -471,7 +471,7 @@ where } fn try_load_from_disk_and_cache_in_memory( - tcx: CTX, + qcx: CTX, key: &K, dep_node: &DepNode, query: &QueryVTable, @@ -484,32 +484,32 @@ where // Note this function can be called concurrently from the same query // We must ensure that this is handled correctly. - let dep_graph = tcx.dep_context().dep_graph(); - let (prev_dep_node_index, dep_node_index) = dep_graph.try_mark_green(tcx, &dep_node)?; + let dep_graph = qcx.dep_context().dep_graph(); + let (prev_dep_node_index, dep_node_index) = dep_graph.try_mark_green(qcx, &dep_node)?; debug_assert!(dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache. // Some things are never cached on disk. if let Some(try_load_from_disk) = query.try_load_from_disk { - let prof_timer = tcx.dep_context().profiler().incr_cache_loading(); + let prof_timer = qcx.dep_context().profiler().incr_cache_loading(); // The call to `with_query_deserialization` enforces that no new `DepNodes` // are created during deserialization. See the docs of that method for more // details. let result = - dep_graph.with_query_deserialization(|| try_load_from_disk(tcx, prev_dep_node_index)); + dep_graph.with_query_deserialization(|| try_load_from_disk(qcx, prev_dep_node_index)); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); if let Some(result) = result { if std::intrinsics::unlikely( - tcx.dep_context().sess().opts.unstable_opts.query_dep_graph, + qcx.dep_context().sess().opts.unstable_opts.query_dep_graph, ) { dep_graph.mark_debug_loaded_from_disk(*dep_node) } - let prev_fingerprint = tcx + let prev_fingerprint = qcx .dep_context() .dep_graph() .prev_fingerprint_of(dep_node) @@ -523,9 +523,9 @@ where // give us some coverage of potential bugs though. let try_verify = prev_fingerprint.as_value().1 % 32 == 0; if std::intrinsics::unlikely( - try_verify || tcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, + try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, ) { - incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query); + incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query); } return Some((result, dep_node_index)); @@ -534,7 +534,7 @@ where // We always expect to find a cached result for things that // can be forced from `DepNode`. debug_assert!( - !tcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), + !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), "missing on-disk cache entry for {:?}", dep_node ); @@ -542,10 +542,10 @@ where // We could not load a result from the on-disk cache, so // recompute. - let prof_timer = tcx.dep_context().profiler().query_provider(); + let prof_timer = qcx.dep_context().profiler().query_provider(); // The dep-graph for this computation is already in-place. - let result = dep_graph.with_ignore(|| query.compute(*tcx.dep_context(), key.clone())); + let result = dep_graph.with_ignore(|| query.compute(*qcx.dep_context(), key.clone())); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -558,14 +558,14 @@ where // // See issue #82920 for an example of a miscompilation that would get turned into // an ICE by this check - incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query); + incremental_verify_ich(*qcx.dep_context(), &result, dep_node, query); Some((result, dep_node_index)) } -#[instrument(skip(tcx, result, query), level = "debug")] +#[instrument(skip(qcx, result, query), level = "debug")] fn incremental_verify_ich( - tcx: CTX::DepContext, + qcx: CTX::DepContext, result: &V, dep_node: &DepNode, query: &QueryVTable, @@ -573,20 +573,20 @@ fn incremental_verify_ich( CTX: QueryContext, { assert!( - tcx.dep_graph().is_green(dep_node), + qcx.dep_graph().is_green(dep_node), "fingerprint for green query instance not loaded from cache: {:?}", dep_node, ); let new_hash = query.hash_result.map_or(Fingerprint::ZERO, |f| { - tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) + qcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) }); - let old_hash = tcx.dep_graph().prev_fingerprint_of(dep_node); + let old_hash = qcx.dep_graph().prev_fingerprint_of(dep_node); if Some(new_hash) != old_hash { incremental_verify_ich_failed( - tcx.sess(), + qcx.sess(), DebugArg::from(&dep_node), DebugArg::from(&result), ); @@ -677,7 +677,7 @@ fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: /// Note: The optimization is only available during incr. comp. #[inline(never)] fn ensure_must_run( - tcx: CTX, + qcx: CTX, key: &K, query: &QueryVTable, ) -> (bool, Option>) @@ -692,10 +692,10 @@ where // Ensuring an anonymous query makes no sense assert!(!query.anon); - let dep_node = query.to_dep_node(*tcx.dep_context(), key); + let dep_node = query.to_dep_node(*qcx.dep_context(), key); - let dep_graph = tcx.dep_context().dep_graph(); - match dep_graph.try_mark_green(tcx, &dep_node) { + let dep_graph = qcx.dep_context().dep_graph(); + match dep_graph.try_mark_green(qcx, &dep_node) { None => { // A None return from `try_mark_green` means that this is either // a new dep node or that the dep node has already been marked red. @@ -707,7 +707,7 @@ where } Some((_, dep_node_index)) => { dep_graph.read_index(dep_node_index); - tcx.dep_context().profiler().query_cache_hit(dep_node_index.into()); + qcx.dep_context().profiler().query_cache_hit(dep_node_index.into()); (false, None) } } @@ -719,16 +719,16 @@ pub enum QueryMode { Ensure, } -pub fn get_query(tcx: CTX, span: Span, key: Q::Key, mode: QueryMode) -> Option +pub fn get_query(qcx: CTX, span: Span, key: Q::Key, mode: QueryMode) -> Option where Q: QueryConfig, Q::Key: DepNodeParams, Q::Value: Value, CTX: QueryContext, { - let query = Q::make_vtable(tcx, &key); + let query = Q::make_vtable(qcx, &key); let dep_node = if let QueryMode::Ensure = mode { - let (must_run, dep_node) = ensure_must_run(tcx, &key, &query); + let (must_run, dep_node) = ensure_must_run(qcx, &key, &query); if !must_run { return None; } @@ -738,21 +738,21 @@ where }; let (result, dep_node_index) = try_execute_query( - tcx, - Q::query_state(tcx), - Q::query_cache(tcx), + qcx, + Q::query_state(qcx), + Q::query_cache(qcx), span, key, dep_node, &query, ); if let Some(dep_node_index) = dep_node_index { - tcx.dep_context().dep_graph().read_index(dep_node_index) + qcx.dep_context().dep_graph().read_index(dep_node_index) } Some(result) } -pub fn force_query(tcx: CTX, key: Q::Key, dep_node: DepNode) +pub fn force_query(qcx: CTX, key: Q::Key, dep_node: DepNode) where Q: QueryConfig, Q::Key: DepNodeParams, @@ -761,10 +761,10 @@ where { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. - let cache = Q::query_cache(tcx); + let cache = Q::query_cache(qcx); let cached = cache.lookup(&key, |_, index| { - if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) { - tcx.dep_context().profiler().query_cache_hit(index.into()); + if std::intrinsics::unlikely(qcx.dep_context().profiler().enabled()) { + qcx.dep_context().profiler().query_cache_hit(index.into()); } }); @@ -773,9 +773,9 @@ where Err(()) => {} } - let query = Q::make_vtable(tcx, &key); - let state = Q::query_state(tcx); + let query = Q::make_vtable(qcx, &key); + let state = Q::query_state(qcx); debug_assert!(!query.anon); - try_execute_query(tcx, state, cache, DUMMY_SP, key, Some(dep_node), &query); + try_execute_query(qcx, state, cache, DUMMY_SP, key, Some(dep_node), &query); } From f53eb1d4573133582efef3e521aa54a9bc113e57 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 5 Nov 2022 21:04:19 +0100 Subject: [PATCH 210/482] Rename `Ctxt` and `CTX` to `Tcx` and `Qcx` This makes it consistent and clear which context is used. --- compiler/rustc_query_system/src/cache.rs | 4 +- .../src/dep_graph/dep_node.rs | 36 +++--- .../rustc_query_system/src/dep_graph/graph.rs | 22 ++-- .../rustc_query_system/src/query/config.rs | 32 ++--- compiler/rustc_query_system/src/query/job.rs | 4 +- .../rustc_query_system/src/query/plumbing.rs | 112 +++++++++--------- compiler/rustc_query_system/src/values.rs | 8 +- 7 files changed, 109 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_query_system/src/cache.rs b/compiler/rustc_query_system/src/cache.rs index d592812f79b6b..7cc885be2ba6a 100644 --- a/compiler/rustc_query_system/src/cache.rs +++ b/compiler/rustc_query_system/src/cache.rs @@ -26,7 +26,7 @@ impl Cache { } impl Cache { - pub fn get(&self, key: &Key, tcx: CTX) -> Option { + pub fn get(&self, key: &Key, tcx: Tcx) -> Option { Some(self.hashmap.borrow().get(key)?.get(tcx)) } @@ -46,7 +46,7 @@ impl WithDepNode { WithDepNode { dep_node, cached_value } } - pub fn get(&self, tcx: CTX) -> T { + pub fn get(&self, tcx: Tcx) -> T { tcx.dep_graph().read_index(self.dep_node); self.cached_value.clone() } diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 5c6ce0556eb8a..d79c5816a9c40 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -61,18 +61,18 @@ impl DepNode { /// Creates a new, parameterless DepNode. This method will assert /// that the DepNode corresponding to the given DepKind actually /// does not require any parameters. - pub fn new_no_params(tcx: Ctxt, kind: K) -> DepNode + pub fn new_no_params(tcx: Tcx, kind: K) -> DepNode where - Ctxt: super::DepContext, + Tcx: super::DepContext, { debug_assert_eq!(tcx.fingerprint_style(kind), FingerprintStyle::Unit); DepNode { kind, hash: Fingerprint::ZERO.into() } } - pub fn construct(tcx: Ctxt, kind: K, arg: &Key) -> DepNode + pub fn construct(tcx: Tcx, kind: K, arg: &Key) -> DepNode where - Ctxt: super::DepContext, - Key: DepNodeParams, + Tcx: super::DepContext, + Key: DepNodeParams, { let hash = arg.to_fingerprint(tcx); let dep_node = DepNode { kind, hash: hash.into() }; @@ -93,9 +93,9 @@ impl DepNode { /// Construct a DepNode from the given DepKind and DefPathHash. This /// method will assert that the given DepKind actually requires a /// single DefId/DefPathHash parameter. - pub fn from_def_path_hash(tcx: Ctxt, def_path_hash: DefPathHash, kind: K) -> Self + pub fn from_def_path_hash(tcx: Tcx, def_path_hash: DefPathHash, kind: K) -> Self where - Ctxt: super::DepContext, + Tcx: super::DepContext, { debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash); DepNode { kind, hash: def_path_hash.0.into() } @@ -108,18 +108,18 @@ impl fmt::Debug for DepNode { } } -pub trait DepNodeParams: fmt::Debug + Sized { +pub trait DepNodeParams: fmt::Debug + Sized { fn fingerprint_style() -> FingerprintStyle; /// This method turns the parameters of a DepNodeConstructor into an opaque /// Fingerprint to be used in DepNode. /// Not all DepNodeParams support being turned into a Fingerprint (they /// don't need to if the corresponding DepNode is anonymous). - fn to_fingerprint(&self, _: Ctxt) -> Fingerprint { + fn to_fingerprint(&self, _: Tcx) -> Fingerprint { panic!("Not implemented. Accidentally called on anonymous node?") } - fn to_debug_str(&self, _: Ctxt) -> String { + fn to_debug_str(&self, _: Tcx) -> String { format!("{:?}", self) } @@ -129,10 +129,10 @@ pub trait DepNodeParams: fmt::Debug + Sized { /// `fingerprint_style()` is not `FingerprintStyle::Opaque`. /// It is always valid to return `None` here, in which case incremental /// compilation will treat the query as having changed instead of forcing it. - fn recover(tcx: Ctxt, dep_node: &DepNode) -> Option; + fn recover(tcx: Tcx, dep_node: &DepNode) -> Option; } -impl DepNodeParams for T +impl DepNodeParams for T where T: for<'a> HashStable> + fmt::Debug, { @@ -142,7 +142,7 @@ where } #[inline(always)] - default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint { + default fn to_fingerprint(&self, tcx: Tcx) -> Fingerprint { tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); self.hash_stable(&mut hcx, &mut hasher); @@ -151,12 +151,12 @@ where } #[inline(always)] - default fn to_debug_str(&self, _: Ctxt) -> String { + default fn to_debug_str(&self, _: Tcx) -> String { format!("{:?}", *self) } #[inline(always)] - default fn recover(_: Ctxt, _: &DepNode) -> Option { + default fn recover(_: Tcx, _: &DepNode) -> Option { None } } @@ -166,7 +166,7 @@ where /// Information is retrieved by indexing the `DEP_KINDS` array using the integer value /// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual /// jump table instead of large matches. -pub struct DepKindStruct { +pub struct DepKindStruct { /// Anonymous queries cannot be replayed from one compiler invocation to the next. /// When their result is needed, it is recomputed. They are useful for fine-grained /// dependency tracking, and caching within one compiler invocation. @@ -216,10 +216,10 @@ pub struct DepKindStruct { /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` /// is actually a `DefPathHash`, and can therefore just look up the corresponding /// `DefId` in `tcx.def_path_hash_to_def_id`. - pub force_from_dep_node: Option) -> bool>, + pub force_from_dep_node: Option) -> bool>, /// Invoke a query to put the on-disk cached value in memory. - pub try_load_from_on_disk_cache: Option)>, + pub try_load_from_on_disk_cache: Option)>, } /// A "work product" corresponds to a `.o` (or other) file that we diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index e856e39bf212a..d86c0bebdcdf4 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -377,9 +377,9 @@ impl DepGraph { /// Executes something within an "anonymous" task, that is, a task the /// `DepNode` of which is determined by the list of inputs it read from. - pub fn with_anon_task, OP, R>( + pub fn with_anon_task, OP, R>( &self, - cx: Ctxt, + cx: Tcx, dep_kind: K, op: OP, ) -> (R, DepNodeIndex) @@ -571,9 +571,9 @@ impl DepGraph { /// A node will have an index, when it's already been marked green, or when we can mark it /// green. This function will mark the current task as a reader of the specified node, when /// a node index can be found for that node. - pub fn try_mark_green>( + pub fn try_mark_green>( &self, - qcx: Ctxt, + qcx: Qcx, dep_node: &DepNode, ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> { debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind)); @@ -599,9 +599,9 @@ impl DepGraph { } #[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")] - fn try_mark_parent_green>( + fn try_mark_parent_green>( &self, - qcx: Ctxt, + qcx: Qcx, data: &DepGraphData, parent_dep_node_index: SerializedDepNodeIndex, dep_node: &DepNode, @@ -687,9 +687,9 @@ impl DepGraph { /// Try to mark a dep-node which existed in the previous compilation session as green. #[instrument(skip(self, qcx, data, prev_dep_node_index), level = "debug")] - fn try_mark_previous_green>( + fn try_mark_previous_green>( &self, - qcx: Ctxt, + qcx: Qcx, data: &DepGraphData, prev_dep_node_index: SerializedDepNodeIndex, dep_node: &DepNode, @@ -755,9 +755,9 @@ impl DepGraph { /// This may be called concurrently on multiple threads for the same dep node. #[cold] #[inline(never)] - fn emit_side_effects>( + fn emit_side_effects>( &self, - qcx: Ctxt, + qcx: Qcx, data: &DepGraphData, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects, @@ -799,7 +799,7 @@ impl DepGraph { // // This method will only load queries that will end up in the disk cache. // Other queries will not be executed. - pub fn exec_cache_promotions>(&self, tcx: Ctxt) { + pub fn exec_cache_promotions>(&self, tcx: Tcx) { let _prof_timer = tcx.profiler().generic_activity("incr_comp_query_cache_promotion"); let data = self.data.as_ref().unwrap(); diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index db3ae559ad15d..f40e174b7e79b 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use std::fmt::Debug; use std::hash::Hash; -pub trait QueryConfig { +pub trait QueryConfig { const NAME: &'static str; type Key: Eq + Hash + Clone + Debug; @@ -21,47 +21,47 @@ pub trait QueryConfig { type Cache: QueryCache; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state<'a>(tcx: CTX) -> &'a QueryState + fn query_state<'a>(tcx: Qcx) -> &'a QueryState where - CTX: 'a; + Qcx: 'a; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_cache<'a>(tcx: CTX) -> &'a Self::Cache + fn query_cache<'a>(tcx: Qcx) -> &'a Self::Cache where - CTX: 'a; + Qcx: 'a; // Don't use this method to compute query results, instead use the methods on TyCtxt - fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable; + fn make_vtable(tcx: Qcx, key: &Self::Key) -> QueryVTable; - fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool; + fn cache_on_disk(tcx: Qcx::DepContext, key: &Self::Key) -> bool; // Don't use this method to compute query results, instead use the methods on TyCtxt - fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored; + fn execute_query(tcx: Qcx::DepContext, k: Self::Key) -> Self::Stored; } #[derive(Copy, Clone)] -pub struct QueryVTable { +pub struct QueryVTable { pub anon: bool, - pub dep_kind: CTX::DepKind, + pub dep_kind: Qcx::DepKind, pub eval_always: bool, pub depth_limit: bool, - pub compute: fn(CTX::DepContext, K) -> V, + pub compute: fn(Qcx::DepContext, K) -> V, pub hash_result: Option, &V) -> Fingerprint>, pub handle_cycle_error: HandleCycleError, // NOTE: this is also `None` if `cache_on_disk()` returns false, not just if it's unsupported by the query - pub try_load_from_disk: Option Option>, + pub try_load_from_disk: Option Option>, } -impl QueryVTable { - pub(crate) fn to_dep_node(&self, tcx: CTX::DepContext, key: &K) -> DepNode +impl QueryVTable { + pub(crate) fn to_dep_node(&self, tcx: Qcx::DepContext, key: &K) -> DepNode where - K: crate::dep_graph::DepNodeParams, + K: crate::dep_graph::DepNodeParams, { DepNode::construct(tcx, self.dep_kind, key) } - pub(crate) fn compute(&self, tcx: CTX::DepContext, key: K) -> V { + pub(crate) fn compute(&self, tcx: Qcx::DepContext, key: K) -> V { (self.compute)(tcx, key) } } diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index bd21b5465e2f4..49bbcf5780459 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -596,8 +596,8 @@ pub(crate) fn report_cycle<'a>( cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic) } -pub fn print_query_stack( - qcx: CTX, +pub fn print_query_stack( + qcx: Qcx, mut current_query: Option, handler: &Handler, num_frames: Option, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 6348bc6b3afaf..f8d93a27d1c2b 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -62,10 +62,10 @@ where } } - pub fn try_collect_active_jobs( + pub fn try_collect_active_jobs( &self, - qcx: CTX, - make_query: fn(CTX, K) -> QueryStackFrame, + qcx: Qcx, + make_query: fn(Qcx, K) -> QueryStackFrame, jobs: &mut QueryMap, ) -> Option<()> { #[cfg(parallel_compiler)] @@ -119,15 +119,15 @@ where #[cold] #[inline(never)] -fn mk_cycle( - qcx: CTX, +fn mk_cycle( + qcx: Qcx, cycle_error: CycleError, handler: HandleCycleError, cache: &dyn crate::query::QueryStorage, ) -> R where - CTX: QueryContext, - V: std::fmt::Debug + Value, + Qcx: QueryContext, + V: std::fmt::Debug + Value, R: Clone, { let error = report_cycle(qcx.dep_context().sess(), &cycle_error); @@ -135,15 +135,15 @@ where cache.store_nocache(value) } -fn handle_cycle_error( - tcx: CTX, +fn handle_cycle_error( + tcx: Tcx, cycle_error: &CycleError, mut error: DiagnosticBuilder<'_, ErrorGuaranteed>, handler: HandleCycleError, ) -> V where - CTX: DepContext, - V: Value, + Tcx: DepContext, + V: Value, { use HandleCycleError::*; match handler { @@ -176,14 +176,14 @@ where /// This function is inlined because that results in a noticeable speed-up /// for some compile-time benchmarks. #[inline(always)] - fn try_start<'b, CTX>( - qcx: &'b CTX, + fn try_start<'b, Qcx>( + qcx: &'b Qcx, state: &'b QueryState, span: Span, key: K, ) -> TryGetJob<'b, K> where - CTX: QueryContext, + Qcx: QueryContext, { #[cfg(parallel_compiler)] let mut state_lock = state.active.get_shard_by_value(&key).lock(); @@ -335,8 +335,8 @@ where /// which will be used if the query is not in the cache and we need /// to compute it. #[inline] -pub fn try_get_cached<'a, CTX, C, R, OnHit>( - tcx: CTX, +pub fn try_get_cached<'a, Tcx, C, R, OnHit>( + tcx: Tcx, cache: &'a C, key: &C::Key, // `on_hit` can be called while holding a lock to the query cache @@ -344,7 +344,7 @@ pub fn try_get_cached<'a, CTX, C, R, OnHit>( ) -> Result where C: QueryCache, - CTX: DepContext, + Tcx: DepContext, OnHit: FnOnce(&C::Stored) -> R, { cache.lookup(&key, |value, index| { @@ -356,20 +356,20 @@ where }) } -fn try_execute_query( - qcx: CTX, +fn try_execute_query( + qcx: Qcx, state: &QueryState, cache: &C, span: Span, key: C::Key, - dep_node: Option>, - query: &QueryVTable, + dep_node: Option>, + query: &QueryVTable, ) -> (C::Stored, Option) where C: QueryCache, - C::Key: Clone + DepNodeParams, - C::Value: Value, - CTX: QueryContext, + C::Key: Clone + DepNodeParams, + C::Value: Value, + Qcx: QueryContext, { match JobOwner::<'_, C::Key>::try_start(&qcx, state, span, key.clone()) { TryGetJob::NotYetStarted(job) => { @@ -397,17 +397,17 @@ where } } -fn execute_job( - qcx: CTX, +fn execute_job( + qcx: Qcx, key: K, - mut dep_node_opt: Option>, - query: &QueryVTable, + mut dep_node_opt: Option>, + query: &QueryVTable, job_id: QueryJobId, ) -> (V, DepNodeIndex) where - K: Clone + DepNodeParams, + K: Clone + DepNodeParams, V: Debug, - CTX: QueryContext, + Qcx: QueryContext, { let dep_graph = qcx.dep_context().dep_graph(); @@ -470,15 +470,15 @@ where (result, dep_node_index) } -fn try_load_from_disk_and_cache_in_memory( - qcx: CTX, +fn try_load_from_disk_and_cache_in_memory( + qcx: Qcx, key: &K, - dep_node: &DepNode, - query: &QueryVTable, + dep_node: &DepNode, + query: &QueryVTable, ) -> Option<(V, DepNodeIndex)> where K: Clone, - CTX: QueryContext, + Qcx: QueryContext, V: Debug, { // Note this function can be called concurrently from the same query @@ -564,13 +564,13 @@ where } #[instrument(skip(qcx, result, query), level = "debug")] -fn incremental_verify_ich( - qcx: CTX::DepContext, +fn incremental_verify_ich( + qcx: Qcx::DepContext, result: &V, - dep_node: &DepNode, - query: &QueryVTable, + dep_node: &DepNode, + query: &QueryVTable, ) where - CTX: QueryContext, + Qcx: QueryContext, { assert!( qcx.dep_graph().is_green(dep_node), @@ -676,14 +676,14 @@ fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: /// /// Note: The optimization is only available during incr. comp. #[inline(never)] -fn ensure_must_run( - qcx: CTX, +fn ensure_must_run( + qcx: Qcx, key: &K, - query: &QueryVTable, -) -> (bool, Option>) + query: &QueryVTable, +) -> (bool, Option>) where - K: crate::dep_graph::DepNodeParams, - CTX: QueryContext, + K: crate::dep_graph::DepNodeParams, + Qcx: QueryContext, { if query.eval_always { return (true, None); @@ -719,12 +719,12 @@ pub enum QueryMode { Ensure, } -pub fn get_query(qcx: CTX, span: Span, key: Q::Key, mode: QueryMode) -> Option +pub fn get_query(qcx: Qcx, span: Span, key: Q::Key, mode: QueryMode) -> Option where - Q: QueryConfig, - Q::Key: DepNodeParams, - Q::Value: Value, - CTX: QueryContext, + Q: QueryConfig, + Q::Key: DepNodeParams, + Q::Value: Value, + Qcx: QueryContext, { let query = Q::make_vtable(qcx, &key); let dep_node = if let QueryMode::Ensure = mode { @@ -752,12 +752,12 @@ where Some(result) } -pub fn force_query(qcx: CTX, key: Q::Key, dep_node: DepNode) +pub fn force_query(qcx: Qcx, key: Q::Key, dep_node: DepNode) where - Q: QueryConfig, - Q::Key: DepNodeParams, - Q::Value: Value, - CTX: QueryContext, + Q: QueryConfig, + Q::Key: DepNodeParams, + Q::Value: Value, + Qcx: QueryContext, { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. diff --git a/compiler/rustc_query_system/src/values.rs b/compiler/rustc_query_system/src/values.rs index 67fbf14e61299..214656abed4df 100644 --- a/compiler/rustc_query_system/src/values.rs +++ b/compiler/rustc_query_system/src/values.rs @@ -1,12 +1,12 @@ use crate::dep_graph::DepContext; use crate::query::QueryInfo; -pub trait Value: Sized { - fn from_cycle_error(tcx: CTX, cycle: &[QueryInfo]) -> Self; +pub trait Value: Sized { + fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo]) -> Self; } -impl Value for T { - default fn from_cycle_error(tcx: CTX, _: &[QueryInfo]) -> T { +impl Value for T { + default fn from_cycle_error(tcx: Tcx, _: &[QueryInfo]) -> T { tcx.sess().abort_if_errors(); // Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's // non-trivial to define it earlier. From 36d2ad5c0043049caee72551ff15d906cc4e7124 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 23 Oct 2022 19:16:49 +0200 Subject: [PATCH 211/482] add benchmark for iter::ArrayChunks::fold specialization This also updates the existing iter::Copied::next_chunk benchmark so that the thing it benches doesn't get masked by the ArrayChunks specialization --- library/core/benches/iter.rs | 23 +++++++++++++++++++++-- library/core/benches/lib.rs | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/library/core/benches/iter.rs b/library/core/benches/iter.rs index 38887f29af153..9193c79bee875 100644 --- a/library/core/benches/iter.rs +++ b/library/core/benches/iter.rs @@ -1,3 +1,4 @@ +use core::borrow::Borrow; use core::iter::*; use core::mem; use core::num::Wrapping; @@ -403,13 +404,31 @@ fn bench_trusted_random_access_adapters(b: &mut Bencher) { /// Exercises the iter::Copied specialization for slice::Iter #[bench] -fn bench_copied_array_chunks(b: &mut Bencher) { +fn bench_copied_chunks(b: &mut Bencher) { + let v = vec![1u8; 1024]; + + b.iter(|| { + let mut iter = black_box(&v).iter().copied(); + let mut acc = Wrapping(0); + // This uses a while-let loop to side-step the TRA specialization in ArrayChunks + while let Ok(chunk) = iter.next_chunk::<{ mem::size_of::() }>() { + let d = u64::from_ne_bytes(chunk); + acc += Wrapping(d.rotate_left(7).wrapping_add(1)); + } + acc + }) +} + +/// Exercises the TrustedRandomAccess specialization in ArrayChunks +#[bench] +fn bench_trusted_random_access_chunks(b: &mut Bencher) { let v = vec![1u8; 1024]; b.iter(|| { black_box(&v) .iter() - .copied() + // this shows that we're not relying on the slice::Iter specialization in Copied + .map(|b| *b.borrow()) .array_chunks::<{ mem::size_of::() }>() .map(|ary| { let d = u64::from_ne_bytes(ary); diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs index 1e462e3fc3f8c..cf5a7cada93ce 100644 --- a/library/core/benches/lib.rs +++ b/library/core/benches/lib.rs @@ -5,6 +5,7 @@ #![feature(test)] #![feature(trusted_random_access)] #![feature(iter_array_chunks)] +#![feature(iter_next_chunk)] extern crate test; From 2cf34a810f599b6c2c9035ea31f5e77456b499bb Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 23 Oct 2022 19:17:41 +0200 Subject: [PATCH 212/482] make the array initialization guard available to other modules --- library/core/src/array/mod.rs | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index eae0e1c761866..24e5d0fba21bf 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -865,24 +865,6 @@ where return Ok(Try::from_output(unsafe { mem::zeroed() })); } - struct Guard<'a, T, const N: usize> { - array_mut: &'a mut [MaybeUninit; N], - initialized: usize, - } - - impl Drop for Guard<'_, T, N> { - fn drop(&mut self) { - debug_assert!(self.initialized <= N); - - // SAFETY: this slice will contain only initialized objects. - unsafe { - crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut( - &mut self.array_mut.get_unchecked_mut(..self.initialized), - )); - } - } - } - let mut array = MaybeUninit::uninit_array::(); let mut guard = Guard { array_mut: &mut array, initialized: 0 }; @@ -920,6 +902,24 @@ where Ok(Try::from_output(output)) } +pub(crate) struct Guard<'a, T, const N: usize> { + pub array_mut: &'a mut [MaybeUninit; N], + pub initialized: usize, +} + +impl Drop for Guard<'_, T, N> { + fn drop(&mut self) { + debug_assert!(self.initialized <= N); + + // SAFETY: this slice will contain only initialized objects. + unsafe { + crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut( + &mut self.array_mut.get_unchecked_mut(..self.initialized), + )); + } + } +} + /// Returns the next chunk of `N` items from the iterator or errors with an /// iterator over the remainder. Used for `Iterator::next_chunk`. #[inline] From ff0865bfc269bbb1010c4d6f772cff59f589fd09 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 23 Oct 2022 19:19:37 +0200 Subject: [PATCH 213/482] specialize iter::ArrayChunks::fold for TrustedRandomAccess iters This is fairly safe use of TRA since it consumes the iterator so no struct in an unsafe state will be left exposed to user code --- .../core/src/iter/adapters/array_chunks.rs | 89 ++++++++++++++++++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index d4fb886101fe7..3f0fad4ed336f 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -1,6 +1,8 @@ use crate::array; -use crate::iter::{ByRefSized, FusedIterator, Iterator}; -use crate::ops::{ControlFlow, Try}; +use crate::const_closure::ConstFnMutClosure; +use crate::iter::{ByRefSized, FusedIterator, Iterator, TrustedRandomAccessNoCoerce}; +use crate::mem::{self, MaybeUninit}; +use crate::ops::{ControlFlow, NeverShortCircuit, Try}; /// An iterator over `N` elements of the iterator at a time. /// @@ -82,7 +84,13 @@ where } } - impl_fold_via_try_fold! { fold -> try_fold } + fn fold(self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + ::fold(self, init, f) + } } #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] @@ -168,3 +176,78 @@ where self.iter.len() < N } } + +trait SpecFold: Iterator { + fn fold(self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B; +} + +impl SpecFold for ArrayChunks +where + I: Iterator, +{ + #[inline] + default fn fold(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + let fold = ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp); + self.try_fold(init, fold).0 + } +} + +impl SpecFold for ArrayChunks +where + I: Iterator + TrustedRandomAccessNoCoerce, +{ + #[inline] + fn fold(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + if self.remainder.is_some() { + return init; + } + + let mut accum = init; + let inner_len = self.iter.size(); + let mut i = 0; + // Use a while loop because (0..len).step_by(N) doesn't optimize well. + while inner_len - i >= N { + let mut chunk = MaybeUninit::uninit_array(); + let mut guard = array::Guard { array_mut: &mut chunk, initialized: 0 }; + for j in 0..N { + // SAFETY: The method consumes the iterator and the loop condition ensures that + // all accesses are in bounds and only happen once. + guard.array_mut[j].write(unsafe { self.iter.__iterator_get_unchecked(i + j) }); + guard.initialized = j + 1; + } + mem::forget(guard); + // SAFETY: The loop above initialized all elements + let chunk = unsafe { MaybeUninit::array_assume_init(chunk) }; + accum = f(accum, chunk); + i += N; + } + + let remainder = inner_len % N; + + let mut tail = MaybeUninit::uninit_array(); + let mut guard = array::Guard { array_mut: &mut tail, initialized: 0 }; + for i in 0..remainder { + // SAFETY: the remainder was not visited by the previous loop, so we're still only + // accessing each element once + let val = unsafe { self.iter.__iterator_get_unchecked(inner_len - remainder + i) }; + guard.array_mut[i].write(val); + guard.initialized = i + 1; + } + mem::forget(guard); + // SAFETY: the loop above initialized elements up to the `remainder` index + self.remainder = Some(unsafe { array::IntoIter::new_unchecked(tail, 0..remainder) }); + + accum + } +} From 8dd4692383c195a4a115c9e57b0bfa42fb05d29a Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 23 Oct 2022 21:29:15 +0200 Subject: [PATCH 214/482] simplification: do not process the ArrayChunks remainder in fold() --- .../core/src/iter/adapters/array_chunks.rs | 20 ++----------------- .../core/tests/iter/adapters/array_chunks.rs | 3 ++- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 3f0fad4ed336f..9bd135007b4a6 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -209,10 +209,6 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - if self.remainder.is_some() { - return init; - } - let mut accum = init; let inner_len = self.iter.size(); let mut i = 0; @@ -233,20 +229,8 @@ where i += N; } - let remainder = inner_len % N; - - let mut tail = MaybeUninit::uninit_array(); - let mut guard = array::Guard { array_mut: &mut tail, initialized: 0 }; - for i in 0..remainder { - // SAFETY: the remainder was not visited by the previous loop, so we're still only - // accessing each element once - let val = unsafe { self.iter.__iterator_get_unchecked(inner_len - remainder + i) }; - guard.array_mut[i].write(val); - guard.initialized = i + 1; - } - mem::forget(guard); - // SAFETY: the loop above initialized elements up to the `remainder` index - self.remainder = Some(unsafe { array::IntoIter::new_unchecked(tail, 0..remainder) }); + // unlike try_fold this method does not need to take care of the remainder + // since `self` will be dropped accum } diff --git a/library/core/tests/iter/adapters/array_chunks.rs b/library/core/tests/iter/adapters/array_chunks.rs index 4e9d89e1e580f..ef4a7e53bdd33 100644 --- a/library/core/tests/iter/adapters/array_chunks.rs +++ b/library/core/tests/iter/adapters/array_chunks.rs @@ -139,7 +139,8 @@ fn test_iterator_array_chunks_fold() { let result = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1); assert_eq!(result, 3); - assert_eq!(count.get(), 10); + // fold impls may or may not process the remainder + assert!(count.get() <= 10 && count.get() >= 9); } #[test] From 6cb4c1bf570b40a03594d92deb8d1f7433b9436d Mon Sep 17 00:00:00 2001 From: The 8472 Date: Tue, 8 Nov 2022 00:13:26 +0100 Subject: [PATCH 215/482] document and improve array Guard type The type is unsafe and now exposed to the whole crate. Document it properly and add an unsafe method so the caller can make it visible that something unsafe is happening. --- library/core/src/array/mod.rs | 39 ++++++++++++++++--- .../core/src/iter/adapters/array_chunks.rs | 8 ++-- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 24e5d0fba21bf..2090756d7a3ec 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -878,13 +878,11 @@ where ControlFlow::Continue(elem) => elem, }; - // SAFETY: `guard.initialized` starts at 0, is increased by one in the - // loop and the loop is aborted once it reaches N (which is - // `array.len()`). + // SAFETY: `guard.initialized` starts at 0, which means push can be called + // at most N times, which this loop does. unsafe { - guard.array_mut.get_unchecked_mut(guard.initialized).write(item); + guard.push_unchecked(item); } - guard.initialized += 1; } None => { let alive = 0..guard.initialized; @@ -902,11 +900,42 @@ where Ok(Try::from_output(output)) } +/// Panic guard for incremental initialization of arrays. +/// +/// Disarm the guard with `mem::forget` once the array has been initialized. +/// +/// # Safety +/// +/// All write accesses to this structure are unsafe and must maintain a correct +/// count of `initialized` elements. +/// +/// To minimize indirection fields are still pub but callers should at least use +/// `push_unchecked` to signal that something unsafe is going on. pub(crate) struct Guard<'a, T, const N: usize> { + /// The array to be initialized. pub array_mut: &'a mut [MaybeUninit; N], + /// The number of items that have been initialized so far. pub initialized: usize, } +impl Guard<'_, T, N> { + /// Adds an item to the array and updates the initialized item counter. + /// + /// # Safety + /// + /// No more than N elements must be initialized. + #[inline] + pub unsafe fn push_unchecked(&mut self, item: T) { + // SAFETY: If `initialized` was correct before and the caller does not + // invoke this method more than N times then writes will be in-bounds + // and slots will not be initialized more than once. + unsafe { + self.array_mut.get_unchecked_mut(self.initialized).write(item); + self.initialized = self.initialized.unchecked_add(1); + } + } +} + impl Drop for Guard<'_, T, N> { fn drop(&mut self) { debug_assert!(self.initialized <= N); diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 9bd135007b4a6..5e4211058aa6f 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -216,11 +216,13 @@ where while inner_len - i >= N { let mut chunk = MaybeUninit::uninit_array(); let mut guard = array::Guard { array_mut: &mut chunk, initialized: 0 }; - for j in 0..N { + while guard.initialized < N { // SAFETY: The method consumes the iterator and the loop condition ensures that // all accesses are in bounds and only happen once. - guard.array_mut[j].write(unsafe { self.iter.__iterator_get_unchecked(i + j) }); - guard.initialized = j + 1; + unsafe { + let idx = i + guard.initialized; + guard.push_unchecked(self.iter.__iterator_get_unchecked(idx)); + } } mem::forget(guard); // SAFETY: The loop above initialized all elements From d1474aa00c90dec2c8db2bec127a136ad6c2ee74 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Thu, 27 Oct 2022 18:20:56 +0000 Subject: [PATCH 216/482] Fix rustc_parse_format spans following escaped utf-8 multibyte chars --- compiler/rustc_parse_format/src/lib.rs | 47 +++++++++------ src/test/ui/fmt/unicode-escape-spans.rs | 19 +++++++ src/test/ui/fmt/unicode-escape-spans.stderr | 63 +++++++++++++++++++++ 3 files changed, 111 insertions(+), 18 deletions(-) create mode 100644 src/test/ui/fmt/unicode-escape-spans.rs create mode 100644 src/test/ui/fmt/unicode-escape-spans.stderr diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 1394993abade9..54bf4d1d6b738 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -819,19 +819,19 @@ fn find_skips_from_snippet( }; fn find_skips(snippet: &str, is_raw: bool) -> Vec { - let mut s = snippet.char_indices().peekable(); + let mut s = snippet.char_indices(); let mut skips = vec![]; while let Some((pos, c)) = s.next() { - match (c, s.peek()) { + match (c, s.clone().next()) { // skip whitespace and empty lines ending in '\\' ('\\', Some((next_pos, '\n'))) if !is_raw => { skips.push(pos); - skips.push(*next_pos); + skips.push(next_pos); let _ = s.next(); - while let Some((pos, c)) = s.peek() { + while let Some((pos, c)) = s.clone().next() { if matches!(c, ' ' | '\n' | '\t') { - skips.push(*pos); + skips.push(pos); let _ = s.next(); } else { break; @@ -839,7 +839,7 @@ fn find_skips_from_snippet( } } ('\\', Some((next_pos, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => { - skips.push(*next_pos); + skips.push(next_pos); let _ = s.next(); } ('\\', Some((_, 'x'))) if !is_raw => { @@ -858,19 +858,30 @@ fn find_skips_from_snippet( } if let Some((next_pos, next_c)) = s.next() { if next_c == '{' { - skips.push(next_pos); - let mut i = 0; // consume up to 6 hexanumeric chars + closing `}` - while let (Some((next_pos, c)), true) = (s.next(), i < 7) { - if c.is_digit(16) { - skips.push(next_pos); - } else if c == '}' { - skips.push(next_pos); - break; - } else { - break; - } - i += 1; + // consume up to 6 hexanumeric chars + let digits_len = + s.clone().take(6).take_while(|(_, c)| c.is_digit(16)).count(); + + let len_utf8 = s + .as_str() + .get(..digits_len) + .and_then(|digits| u32::from_str_radix(digits, 16).ok()) + .and_then(char::from_u32) + .map_or(1, char::len_utf8); + + // Skip the digits, for chars that encode to more than 1 utf-8 byte + // exclude as many digits as it is greater than 1 byte + // + // So for a 3 byte character, exclude 2 digits + let required_skips = + digits_len.saturating_sub(len_utf8.saturating_sub(1)); + + // skip '{' and '}' also + for pos in (next_pos..).take(required_skips + 2) { + skips.push(pos) } + + s.nth(digits_len); } else if next_c.is_digit(16) { skips.push(next_pos); // We suggest adding `{` and `}` when appropriate, accept it here as if diff --git a/src/test/ui/fmt/unicode-escape-spans.rs b/src/test/ui/fmt/unicode-escape-spans.rs new file mode 100644 index 0000000000000..753d91ce58e66 --- /dev/null +++ b/src/test/ui/fmt/unicode-escape-spans.rs @@ -0,0 +1,19 @@ +fn main() { + // 1 byte in UTF-8 + format!("\u{000041}{a}"); //~ ERROR cannot find value + format!("\u{0041}{a}"); //~ ERROR cannot find value + format!("\u{41}{a}"); //~ ERROR cannot find value + format!("\u{0}{a}"); //~ ERROR cannot find value + + // 2 bytes + format!("\u{0df}{a}"); //~ ERROR cannot find value + format!("\u{df}{a}"); //~ ERROR cannot find value + + // 3 bytes + format!("\u{00211d}{a}"); //~ ERROR cannot find value + format!("\u{211d}{a}"); //~ ERROR cannot find value + + // 4 bytes + format!("\u{1f4a3}{a}"); //~ ERROR cannot find value + format!("\u{10ffff}{a}"); //~ ERROR cannot find value +} diff --git a/src/test/ui/fmt/unicode-escape-spans.stderr b/src/test/ui/fmt/unicode-escape-spans.stderr new file mode 100644 index 0000000000000..1d8473f01b822 --- /dev/null +++ b/src/test/ui/fmt/unicode-escape-spans.stderr @@ -0,0 +1,63 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:3:25 + | +LL | format!("\u{000041}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:4:23 + | +LL | format!("\u{0041}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:5:21 + | +LL | format!("\u{41}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:6:20 + | +LL | format!("\u{0}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:9:22 + | +LL | format!("\u{0df}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:10:21 + | +LL | format!("\u{df}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:13:25 + | +LL | format!("\u{00211d}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:14:23 + | +LL | format!("\u{211d}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:17:24 + | +LL | format!("\u{1f4a3}{a}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/unicode-escape-spans.rs:18:25 + | +LL | format!("\u{10ffff}{a}"); + | ^ not found in this scope + +error: aborting due to 10 previous errors + +For more information about this error, try `rustc --explain E0425`. From 7d7895166aaf5ff0cbd69e434c36c41f5dbd1527 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 01:34:17 +0000 Subject: [PATCH 217/482] Move fallback_has_occurred to FnCtxt --- .../src/region_infer/opaque_types.rs | 2 +- .../src/transform/check_consts/check.rs | 3 +-- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_method.rs | 10 +++---- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/coherence/builtin.rs | 4 +-- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 4 +-- compiler/rustc_hir_typeck/src/coercion.rs | 7 +---- compiler/rustc_hir_typeck/src/expr.rs | 4 +-- compiler/rustc_hir_typeck/src/fallback.rs | 26 +++++++++---------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 13 +++------- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 9 ++++++- compiler/rustc_hir_typeck/src/lib.rs | 4 +-- compiler/rustc_hir_typeck/src/op.rs | 2 +- .../src/infer/error_reporting/mod.rs | 1 + compiler/rustc_infer/src/infer/mod.rs | 4 +-- .../src/traits/error_reporting/mod.rs | 11 ++------ .../rustc_trait_selection/src/traits/misc.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- 21 files changed, 52 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 95ea42b584a3a..103c7ed8ef701 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -299,7 +299,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { if errors.is_empty() { definition_ty } else { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); self.tcx.ty_error() } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index b1ad22b899e30..5a8b3e30b9fc0 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -765,7 +765,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); } } @@ -831,7 +831,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { obligation.clone(), &obligation, &e, - false, ); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 133bbd52b9142..3170f8feffc66 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -471,7 +471,7 @@ fn check_opaque_meets_bounds<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); } match origin { // Checked when type checking the function containing them. diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index c6b497e9b9fc4..0e8ac17fb71b1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -405,7 +405,7 @@ fn compare_predicate_entailment<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); return Err(reported); } @@ -538,7 +538,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( // RPITs. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); return Err(reported); } @@ -1431,7 +1431,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None, false)); + return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None)); } // FIXME return `ErrorReported` if region obligations error? @@ -1549,7 +1549,7 @@ fn compare_type_predicate_entailment<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); return Err(reported); } @@ -1769,7 +1769,7 @@ pub fn check_type_bounds<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); return Err(reported); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 416b555db5c5e..e2c967d0b0836 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -105,7 +105,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( f(&mut wfcx); let errors = wfcx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); return; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b6c91d425dff4..6f74ef3ccad6d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -321,7 +321,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: }), ); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); } // Finally, resolve all regions. @@ -561,7 +561,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]); let errors = traits::fully_solve_obligation(&infcx, predicate); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); } // Finally, resolve all regions. diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index e806e94879d93..267077cdab4e6 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -155,7 +155,7 @@ fn get_impl_substs<'tcx>( let errors = ocx.select_all_or_error(); if !errors.is_empty() { - ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None); return None; } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index bd1a461b93522..664d3a3a1db84 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -173,7 +173,7 @@ fn require_same_types<'tcx>( match &errors[..] { [] => true, errors => { - infcx.err_ctxt().report_fulfillment_errors(errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(errors, None); false } } @@ -336,7 +336,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { ocx.register_bound(cause, param_env, norm_return_ty, term_did); let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); error = true; } // now we can take the return type of the given main function diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index e8bf299b0378e..25306ebf35679 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -705,12 +705,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Object safety violations or miscellaneous. Err(err) => { - self.err_ctxt().report_selection_error( - obligation.clone(), - &obligation, - &err, - false, - ); + self.err_ctxt().report_selection_error(obligation.clone(), &obligation, &err); // Treat this like an obligation and follow through // with the unsizing - the lack of a coercion should // be silent, as it causes a type mismatch later. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 682dbab56bc15..89b5e5161a9c2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -843,7 +843,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Point any obligations that were registered due to opaque type // inference at the return expression. - self.select_obligations_where_possible(false, |errors| { + self.select_obligations_where_possible(|errors| { self.point_at_return_for_opaque_ty_error(errors, span, return_expr_ty); }); } @@ -2738,7 +2738,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some((index_ty, element_ty)) => { // two-phase not needed because index_ty is never mutable self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); - self.select_obligations_where_possible(false, |errors| { + self.select_obligations_where_possible(|errors| { self.point_at_index_if_possible(errors, idx.span) }); element_ty diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 747ecb036b2a1..5d44092a5f68e 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -7,16 +7,16 @@ use rustc_data_structures::{ use rustc_middle::ty::{self, Ty}; impl<'tcx> FnCtxt<'_, 'tcx> { - /// Performs type inference fallback, returning true if any fallback - /// occurs. - pub(super) fn type_inference_fallback(&self) -> bool { + /// Performs type inference fallback, setting `FnCtxt::fallback_has_occurred` + /// if fallback has occurred. + pub(super) fn type_inference_fallback(&self) { debug!( "type-inference-fallback start obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations() ); // All type checking constraints were added, try to fallback unsolved variables. - self.select_obligations_where_possible(false, |_| {}); + self.select_obligations_where_possible(|_| {}); debug!( "type-inference-fallback post selection obligations: {:#?}", @@ -26,18 +26,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // Check if we have any unsolved variables. If not, no need for fallback. let unsolved_variables = self.unsolved_variables(); if unsolved_variables.is_empty() { - return false; + return; } let diverging_fallback = self.calculate_diverging_fallback(&unsolved_variables); - let mut fallback_has_occurred = false; // We do fallback in two passes, to try to generate // better error messages. // The first time, we do *not* replace opaque types. for ty in unsolved_variables { debug!("unsolved_variable = {:?}", ty); - fallback_has_occurred |= self.fallback_if_possible(ty, &diverging_fallback); + self.fallback_if_possible(ty, &diverging_fallback); } // We now see if we can make progress. This might cause us to @@ -63,9 +62,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // If we had tried to fallback the opaque inference variable to `MyType`, // we will generate a confusing type-check error that does not explicitly // refer to opaque types. - self.select_obligations_where_possible(fallback_has_occurred, |_| {}); - - fallback_has_occurred + self.select_obligations_where_possible(|_| {}); } // Tries to apply a fallback to `ty` if it is an unsolved variable. @@ -81,12 +78,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // Fallback becomes very dubious if we have encountered // type-checking errors. In that case, fallback to Error. // - // The return value indicates whether fallback has occurred. + // Sets `FnCtxt::fallback_has_occurred` if fallback is performed + // during this call. fn fallback_if_possible( &self, ty: Ty<'tcx>, diverging_fallback: &FxHashMap, Ty<'tcx>>, - ) -> bool { + ) { // Careful: we do NOT shallow-resolve `ty`. We know that `ty` // is an unsolved variable, and we determine its fallback // based solely on how it was created, not what other type @@ -111,7 +109,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, _ => match diverging_fallback.get(&ty) { Some(&fallback_ty) => fallback_ty, - None => return false, + None => return, }, }; debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback); @@ -122,7 +120,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .map(|origin| origin.span) .unwrap_or(rustc_span::DUMMY_SP); self.demand_eqtype(span, ty, fallback); - true + self.fallback_has_occurred.set(true); } /// The "diverging fallback" system is rather complicated. This is diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7563c543d3f19..35323137e2d5a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // possible. This can help substantially when there are // indirect dependencies that don't seem worth tracking // precisely. - self.select_obligations_where_possible(false, mutate_fulfillment_errors); + self.select_obligations_where_possible(mutate_fulfillment_errors); self.resolve_vars_if_possible(ty) } @@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) { let mut generators = self.deferred_generator_interiors.borrow_mut(); for (body_id, interior, kind) in generators.drain(..) { - self.select_obligations_where_possible(false, |_| {}); + self.select_obligations_where_possible(|_| {}); crate::generator_interior::resolve_interior(self, def_id, body_id, interior, kind); } } @@ -611,25 +611,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !errors.is_empty() { self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); - self.err_ctxt().report_fulfillment_errors(&errors, self.inh.body_id, false); + self.err_ctxt().report_fulfillment_errors(&errors, self.inh.body_id); } } /// Select as many obligations as we can at present. pub(in super::super) fn select_obligations_where_possible( &self, - fallback_has_occurred: bool, mutate_fulfillment_errors: impl Fn(&mut Vec>), ) { let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self); if !result.is_empty() { mutate_fulfillment_errors(&mut result); self.adjust_fulfillment_errors_for_expr_obligation(&mut result); - self.err_ctxt().report_fulfillment_errors( - &result, - self.inh.body_id, - fallback_has_occurred, - ); + self.err_ctxt().report_fulfillment_errors(&result, self.inh.body_id); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 4066cca8a4bd4..a7a60a19bd37e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -345,7 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // an "opportunistic" trait resolution of any trait bounds on // the call. This helps coercions. if check_closures { - self.select_obligations_where_possible(false, |_| {}) + self.select_obligations_where_possible(|_| {}) } // Check each argument, to satisfy the input it was provided for diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 72388baa261ea..75984243aa731 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -115,6 +115,8 @@ pub struct FnCtxt<'a, 'tcx> { pub(super) enclosing_breakables: RefCell>, pub(super) inh: &'a Inherited<'tcx>, + + pub(super) fallback_has_occurred: Cell, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -138,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { by_id: Default::default(), }), inh, + fallback_has_occurred: Cell::new(false), } } @@ -159,7 +162,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// [`InferCtxt::err_ctxt`]: infer::InferCtxt::err_ctxt pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> { - TypeErrCtxt { infcx: &self.infcx, typeck_results: Some(self.typeck_results.borrow()) } + TypeErrCtxt { + infcx: &self.infcx, + typeck_results: Some(self.typeck_results.borrow()), + fallback_has_occurred: self.fallback_has_occurred.get(), + } } pub fn errors_reported_since_creation(&self) -> bool { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 624443d9594c9..052fdef2fc518 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -316,12 +316,12 @@ fn typeck_with_fallback<'tcx>( fcx }; - let fallback_has_occurred = fcx.type_inference_fallback(); + fcx.type_inference_fallback(); // Even though coercion casts provide type hints, we check casts after fallback for // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. fcx.check_casts(); - fcx.select_obligations_where_possible(fallback_has_occurred, |_| {}); + fcx.select_obligations_where_possible(|_| {}); // Closure and generator analysis may run after fallback // because they don't constrain other type variables. diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 8598369e884b4..c3bcbcc993b7c 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -772,7 +772,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match (method, trait_did) { (Some(ok), _) => { let method = self.register_infer_ok_obligations(ok); - self.select_obligations_where_possible(false, |_| {}); + self.select_obligations_where_possible(|_| {}); Ok(method) } (None, None) => Err(vec![]), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e4a76fbd45130..3dbc9b9f3f938 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -91,6 +91,7 @@ pub mod nice_region_error; pub struct TypeErrCtxt<'a, 'tcx> { pub infcx: &'a InferCtxt<'tcx>, pub typeck_results: Option>>, + pub fallback_has_occurred: bool, } impl TypeErrCtxt<'_, '_> { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c2eecd9e87a38..d5be9983ea7c6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -677,9 +677,9 @@ pub struct CombinedSnapshot<'tcx> { impl<'tcx> InferCtxt<'tcx> { /// Creates a `TypeErrCtxt` for emitting various inference errors. - /// During typeck, use `FnCtxt::infer_err` instead. + /// During typeck, use `FnCtxt::err_ctxt` instead. pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> { - TypeErrCtxt { infcx: self, typeck_results: None } + TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false } } /// calls `tcx.try_unify_abstract_consts` after diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 54281f9120547..f2275e2303aec 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -101,7 +101,6 @@ pub trait TypeErrCtxtExt<'tcx> { &self, errors: &[FulfillmentError<'tcx>], body_id: Option, - fallback_has_occurred: bool, ) -> ErrorGuaranteed; fn report_overflow_error( @@ -124,7 +123,6 @@ pub trait TypeErrCtxtExt<'tcx> { obligation: PredicateObligation<'tcx>, root_obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>, - fallback_has_occurred: bool, ); } @@ -375,7 +373,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { &self, errors: &[FulfillmentError<'tcx>], body_id: Option, - fallback_has_occurred: bool, ) -> ErrorGuaranteed { #[derive(Debug)] struct ErrorDescriptor<'tcx> { @@ -452,7 +449,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { for (error, suppressed) in iter::zip(errors, is_suppressed) { if !suppressed { - self.report_fulfillment_error(error, body_id, fallback_has_occurred); + self.report_fulfillment_error(error, body_id); } } @@ -534,7 +531,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { mut obligation: PredicateObligation<'tcx>, root_obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>, - fallback_has_occurred: bool, ) { self.set_tainted_by_errors(); let tcx = self.tcx; @@ -1015,7 +1011,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // variable that used to fallback to `()` now falling back to `!`. Issue a // note informing about the change in behaviour. if trait_predicate.skip_binder().self_ty().is_never() - && fallback_has_occurred + && self.fallback_has_occurred { let predicate = trait_predicate.map_bound(|mut trait_pred| { trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( @@ -1381,7 +1377,6 @@ trait InferCtxtPrivExt<'tcx> { &self, error: &FulfillmentError<'tcx>, body_id: Option, - fallback_has_occurred: bool, ); fn report_projection_error( @@ -1531,7 +1526,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { &self, error: &FulfillmentError<'tcx>, body_id: Option, - fallback_has_occurred: bool, ) { match error.code { FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { @@ -1539,7 +1533,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { error.obligation.clone(), &error.root_obligation, selection_error, - fallback_has_occurred, ); } FulfillmentErrorCode::CodeProjectionError(ref e) => { diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index be603c609cb36..b6ded4ce5a396 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -70,7 +70,7 @@ pub fn can_type_implement_copy<'tcx>( } } Err(errors) => { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + infcx.err_ctxt().report_fulfillment_errors(&errors, None); } }; } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a33534f5747fa..0d5e4cfd3bb96 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -214,7 +214,7 @@ fn do_normalize_predicates<'tcx>( let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) { Ok(predicates) => predicates, Err(errors) => { - let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); return Err(reported); } }; From 66f7f5f91a1f39f01c286a9d14450b17a27f46da Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 4 Nov 2022 06:09:35 +0000 Subject: [PATCH 218/482] Update linker-plugin-lto.md to contain up to Rust 1.65 The table rows were obtained via the script embedded in the page. --- src/doc/rustc/src/linker-plugin-lto.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index b1854b22a7cd6..5730f95ad2b95 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -136,7 +136,7 @@ able to get around this problem by setting `-Clinker=lld-link` in RUSTFLAGS ```sh rustup toolchain install --profile minimal nightly MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2) -LOWER_BOUND=61 +LOWER_BOUND=66 llvm_version() { toolchain="$1" @@ -193,5 +193,10 @@ The following table shows known good combinations of toolchain versions. | Rust 1.58 | Clang 13 | | Rust 1.59 | Clang 13 | | Rust 1.60 | Clang 14 | +| Rust 1.61 | Clang 14 | +| Rust 1.62 | Clang 14 | +| Rust 1.63 | Clang 14 | +| Rust 1.64 | Clang 14 | +| Rust 1.65 | Clang 15 | Note that the compatibility policy for this feature might change in the future. From c9c5e120b5f4a12ed7d613905098098b1143c20d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 7 Nov 2022 03:25:54 +0000 Subject: [PATCH 219/482] Migrate linker-plugin-lto.md compatibility table to show Rust ranges The helper shell script has been rewritten as a helper Python script that generates the range-based table. --- src/doc/rustc/src/linker-plugin-lto.md | 99 +++++++++++++------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index 5730f95ad2b95..9272b9ac9b2d4 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -131,24 +131,47 @@ able to get around this problem by setting `-Clinker=lld-link` in RUSTFLAGS ## Toolchain Compatibility - @@ -166,37 +189,13 @@ The following table shows known good combinations of toolchain versions. | Rust Version | Clang Version | |--------------|---------------| -| Rust 1.34 | Clang 8 | -| Rust 1.35 | Clang 8 | -| Rust 1.36 | Clang 8 | -| Rust 1.37 | Clang 8 | -| Rust 1.38 | Clang 9 | -| Rust 1.39 | Clang 9 | -| Rust 1.40 | Clang 9 | -| Rust 1.41 | Clang 9 | -| Rust 1.42 | Clang 9 | -| Rust 1.43 | Clang 9 | -| Rust 1.44 | Clang 9 | -| Rust 1.45 | Clang 10 | -| Rust 1.46 | Clang 10 | -| Rust 1.47 | Clang 11 | -| Rust 1.48 | Clang 11 | -| Rust 1.49 | Clang 11 | -| Rust 1.50 | Clang 11 | -| Rust 1.51 | Clang 11 | -| Rust 1.52 | Clang 12 | -| Rust 1.53 | Clang 12 | -| Rust 1.54 | Clang 12 | -| Rust 1.55 | Clang 12 | -| Rust 1.56 | Clang 13 | -| Rust 1.57 | Clang 13 | -| Rust 1.58 | Clang 13 | -| Rust 1.59 | Clang 13 | -| Rust 1.60 | Clang 14 | -| Rust 1.61 | Clang 14 | -| Rust 1.62 | Clang 14 | -| Rust 1.63 | Clang 14 | -| Rust 1.64 | Clang 14 | -| Rust 1.65 | Clang 15 | +| 1.34 - 1.37 | 8 | +| 1.38 - 1.44 | 9 | +| 1.45 - 1.46 | 10 | +| 1.47 - 1.51 | 11 | +| 1.52 - 1.55 | 12 | +| 1.56 - 1.59 | 13 | +| 1.60 - 1.64 | 14 | +| 1.65 | 15 | Note that the compatibility policy for this feature might change in the future. From eae431b5c14c3d5cb06b2d006eac5e3621b63a40 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 4 Nov 2022 21:17:39 +0000 Subject: [PATCH 220/482] Remove in_tail_expr from FnCtxt --- compiler/rustc_hir_typeck/src/_match.rs | 123 +++++++++++-------- compiler/rustc_hir_typeck/src/check.rs | 2 - compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 5 - 3 files changed, 73 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 8d39fa81165ea..6a4a6a5b0a546 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -1,6 +1,6 @@ use crate::coercion::{AsCoercionSite, CoerceMany}; use crate::{Diverges, Expectation, FnCtxt, Needs}; -use rustc_errors::{Applicability, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir::{self as hir, ExprKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::traits::Obligation; @@ -137,55 +137,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&arm.body), arm_ty, Some(&mut |err| { - let Some(ret) = self - .tcx - .hir() - .find_by_def_id(self.body_id.owner.def_id) - .and_then(|owner| owner.fn_decl()) - .map(|decl| decl.output.span()) - else { return; }; - let Expectation::IsLast(stmt) = orig_expected else { - return - }; - let can_coerce_to_return_ty = match self.ret_coercion.as_ref() { - Some(ret_coercion) if self.in_tail_expr => { - let ret_ty = ret_coercion.borrow().expected_ty(); - let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); - self.can_coerce(arm_ty, ret_ty) - && prior_arm.map_or(true, |(_, t, _)| self.can_coerce(t, ret_ty)) - // The match arms need to unify for the case of `impl Trait`. - && !matches!(ret_ty.kind(), ty::Opaque(..)) - } - _ => false, - }; - if !can_coerce_to_return_ty { - return; - } - - let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi()); - let mut ret_span: MultiSpan = semi_span.into(); - ret_span.push_span_label( - expr.span, - "this could be implicitly returned but it is a statement, not a \ - tail expression", - ); - ret_span - .push_span_label(ret, "the `match` arms can conform to this return type"); - ret_span.push_span_label( - semi_span, - "the `match` is a statement because of this semicolon, consider \ - removing it", - ); - err.span_note( - ret_span, - "you might have meant to return the `match` expression", - ); - err.tool_only_span_suggestion( - semi_span, - "remove this semicolon", - "", - Applicability::MaybeIncorrect, - ); + self.suggest_removing_semicolon_for_coerce( + err, + expr, + orig_expected, + arm_ty, + prior_arm, + ) }), false, ); @@ -219,6 +177,71 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coercion.complete(self) } + fn suggest_removing_semicolon_for_coerce( + &self, + diag: &mut Diagnostic, + expr: &hir::Expr<'tcx>, + expectation: Expectation<'tcx>, + arm_ty: Ty<'tcx>, + prior_arm: Option<(Option, Ty<'tcx>, Span)>, + ) { + let hir = self.tcx.hir(); + + // First, check that we're actually in the tail of a function. + let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Block(block, _), .. }) = + hir.get(self.body_id) else { return; }; + let Some(hir::Stmt { kind: hir::StmtKind::Semi(last_expr), .. }) + = block.innermost_block().stmts.last() else { return; }; + if last_expr.hir_id != expr.hir_id { + return; + } + + // Next, make sure that we have no type expectation. + let Some(ret) = hir + .find_by_def_id(self.body_id.owner.def_id) + .and_then(|owner| owner.fn_decl()) + .map(|decl| decl.output.span()) else { return; }; + let Expectation::IsLast(stmt) = expectation else { + return; + }; + + let can_coerce_to_return_ty = match self.ret_coercion.as_ref() { + Some(ret_coercion) => { + let ret_ty = ret_coercion.borrow().expected_ty(); + let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); + self.can_coerce(arm_ty, ret_ty) + && prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty)) + // The match arms need to unify for the case of `impl Trait`. + && !matches!(ret_ty.kind(), ty::Opaque(..)) + } + _ => false, + }; + if !can_coerce_to_return_ty { + return; + } + + let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi()); + let mut ret_span: MultiSpan = semi_span.into(); + ret_span.push_span_label( + expr.span, + "this could be implicitly returned but it is a statement, not a \ + tail expression", + ); + ret_span.push_span_label(ret, "the `match` arms can conform to this return type"); + ret_span.push_span_label( + semi_span, + "the `match` is a statement because of this semicolon, consider \ + removing it", + ); + diag.span_note(ret_span, "you might have meant to return the `match` expression"); + diag.tool_only_span_suggestion( + semi_span, + "remove this semicolon", + "", + Applicability::MaybeIncorrect, + ); + } + /// When the previously checked expression (the scrutinee) diverges, /// warn the user about the match arms being unreachable. fn warn_arms_when_scrutinee_diverges(&self, arms: &'tcx [hir::Arm<'tcx>]) { diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 37af6e79c3ef5..3c57e33f6f7fb 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -100,7 +100,6 @@ pub(super) fn check_fn<'a, 'tcx>( inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); - fcx.in_tail_expr = true; if let ty::Dynamic(..) = declared_ret_ty.kind() { // FIXME: We need to verify that the return type is `Sized` after the return expression has // been evaluated so that we have types available for all the nodes being returned, but that @@ -119,7 +118,6 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); fcx.check_return_expr(&body.value, false); } - fcx.in_tail_expr = false; // We insert the deferred_generator_interiors entry after visiting the body. // This ensures that all nested generators appear before the entry of this generator. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 75984243aa731..d5e4b6de581c3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -68,10 +68,6 @@ pub struct FnCtxt<'a, 'tcx> { /// any). pub(super) ret_coercion: Option>>, - /// Used exclusively to reduce cost of advanced evaluation used for - /// more helpful diagnostics. - pub(super) in_tail_expr: bool, - /// First span of a return site that we find. Used in error messages. pub(super) ret_coercion_span: Cell>, @@ -130,7 +126,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param_env, err_count_on_creation: inh.tcx.sess.err_count(), ret_coercion: None, - in_tail_expr: false, ret_coercion_span: Cell::new(None), resume_yield_tys: None, ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), From 51c80427fb3541749bdb7f1ed84ae1bd7a2fff40 Mon Sep 17 00:00:00 2001 From: jeremyd2019 Date: Sun, 6 Nov 2022 11:51:12 -0800 Subject: [PATCH 221/482] fix debuginfo for windows_gnullvm_base.rs These lines (including the FIXME comment) were added to windows_gnu_base.rs in cf2c492ef8c87c049b4e3a62f43c841aafc88cba but windows_gnullvm_base.rs was not updated. This resulted in an error `LLVM ERROR: dwo only supported with ELF and Wasm` attempting to build on aarch64-pc-windows-gnullvm. Signed-off-by: Jeremy Drake --- compiler/rustc_target/src/spec/windows_gnullvm_base.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs index 58210c75a3da2..cada28652f98a 100644 --- a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs @@ -1,4 +1,5 @@ -use crate::spec::{cvs, Cc, LinkerFlavor, Lld, TargetOptions}; +use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; +use std::borrow::Cow; pub fn opts() -> TargetOptions { // We cannot use `-nodefaultlibs` because compiler-rt has to be passed @@ -36,7 +37,10 @@ pub fn opts() -> TargetOptions { eh_frame_header: false, no_default_libraries: false, has_thread_local: true, - + // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to + // output DWO, despite using DWARF, doesn't use ELF.. + debuginfo_kind: DebuginfoKind::Pdb, + supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..Default::default() } } From dc7cf83f491a2d309ed9065b53bf9df30cad517b Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 7 Nov 2022 08:10:25 +0100 Subject: [PATCH 222/482] fully move `on_unimplemented` to error reporting --- .../rustc_hir_analysis/src/check/check.rs | 3 +- .../rustc_hir_typeck/src/method/suggest.rs | 3 +- .../src/traits/error_reporting/mod.rs | 16 +- .../error_reporting/on_unimplemented.rs | 398 +++++++++++++++++- .../rustc_trait_selection/src/traits/mod.rs | 2 - .../src/traits/on_unimplemented.rs | 393 ----------------- 6 files changed, 404 insertions(+), 411 deletions(-) delete mode 100644 compiler/rustc_trait_selection/src/traits/on_unimplemented.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 3170f8feffc66..0ba5e61510125 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -26,6 +26,7 @@ use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVE use rustc_span::symbol::sym; use rustc_span::{self, Span}; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -655,7 +656,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) { pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { // an error would be reported if this fails. - let _ = traits::OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id()); + let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id()); } pub(super) fn check_specialization_validity<'tcx>( diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 04ecd2757b427..50e2b0f89267d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -23,10 +23,11 @@ use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span}; +use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ - FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedNote, + FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, }; use std::cmp::Ordering; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f2275e2303aec..c7dee4a18ac5d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3,14 +3,17 @@ pub mod suggestions; use super::{ FulfillmentContext, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, - Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective, - OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation, - SelectionContext, SelectionError, TraitNotObjectSafe, + Obligation, ObligationCause, ObligationCauseCode, OutputTypeParameterMismatch, Overflow, + PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, }; - use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{self, InferCtxt, TyCtxtInferExt}; +use crate::traits::query::evaluate_obligation::InferCtxtExt as _; +use crate::traits::query::normalize::AtExt as _; +use crate::traits::specialize::to_pretty_impl_header; +use on_unimplemented::OnUnimplementedNote; +use on_unimplemented::TypeErrCtxtExt as _; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, @@ -40,11 +43,6 @@ use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; use std::iter; use std::ops::ControlFlow; - -use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::query::normalize::AtExt as _; -use crate::traits::specialize::to_pretty_impl_header; -use on_unimplemented::TypeErrCtxtExt as _; use suggestions::TypeErrCtxtExt as _; pub use rustc_infer::traits::error_reporting::*; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 5eef54c6330db..82f0440b3078b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -1,14 +1,22 @@ -use super::{ - ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, PredicateObligation, -}; +use super::{ObligationCauseCode, PredicateObligation}; use crate::infer::error_reporting::TypeErrCtxt; +use rustc_ast::{MetaItem, NestedMetaItem}; +use rustc_attr as attr; +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::SubstsRef; -use rustc_middle::ty::{self, GenericParamDefKind}; -use rustc_span::symbol::sym; +use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; +use rustc_parse_format::{ParseMode, Parser, Piece, Position}; +use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::{Span, DUMMY_SP}; use std::iter; +use crate::errors::{ + EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, +}; + use super::InferCtxtPrivExt; pub trait TypeErrCtxtExt<'tcx> { @@ -276,3 +284,383 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } } + +#[derive(Clone, Debug)] +pub struct OnUnimplementedFormatString(Symbol); + +#[derive(Debug)] +pub struct OnUnimplementedDirective { + pub condition: Option, + pub subcommands: Vec, + pub message: Option, + pub label: Option, + pub note: Option, + pub parent_label: Option, + pub append_const_msg: Option>, +} + +/// For the `#[rustc_on_unimplemented]` attribute +#[derive(Default)] +pub struct OnUnimplementedNote { + pub message: Option, + pub label: Option, + pub note: Option, + pub parent_label: Option, + /// Append a message for `~const Trait` errors. `None` means not requested and + /// should fallback to a generic message, `Some(None)` suggests using the default + /// appended message, `Some(Some(s))` suggests use the `s` message instead of the + /// default one.. + pub append_const_msg: Option>, +} + +impl<'tcx> OnUnimplementedDirective { + fn parse( + tcx: TyCtxt<'tcx>, + item_def_id: DefId, + items: &[NestedMetaItem], + span: Span, + is_root: bool, + ) -> Result { + let mut errored = None; + let mut item_iter = items.iter(); + + let parse_value = |value_str| { + OnUnimplementedFormatString::try_parse(tcx, item_def_id, value_str, span).map(Some) + }; + + let condition = if is_root { + None + } else { + let cond = item_iter + .next() + .ok_or_else(|| tcx.sess.emit_err(EmptyOnClauseInOnUnimplemented { span }))? + .meta_item() + .ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?; + attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| { + if let Some(value) = cfg.value && let Err(guar) = parse_value(value) { + errored = Some(guar); + } + true + }); + Some(cond.clone()) + }; + + let mut message = None; + let mut label = None; + let mut note = None; + let mut parent_label = None; + let mut subcommands = vec![]; + let mut append_const_msg = None; + + for item in item_iter { + if item.has_name(sym::message) && message.is_none() { + if let Some(message_) = item.value_str() { + message = parse_value(message_)?; + continue; + } + } else if item.has_name(sym::label) && label.is_none() { + if let Some(label_) = item.value_str() { + label = parse_value(label_)?; + continue; + } + } else if item.has_name(sym::note) && note.is_none() { + if let Some(note_) = item.value_str() { + note = parse_value(note_)?; + continue; + } + } else if item.has_name(sym::parent_label) && parent_label.is_none() { + if let Some(parent_label_) = item.value_str() { + parent_label = parse_value(parent_label_)?; + continue; + } + } else if item.has_name(sym::on) + && is_root + && message.is_none() + && label.is_none() + && note.is_none() + { + if let Some(items) = item.meta_item_list() { + match Self::parse(tcx, item_def_id, &items, item.span(), false) { + Ok(subcommand) => subcommands.push(subcommand), + Err(reported) => errored = Some(reported), + }; + continue; + } + } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { + if let Some(msg) = item.value_str() { + append_const_msg = Some(Some(msg)); + continue; + } else if item.is_word() { + append_const_msg = Some(None); + continue; + } + } + + // nothing found + tcx.sess.emit_err(NoValueInOnUnimplemented { span: item.span() }); + } + + if let Some(reported) = errored { + Err(reported) + } else { + Ok(OnUnimplementedDirective { + condition, + subcommands, + message, + label, + note, + parent_label, + append_const_msg, + }) + } + } + + pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result, ErrorGuaranteed> { + let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) else { + return Ok(None); + }; + + let result = if let Some(items) = attr.meta_item_list() { + Self::parse(tcx, item_def_id, &items, attr.span, true).map(Some) + } else if let Some(value) = attr.value_str() { + Ok(Some(OnUnimplementedDirective { + condition: None, + message: None, + subcommands: vec![], + label: Some(OnUnimplementedFormatString::try_parse( + tcx, + item_def_id, + value, + attr.span, + )?), + note: None, + parent_label: None, + append_const_msg: None, + })) + } else { + let reported = + tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + return Err(reported); + }; + debug!("of_item({:?}) = {:?}", item_def_id, result); + result + } + + pub fn evaluate( + &self, + tcx: TyCtxt<'tcx>, + trait_ref: ty::TraitRef<'tcx>, + options: &[(Symbol, Option)], + ) -> OnUnimplementedNote { + let mut message = None; + let mut label = None; + let mut note = None; + let mut parent_label = None; + let mut append_const_msg = None; + info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); + + let options_map: FxHashMap = + options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect(); + + for command in self.subcommands.iter().chain(Some(self)).rev() { + if let Some(ref condition) = command.condition && !attr::eval_condition( + condition, + &tcx.sess.parse_sess, + Some(tcx.features()), + &mut |cfg| { + let value = cfg.value.map(|v| { + OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map) + }); + + options.contains(&(cfg.name, value)) + }, + ) { + debug!("evaluate: skipping {:?} due to condition", command); + continue; + } + debug!("evaluate: {:?} succeeded", command); + if let Some(ref message_) = command.message { + message = Some(message_.clone()); + } + + if let Some(ref label_) = command.label { + label = Some(label_.clone()); + } + + if let Some(ref note_) = command.note { + note = Some(note_.clone()); + } + + if let Some(ref parent_label_) = command.parent_label { + parent_label = Some(parent_label_.clone()); + } + + append_const_msg = command.append_const_msg; + } + + OnUnimplementedNote { + label: label.map(|l| l.format(tcx, trait_ref, &options_map)), + message: message.map(|m| m.format(tcx, trait_ref, &options_map)), + note: note.map(|n| n.format(tcx, trait_ref, &options_map)), + parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)), + append_const_msg, + } + } +} + +impl<'tcx> OnUnimplementedFormatString { + fn try_parse( + tcx: TyCtxt<'tcx>, + item_def_id: DefId, + from: Symbol, + err_sp: Span, + ) -> Result { + let result = OnUnimplementedFormatString(from); + result.verify(tcx, item_def_id, err_sp)?; + Ok(result) + } + + fn verify( + &self, + tcx: TyCtxt<'tcx>, + item_def_id: DefId, + span: Span, + ) -> Result<(), ErrorGuaranteed> { + let trait_def_id = if tcx.is_trait(item_def_id) { + item_def_id + } else { + tcx.trait_id_of_impl(item_def_id) + .expect("expected `on_unimplemented` to correspond to a trait") + }; + let trait_name = tcx.item_name(trait_def_id); + let generics = tcx.generics_of(item_def_id); + let s = self.0.as_str(); + let parser = Parser::new(s, None, None, false, ParseMode::Format); + let mut result = Ok(()); + for token in parser { + match token { + Piece::String(_) => (), // Normal string, no need to check it + Piece::NextArgument(a) => match a.position { + Position::ArgumentNamed(s) => { + match Symbol::intern(s) { + // `{Self}` is allowed + kw::SelfUpper => (), + // `{ThisTraitsName}` is allowed + s if s == trait_name => (), + // `{from_method}` is allowed + sym::from_method => (), + // `{from_desugaring}` is allowed + sym::from_desugaring => (), + // `{ItemContext}` is allowed + sym::ItemContext => (), + // `{integral}` and `{integer}` and `{float}` are allowed + sym::integral | sym::integer_ | sym::float => (), + // So is `{A}` if A is a type parameter + s => match generics.params.iter().find(|param| param.name == s) { + Some(_) => (), + None => { + let reported = struct_span_err!( + tcx.sess, + span, + E0230, + "there is no parameter `{}` on {}", + s, + if trait_def_id == item_def_id { + format!("trait `{}`", trait_name) + } else { + "impl".to_string() + } + ) + .emit(); + result = Err(reported); + } + }, + } + } + // `{:1}` and `{}` are not to be used + Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => { + let reported = struct_span_err!( + tcx.sess, + span, + E0231, + "only named substitution parameters are allowed" + ) + .emit(); + result = Err(reported); + } + }, + } + } + + result + } + + pub fn format( + &self, + tcx: TyCtxt<'tcx>, + trait_ref: ty::TraitRef<'tcx>, + options: &FxHashMap, + ) -> String { + let name = tcx.item_name(trait_ref.def_id); + let trait_str = tcx.def_path_str(trait_ref.def_id); + let generics = tcx.generics_of(trait_ref.def_id); + let generic_map = generics + .params + .iter() + .filter_map(|param| { + let value = match param.kind { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + trait_ref.substs[param.index as usize].to_string() + } + GenericParamDefKind::Lifetime => return None, + }; + let name = param.name; + Some((name, value)) + }) + .collect::>(); + let empty_string = String::new(); + + let s = self.0.as_str(); + let parser = Parser::new(s, None, None, false, ParseMode::Format); + let item_context = (options.get(&sym::ItemContext)).unwrap_or(&empty_string); + parser + .map(|p| match p { + Piece::String(s) => s, + Piece::NextArgument(a) => match a.position { + Position::ArgumentNamed(s) => { + let s = Symbol::intern(s); + match generic_map.get(&s) { + Some(val) => val, + None if s == name => &trait_str, + None => { + if let Some(val) = options.get(&s) { + val + } else if s == sym::from_desugaring || s == sym::from_method { + // don't break messages using these two arguments incorrectly + &empty_string + } else if s == sym::ItemContext { + &item_context + } else if s == sym::integral { + "{integral}" + } else if s == sym::integer_ { + "{integer}" + } else if s == sym::float { + "{float}" + } else { + bug!( + "broken on_unimplemented {:?} for {:?}: \ + no argument matching {:?}", + self.0, + trait_ref, + s + ) + } + } + } + } + _ => bug!("broken on_unimplemented {:?} - bad format arg", self.0), + }, + }) + .collect() + } +} diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0d5e4cfd3bb96..10e48610e3abb 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -12,7 +12,6 @@ pub mod error_reporting; mod fulfill; pub mod misc; mod object_safety; -mod on_unimplemented; pub mod outlives_bounds; mod project; pub mod query; @@ -58,7 +57,6 @@ pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::ObjectSafetyViolation; -pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote}; pub use self::project::{normalize, normalize_projection_type, normalize_to}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs deleted file mode 100644 index fb062ea71c4ce..0000000000000 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ /dev/null @@ -1,393 +0,0 @@ -use rustc_ast::{MetaItem, NestedMetaItem}; -use rustc_attr as attr; -use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, ErrorGuaranteed}; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; -use rustc_parse_format::{ParseMode, Parser, Piece, Position}; -use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{Span, DUMMY_SP}; - -use crate::errors::{ - EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, -}; - -#[derive(Clone, Debug)] -pub struct OnUnimplementedFormatString(Symbol); - -#[derive(Debug)] -pub struct OnUnimplementedDirective { - pub condition: Option, - pub subcommands: Vec, - pub message: Option, - pub label: Option, - pub note: Option, - pub parent_label: Option, - pub append_const_msg: Option>, -} - -#[derive(Default)] -/// For the `#[rustc_on_unimplemented]` attribute -pub struct OnUnimplementedNote { - pub message: Option, - pub label: Option, - pub note: Option, - pub parent_label: Option, - /// Append a message for `~const Trait` errors. `None` means not requested and - /// should fallback to a generic message, `Some(None)` suggests using the default - /// appended message, `Some(Some(s))` suggests use the `s` message instead of the - /// default one.. - pub append_const_msg: Option>, -} - -impl<'tcx> OnUnimplementedDirective { - fn parse( - tcx: TyCtxt<'tcx>, - item_def_id: DefId, - items: &[NestedMetaItem], - span: Span, - is_root: bool, - ) -> Result { - let mut errored = None; - let mut item_iter = items.iter(); - - let parse_value = |value_str| { - OnUnimplementedFormatString::try_parse(tcx, item_def_id, value_str, span).map(Some) - }; - - let condition = if is_root { - None - } else { - let cond = item_iter - .next() - .ok_or_else(|| tcx.sess.emit_err(EmptyOnClauseInOnUnimplemented { span }))? - .meta_item() - .ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?; - attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| { - if let Some(value) = cfg.value && let Err(guar) = parse_value(value) { - errored = Some(guar); - } - true - }); - Some(cond.clone()) - }; - - let mut message = None; - let mut label = None; - let mut note = None; - let mut parent_label = None; - let mut subcommands = vec![]; - let mut append_const_msg = None; - - for item in item_iter { - if item.has_name(sym::message) && message.is_none() { - if let Some(message_) = item.value_str() { - message = parse_value(message_)?; - continue; - } - } else if item.has_name(sym::label) && label.is_none() { - if let Some(label_) = item.value_str() { - label = parse_value(label_)?; - continue; - } - } else if item.has_name(sym::note) && note.is_none() { - if let Some(note_) = item.value_str() { - note = parse_value(note_)?; - continue; - } - } else if item.has_name(sym::parent_label) && parent_label.is_none() { - if let Some(parent_label_) = item.value_str() { - parent_label = parse_value(parent_label_)?; - continue; - } - } else if item.has_name(sym::on) - && is_root - && message.is_none() - && label.is_none() - && note.is_none() - { - if let Some(items) = item.meta_item_list() { - match Self::parse(tcx, item_def_id, &items, item.span(), false) { - Ok(subcommand) => subcommands.push(subcommand), - Err(reported) => errored = Some(reported), - }; - continue; - } - } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { - if let Some(msg) = item.value_str() { - append_const_msg = Some(Some(msg)); - continue; - } else if item.is_word() { - append_const_msg = Some(None); - continue; - } - } - - // nothing found - tcx.sess.emit_err(NoValueInOnUnimplemented { span: item.span() }); - } - - if let Some(reported) = errored { - Err(reported) - } else { - Ok(OnUnimplementedDirective { - condition, - subcommands, - message, - label, - note, - parent_label, - append_const_msg, - }) - } - } - - pub fn of_item(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> Result, ErrorGuaranteed> { - let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented) else { - return Ok(None); - }; - - let result = if let Some(items) = attr.meta_item_list() { - Self::parse(tcx, item_def_id, &items, attr.span, true).map(Some) - } else if let Some(value) = attr.value_str() { - Ok(Some(OnUnimplementedDirective { - condition: None, - message: None, - subcommands: vec![], - label: Some(OnUnimplementedFormatString::try_parse( - tcx, - item_def_id, - value, - attr.span, - )?), - note: None, - parent_label: None, - append_const_msg: None, - })) - } else { - let reported = - tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); - return Err(reported); - }; - debug!("of_item({:?}) = {:?}", item_def_id, result); - result - } - - pub fn evaluate( - &self, - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - options: &[(Symbol, Option)], - ) -> OnUnimplementedNote { - let mut message = None; - let mut label = None; - let mut note = None; - let mut parent_label = None; - let mut append_const_msg = None; - info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); - - let options_map: FxHashMap = - options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect(); - - for command in self.subcommands.iter().chain(Some(self)).rev() { - if let Some(ref condition) = command.condition && !attr::eval_condition( - condition, - &tcx.sess.parse_sess, - Some(tcx.features()), - &mut |cfg| { - let value = cfg.value.map(|v| { - OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map) - }); - - options.contains(&(cfg.name, value)) - }, - ) { - debug!("evaluate: skipping {:?} due to condition", command); - continue; - } - debug!("evaluate: {:?} succeeded", command); - if let Some(ref message_) = command.message { - message = Some(message_.clone()); - } - - if let Some(ref label_) = command.label { - label = Some(label_.clone()); - } - - if let Some(ref note_) = command.note { - note = Some(note_.clone()); - } - - if let Some(ref parent_label_) = command.parent_label { - parent_label = Some(parent_label_.clone()); - } - - append_const_msg = command.append_const_msg; - } - - OnUnimplementedNote { - label: label.map(|l| l.format(tcx, trait_ref, &options_map)), - message: message.map(|m| m.format(tcx, trait_ref, &options_map)), - note: note.map(|n| n.format(tcx, trait_ref, &options_map)), - parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)), - append_const_msg, - } - } -} - -impl<'tcx> OnUnimplementedFormatString { - fn try_parse( - tcx: TyCtxt<'tcx>, - item_def_id: DefId, - from: Symbol, - err_sp: Span, - ) -> Result { - let result = OnUnimplementedFormatString(from); - result.verify(tcx, item_def_id, err_sp)?; - Ok(result) - } - - fn verify( - &self, - tcx: TyCtxt<'tcx>, - item_def_id: DefId, - span: Span, - ) -> Result<(), ErrorGuaranteed> { - let trait_def_id = if tcx.is_trait(item_def_id) { - item_def_id - } else { - tcx.trait_id_of_impl(item_def_id) - .expect("expected `on_unimplemented` to correspond to a trait") - }; - let trait_name = tcx.item_name(trait_def_id); - let generics = tcx.generics_of(item_def_id); - let s = self.0.as_str(); - let parser = Parser::new(s, None, None, false, ParseMode::Format); - let mut result = Ok(()); - for token in parser { - match token { - Piece::String(_) => (), // Normal string, no need to check it - Piece::NextArgument(a) => match a.position { - Position::ArgumentNamed(s) => { - match Symbol::intern(s) { - // `{Self}` is allowed - kw::SelfUpper => (), - // `{ThisTraitsName}` is allowed - s if s == trait_name => (), - // `{from_method}` is allowed - sym::from_method => (), - // `{from_desugaring}` is allowed - sym::from_desugaring => (), - // `{ItemContext}` is allowed - sym::ItemContext => (), - // `{integral}` and `{integer}` and `{float}` are allowed - sym::integral | sym::integer_ | sym::float => (), - // So is `{A}` if A is a type parameter - s => match generics.params.iter().find(|param| param.name == s) { - Some(_) => (), - None => { - let reported = struct_span_err!( - tcx.sess, - span, - E0230, - "there is no parameter `{}` on {}", - s, - if trait_def_id == item_def_id { - format!("trait `{}`", trait_name) - } else { - "impl".to_string() - } - ) - .emit(); - result = Err(reported); - } - }, - } - } - // `{:1}` and `{}` are not to be used - Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => { - let reported = struct_span_err!( - tcx.sess, - span, - E0231, - "only named substitution parameters are allowed" - ) - .emit(); - result = Err(reported); - } - }, - } - } - - result - } - - pub fn format( - &self, - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - options: &FxHashMap, - ) -> String { - let name = tcx.item_name(trait_ref.def_id); - let trait_str = tcx.def_path_str(trait_ref.def_id); - let generics = tcx.generics_of(trait_ref.def_id); - let generic_map = generics - .params - .iter() - .filter_map(|param| { - let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize].to_string() - } - GenericParamDefKind::Lifetime => return None, - }; - let name = param.name; - Some((name, value)) - }) - .collect::>(); - let empty_string = String::new(); - - let s = self.0.as_str(); - let parser = Parser::new(s, None, None, false, ParseMode::Format); - let item_context = (options.get(&sym::ItemContext)).unwrap_or(&empty_string); - parser - .map(|p| match p { - Piece::String(s) => s, - Piece::NextArgument(a) => match a.position { - Position::ArgumentNamed(s) => { - let s = Symbol::intern(s); - match generic_map.get(&s) { - Some(val) => val, - None if s == name => &trait_str, - None => { - if let Some(val) = options.get(&s) { - val - } else if s == sym::from_desugaring || s == sym::from_method { - // don't break messages using these two arguments incorrectly - &empty_string - } else if s == sym::ItemContext { - &item_context - } else if s == sym::integral { - "{integral}" - } else if s == sym::integer_ { - "{integer}" - } else if s == sym::float { - "{float}" - } else { - bug!( - "broken on_unimplemented {:?} for {:?}: \ - no argument matching {:?}", - self.0, - trait_ref, - s - ) - } - } - } - } - _ => bug!("broken on_unimplemented {:?} - bad format arg", self.0), - }, - }) - .collect() - } -} From 45e0200753aaeab01acaa7b3036c5843fbfbcc10 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Nov 2022 17:14:05 +0000 Subject: [PATCH 223/482] Don't normalize constants unless they need normalization --- compiler/rustc_trait_selection/src/traits/project.rs | 2 +- compiler/rustc_trait_selection/src/traits/query/normalize.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index daee5dd8f02e6..7f829e46bbb1b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -647,7 +647,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { #[instrument(skip(self), level = "debug")] fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); - if tcx.lazy_normalization() { + if tcx.lazy_normalization() || !needs_normalization(&constant, self.param_env.reveal()) { constant } else { let constant = constant.super_fold_with(self); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 715f5be8e2f4b..a7932b332c94b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -353,6 +353,10 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { &mut self, constant: ty::Const<'tcx>, ) -> Result, Self::Error> { + if !needs_normalization(&constant, self.param_env.reveal()) { + return Ok(constant); + } + let constant = constant.try_super_fold_with(self)?; debug!(?constant, ?self.param_env); Ok(crate::traits::project::with_replaced_escaping_bound_vars( From ea7e1fd03fef7ae2e2138400c2f72795aa847705 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 28 Oct 2022 14:58:21 +0400 Subject: [PATCH 224/482] resolve: More detailed effective visibility tracking for imports Also drop `extern` blocks from the effective visibility table, they are nominally private and it doesn't make sense to keep them there. --- compiler/rustc_middle/src/middle/privacy.rs | 43 ++-- .../src/effective_visibilities.rs | 205 +++++++++++------- compiler/rustc_resolve/src/lib.rs | 19 +- src/test/ui/privacy/effective_visibilities.rs | 2 +- .../ui/privacy/effective_visibilities.stderr | 2 +- .../ui/privacy/effective_visibilities_glob.rs | 21 ++ .../effective_visibilities_glob.stderr | 26 +++ 7 files changed, 212 insertions(+), 106 deletions(-) create mode 100644 src/test/ui/privacy/effective_visibilities_glob.rs create mode 100644 src/test/ui/privacy/effective_visibilities_glob.stderr diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index ffbd6d10da6b2..3d7a379c56cd1 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -7,6 +7,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_span::def_id::LocalDefId; +use std::hash::Hash; /// Represents the levels of effective visibility an item can have. /// @@ -74,9 +75,9 @@ impl EffectiveVisibility { } /// Holds a map of effective visibilities for reachable HIR nodes. -#[derive(Default, Clone, Debug)] -pub struct EffectiveVisibilities { - map: FxHashMap, +#[derive(Clone, Debug)] +pub struct EffectiveVisibilities { + map: FxHashMap, } impl EffectiveVisibilities { @@ -111,10 +112,6 @@ impl EffectiveVisibilities { }) } - pub fn effective_vis(&self, id: LocalDefId) -> Option<&EffectiveVisibility> { - self.map.get(&id) - } - pub fn iter(&self) -> impl Iterator { self.map.iter() } @@ -136,27 +133,31 @@ impl EffectiveVisibilities { } self.map.insert(id, effective_vis); } +} + +impl EffectiveVisibilities { + pub fn effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { + self.map.get(&id) + } // `parent_id` is not necessarily a parent in source code tree, // it is the node from which the maximum effective visibility is inherited. pub fn update( &mut self, - id: LocalDefId, + id: Id, nominal_vis: Visibility, - default_vis: impl FnOnce() -> Visibility, - parent_id: LocalDefId, + default_vis: Visibility, + inherited_eff_vis: Option, level: Level, tree: impl DefIdTree, ) -> bool { let mut changed = false; - let mut current_effective_vis = self.effective_vis(id).copied().unwrap_or_else(|| { - if id.is_top_level_module() { - EffectiveVisibility::from_vis(Visibility::Public) - } else { - EffectiveVisibility::from_vis(default_vis()) - } - }); - if let Some(inherited_effective_vis) = self.effective_vis(parent_id) { + let mut current_effective_vis = self + .map + .get(&id) + .copied() + .unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis)); + if let Some(inherited_effective_vis) = inherited_eff_vis { let mut inherited_effective_vis_at_prev_level = *inherited_effective_vis.at_level(level); let mut calculated_effective_vis = inherited_effective_vis_at_prev_level; @@ -194,6 +195,12 @@ impl EffectiveVisibilities { } } +impl Default for EffectiveVisibilities { + fn default() -> Self { + EffectiveVisibilities { map: Default::default() } + } +} + impl<'a> HashStable> for EffectiveVisibilities { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let EffectiveVisibilities { ref map } = *self; diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 17ce854cb4388..56dde6f8ca74e 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -1,16 +1,38 @@ -use crate::{ImportKind, NameBindingKind, Resolver}; +use crate::{ImportKind, NameBinding, NameBindingKind, Resolver, ResolverTree}; use rustc_ast::ast; use rustc_ast::visit; use rustc_ast::visit::Visitor; use rustc_ast::Crate; use rustc_ast::EnumDef; +use rustc_data_structures::intern::Interned; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_middle::middle::privacy::Level; -use rustc_middle::ty::{DefIdTree, Visibility}; +use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; +use rustc_middle::ty::Visibility; + +type ImportId<'a> = Interned<'a, NameBinding<'a>>; + +#[derive(Clone, Copy)] +enum ParentId<'a> { + Def(LocalDefId), + Import(ImportId<'a>), +} + +impl ParentId<'_> { + fn level(self) -> Level { + match self { + ParentId::Def(_) => Level::Direct, + ParentId::Import(_) => Level::Reexported, + } + } +} pub struct EffectiveVisibilitiesVisitor<'r, 'a> { r: &'r mut Resolver<'a>, + /// While walking import chains we need to track effective visibilities per-binding, and def id + /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple + /// bindings can correspond to a single def id in imports. So we keep a separate table. + import_effective_visibilities: EffectiveVisibilities>, changed: bool, } @@ -19,21 +41,25 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we /// need access to a TyCtxt for that. pub fn compute_effective_visibilities<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) { - let mut visitor = EffectiveVisibilitiesVisitor { r, changed: false }; + let mut visitor = EffectiveVisibilitiesVisitor { + r, + import_effective_visibilities: Default::default(), + changed: false, + }; - visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, Level::Direct); + visitor.update(CRATE_DEF_ID, CRATE_DEF_ID); visitor.set_bindings_effective_visibilities(CRATE_DEF_ID); while visitor.changed { - visitor.reset(); + visitor.changed = false; visit::walk_crate(&mut visitor, krate); } info!("resolve::effective_visibilities: {:#?}", r.effective_visibilities); } - fn reset(&mut self) { - self.changed = false; + fn nearest_normal_mod(&mut self, def_id: LocalDefId) -> LocalDefId { + self.r.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local() } /// Update effective visibilities of bindings in the given module, @@ -48,92 +74,114 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { // Set the given effective visibility level to `Level::Direct` and // sets the rest of the `use` chain to `Level::Reexported` until // we hit the actual exported item. - - // FIXME: tag and is_public() condition should be removed, but assertions occur. - let tag = if binding.is_import() { Level::Reexported } else { Level::Direct }; - if binding.vis.is_public() { - let mut prev_parent_id = module_id; - let mut level = Level::Direct; - while let NameBindingKind::Import { binding: nested_binding, import, .. } = - binding.kind - { + let mut parent_id = ParentId::Def(module_id); + while let NameBindingKind::Import { binding: nested_binding, import, .. } = + binding.kind + { + let binding_id = ImportId::new_unchecked(binding); + self.update_import(binding_id, parent_id); + + // Update visibilities for import ids. These are not used during this pass, + // because we have more detailed binding-based information, but are used by + // later passes. Effective visibility of an import def id is the maximum value + // among visibilities of bindings corresponding to that def id. + if let Some(node_id) = import.id() { let mut update = |node_id| { - self.update( + self.update_def( self.r.local_def_id(node_id), binding.vis.expect_local(), - prev_parent_id, - level, + parent_id, ) }; - match import.kind { - ImportKind::Single { id, additional_ids, .. } => { - // In theory all the import IDs have individual visibilities and - // effective visibilities, but in practice these IDs go straigth to - // HIR where all their few uses assume that their (effective) - // visibility applies to the whole syntactic `use` item. So we - // update them all to the maximum value among the potential - // individual effective visibilities. Maybe HIR for imports - // shouldn't use three IDs at all. - update(id); - update(additional_ids.0); - update(additional_ids.1); - prev_parent_id = self.r.local_def_id(id); - } - ImportKind::Glob { id, .. } | ImportKind::ExternCrate { id, .. } => { - update(id); - prev_parent_id = self.r.local_def_id(id); + update(node_id); + if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind { + // In theory all the single import IDs have individual visibilities and + // effective visibilities, but in practice these IDs go straigth to HIR + // where all their few uses assume that their (effective) visibility + // applies to the whole syntactic `use` item. So they all get the same + // value which is the maximum of all bindings. Maybe HIR for imports + // shouldn't use three IDs at all. + if id1 != ast::DUMMY_NODE_ID { + update(id1); } - ImportKind::MacroUse => { - // In theory we should reset the parent id to something private - // here, but `macro_use` imports always refer to external items, - // so it doesn't matter and we can just do nothing. - } - ImportKind::MacroExport => { - // In theory we should reset the parent id to something public - // here, but it has the same effect as leaving the previous parent, - // so we can just do nothing. + if id2 != ast::DUMMY_NODE_ID { + update(id2); } } - - level = Level::Reexported; - binding = nested_binding; } + + parent_id = ParentId::Import(binding_id); + binding = nested_binding; } if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { - self.update(def_id, binding.vis.expect_local(), module_id, tag); + self.update_def(def_id, binding.vis.expect_local(), parent_id); } } } } - fn update( - &mut self, - def_id: LocalDefId, + fn effective_vis(&self, parent_id: ParentId<'a>) -> Option { + match parent_id { + ParentId::Def(def_id) => self.r.effective_visibilities.effective_vis(def_id), + ParentId::Import(binding) => self.import_effective_visibilities.effective_vis(binding), + } + .copied() + } + + /// The update is guaranteed to not change the table and we can skip it. + fn is_noop_update( + &self, + parent_id: ParentId<'a>, nominal_vis: Visibility, - parent_id: LocalDefId, - tag: Level, - ) { - let module_id = self - .r - .get_nearest_non_block_module(def_id.to_def_id()) - .nearest_parent_mod() - .expect_local(); - if nominal_vis == Visibility::Restricted(module_id) - || self.r.visibilities[&parent_id] == Visibility::Restricted(module_id) - { + default_vis: Visibility, + ) -> bool { + nominal_vis == default_vis + || match parent_id { + ParentId::Def(def_id) => self.r.visibilities[&def_id], + ParentId::Import(binding) => binding.vis.expect_local(), + } == default_vis + } + + fn update_import(&mut self, binding: ImportId<'a>, parent_id: ParentId<'a>) { + let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; + let nominal_vis = binding.vis.expect_local(); + let default_vis = Visibility::Restricted( + import + .id() + .map(|id| self.nearest_normal_mod(self.r.local_def_id(id))) + .unwrap_or(CRATE_DEF_ID), + ); + if self.is_noop_update(parent_id, nominal_vis, default_vis) { + return; + } + self.changed |= self.import_effective_visibilities.update( + binding, + nominal_vis, + default_vis, + self.effective_vis(parent_id), + parent_id.level(), + ResolverTree(&self.r.definitions, &self.r.crate_loader), + ); + } + + fn update_def(&mut self, def_id: LocalDefId, nominal_vis: Visibility, parent_id: ParentId<'a>) { + let default_vis = Visibility::Restricted(self.nearest_normal_mod(def_id)); + if self.is_noop_update(parent_id, nominal_vis, default_vis) { return; } - let mut effective_visibilities = std::mem::take(&mut self.r.effective_visibilities); - self.changed |= effective_visibilities.update( + self.changed |= self.r.effective_visibilities.update( def_id, nominal_vis, - || Visibility::Restricted(module_id), - parent_id, - tag, - &*self.r, + if def_id == CRATE_DEF_ID { Visibility::Public } else { default_vis }, + self.effective_vis(parent_id), + parent_id.level(), + ResolverTree(&self.r.definitions, &self.r.crate_loader), ); - self.r.effective_visibilities = effective_visibilities; + } + + fn update(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { + self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id)); } } @@ -151,12 +199,6 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> { "ast::ItemKind::MacCall encountered, this should not anymore appear at this stage" ), - // Foreign modules inherit level from parents. - ast::ItemKind::ForeignMod(..) => { - let parent_id = self.r.local_parent(def_id); - self.update(def_id, Visibility::Public, parent_id, Level::Direct); - } - ast::ItemKind::Mod(..) => { self.set_bindings_effective_visibilities(def_id); visit::walk_item(self, item); @@ -167,18 +209,14 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> { for variant in variants { let variant_def_id = self.r.local_def_id(variant.id); for field in variant.data.fields() { - let field_def_id = self.r.local_def_id(field.id); - let vis = self.r.visibilities[&field_def_id]; - self.update(field_def_id, vis, variant_def_id, Level::Direct); + self.update(self.r.local_def_id(field.id), variant_def_id); } } } ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { for field in def.fields() { - let field_def_id = self.r.local_def_id(field.id); - let vis = self.r.visibilities[&field_def_id]; - self.update(field_def_id, vis, def_id, Level::Direct); + self.update(self.r.local_def_id(field.id), def_id); } } @@ -194,6 +232,7 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> { | ast::ItemKind::TyAlias(..) | ast::ItemKind::TraitAlias(..) | ast::ItemKind::MacroDef(..) + | ast::ItemKind::ForeignMod(..) | ast::ItemKind::Fn(..) => return, } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ee1c97d5ad2b7..a1ff477c6fefb 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1106,17 +1106,30 @@ impl<'a> AsMut> for Resolver<'a> { } } -impl<'a, 'b> DefIdTree for &'a Resolver<'b> { +/// A minimal subset of resolver that can implemenent `DefIdTree`, sometimes +/// required to satisfy borrow checker by avoiding borrowing the whole resolver. +#[derive(Clone, Copy)] +struct ResolverTree<'a, 'b>(&'a Definitions, &'a CrateLoader<'b>); + +impl DefIdTree for ResolverTree<'_, '_> { #[inline] fn opt_parent(self, id: DefId) -> Option { + let ResolverTree(definitions, crate_loader) = self; match id.as_local() { - Some(id) => self.definitions.def_key(id).parent, - None => self.cstore().def_key(id).parent, + Some(id) => definitions.def_key(id).parent, + None => crate_loader.cstore().def_key(id).parent, } .map(|index| DefId { index, ..id }) } } +impl<'a, 'b> DefIdTree for &'a Resolver<'b> { + #[inline] + fn opt_parent(self, id: DefId) -> Option { + ResolverTree(&self.definitions, &self.crate_loader).opt_parent(id) + } +} + impl Resolver<'_> { fn opt_local_def_id(&self, node: NodeId) -> Option { self.node_id_to_def_id.get(&node).copied() diff --git a/src/test/ui/privacy/effective_visibilities.rs b/src/test/ui/privacy/effective_visibilities.rs index c1f9ee8dfdf73..187bd75933048 100644 --- a/src/test/ui/privacy/effective_visibilities.rs +++ b/src/test/ui/privacy/effective_visibilities.rs @@ -6,7 +6,7 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub pub mod inner1 { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub #[rustc_effective_visibility] - extern "C" {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + extern "C" {} //~ ERROR not in the table #[rustc_effective_visibility] pub trait PubTrait { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub diff --git a/src/test/ui/privacy/effective_visibilities.stderr b/src/test/ui/privacy/effective_visibilities.stderr index 5a8f7db38fc8a..10ed14aa15035 100644 --- a/src/test/ui/privacy/effective_visibilities.stderr +++ b/src/test/ui/privacy/effective_visibilities.stderr @@ -10,7 +10,7 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl LL | pub mod inner1 { | ^^^^^^^^^^^^^^ -error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub +error: not in the table --> $DIR/effective_visibilities.rs:9:9 | LL | extern "C" {} diff --git a/src/test/ui/privacy/effective_visibilities_glob.rs b/src/test/ui/privacy/effective_visibilities_glob.rs new file mode 100644 index 0000000000000..eb9dcd6cd1fa4 --- /dev/null +++ b/src/test/ui/privacy/effective_visibilities_glob.rs @@ -0,0 +1,21 @@ +// Effective visibility tracking for imports is fine-grained, so `S2` is not fully exported +// even if its parent import (`m::*`) is fully exported as a `use` item. + +#![feature(rustc_attrs)] + +mod m { + #[rustc_effective_visibility] + pub struct S1 {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + #[rustc_effective_visibility] + pub struct S2 {} //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) +} + +mod glob { + #[rustc_effective_visibility] + pub use crate::m::*; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub +} + +#[rustc_effective_visibility] +pub use glob::S1; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + +fn main() {} diff --git a/src/test/ui/privacy/effective_visibilities_glob.stderr b/src/test/ui/privacy/effective_visibilities_glob.stderr new file mode 100644 index 0000000000000..0496cd5df8db0 --- /dev/null +++ b/src/test/ui/privacy/effective_visibilities_glob.stderr @@ -0,0 +1,26 @@ +error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/effective_visibilities_glob.rs:8:5 + | +LL | pub struct S1 {} + | ^^^^^^^^^^^^^ + +error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) + --> $DIR/effective_visibilities_glob.rs:10:5 + | +LL | pub struct S2 {} + | ^^^^^^^^^^^^^ + +error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/effective_visibilities_glob.rs:15:13 + | +LL | pub use crate::m::*; + | ^^^^^^^^ + +error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/effective_visibilities_glob.rs:19:9 + | +LL | pub use glob::S1; + | ^^^^^^^^ + +error: aborting due to 4 previous errors + From 24dcc0692b5530b9879eac0ca3665fac2f1365df Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 4 Nov 2022 16:28:03 +0400 Subject: [PATCH 225/482] privacy: Print effective visibilities of constructors --- compiler/rustc_privacy/src/lib.rs | 8 ++++ src/test/ui/privacy/effective_visibilities.rs | 2 + .../ui/privacy/effective_visibilities.stderr | 44 ++++++++++++------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 865d6306bd349..bda3b55cfc33f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -959,6 +959,10 @@ impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> { for variant in def.variants.iter() { let variant_id = self.tcx.hir().local_def_id(variant.id); self.effective_visibility_diagnostic(variant_id); + if let Some(ctor_hir_id) = variant.data.ctor_hir_id() { + let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id); + self.effective_visibility_diagnostic(ctor_def_id); + } for field in variant.data.fields() { let def_id = self.tcx.hir().local_def_id(field.hir_id); self.effective_visibility_diagnostic(def_id); @@ -966,6 +970,10 @@ impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> { } } hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { + if let Some(ctor_hir_id) = def.ctor_hir_id() { + let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id); + self.effective_visibility_diagnostic(ctor_def_id); + } for field in def.fields() { let def_id = self.tcx.hir().local_def_id(field.hir_id); self.effective_visibility_diagnostic(def_id); diff --git a/src/test/ui/privacy/effective_visibilities.rs b/src/test/ui/privacy/effective_visibilities.rs index 187bd75933048..4479b0d8f61ba 100644 --- a/src/test/ui/privacy/effective_visibilities.rs +++ b/src/test/ui/privacy/effective_visibilities.rs @@ -18,6 +18,7 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub #[rustc_effective_visibility] struct PrivStruct; //~ ERROR not in the table + //~| ERROR not in the table #[rustc_effective_visibility] pub union PubUnion { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub @@ -31,6 +32,7 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub pub enum Enum { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub #[rustc_effective_visibility] A( //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + //~| ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub #[rustc_effective_visibility] PubUnion, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub ), diff --git a/src/test/ui/privacy/effective_visibilities.stderr b/src/test/ui/privacy/effective_visibilities.stderr index 10ed14aa15035..019aaf8086a6a 100644 --- a/src/test/ui/privacy/effective_visibilities.stderr +++ b/src/test/ui/privacy/effective_visibilities.stderr @@ -28,92 +28,104 @@ error: not in the table LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ +error: not in the table + --> $DIR/effective_visibilities.rs:20:9 + | +LL | struct PrivStruct; + | ^^^^^^^^^^^^^^^^^ + error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:23:9 + --> $DIR/effective_visibilities.rs:24:9 | LL | pub union PubUnion { | ^^^^^^^^^^^^^^^^^^ error: not in the table - --> $DIR/effective_visibilities.rs:25:13 + --> $DIR/effective_visibilities.rs:26:13 | LL | a: u8, | ^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:27:13 + --> $DIR/effective_visibilities.rs:28:13 | LL | pub b: u8, | ^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:31:9 + --> $DIR/effective_visibilities.rs:32:9 | LL | pub enum Enum { | ^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:33:13 + --> $DIR/effective_visibilities.rs:34:13 + | +LL | A( + | ^ + +error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/effective_visibilities.rs:34:13 | LL | A( | ^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:35:17 + --> $DIR/effective_visibilities.rs:37:17 | LL | PubUnion, | ^^^^^^^^ error: not in the table - --> $DIR/effective_visibilities.rs:41:5 + --> $DIR/effective_visibilities.rs:43:5 | LL | macro_rules! none_macro { | ^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:47:5 + --> $DIR/effective_visibilities.rs:49:5 | LL | macro_rules! public_macro { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:52:5 + --> $DIR/effective_visibilities.rs:54:5 | LL | pub struct ReachableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:54:9 + --> $DIR/effective_visibilities.rs:56:9 | LL | pub a: u8, | ^^^^^^^^^ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:59:9 + --> $DIR/effective_visibilities.rs:61:9 | LL | pub use outer::inner1; | ^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:65:5 + --> $DIR/effective_visibilities.rs:67:5 | LL | pub type HalfPublicImport = u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) - --> $DIR/effective_visibilities.rs:68:5 + --> $DIR/effective_visibilities.rs:70:5 | LL | pub(crate) const HalfPublicImport: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:72:9 + --> $DIR/effective_visibilities.rs:74:9 | LL | pub use half_public_import::HalfPublicImport; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:72:9 + --> $DIR/effective_visibilities.rs:74:9 | LL | pub use half_public_import::HalfPublicImport; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -130,5 +142,5 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl LL | type B; | ^^^^^^ -error: aborting due to 22 previous errors +error: aborting due to 24 previous errors From 8f6545c7404709294fd704ff4f0ee88d7bc0969a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 4 Nov 2022 17:44:40 +0400 Subject: [PATCH 226/482] privacy: Check effective visibility invariants --- compiler/rustc_middle/src/middle/privacy.rs | 51 ++++++++++++++++++++- compiler/rustc_privacy/src/lib.rs | 2 + 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 3d7a379c56cd1..11fbefefcc9ef 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,9 +1,10 @@ //! A pass that checks to make sure private fields and methods aren't used //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use crate::ty::{DefIdTree, Visibility}; +use crate::ty::{DefIdTree, TyCtxt, Visibility}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hir::def::DefKind; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_span::def_id::LocalDefId; @@ -133,6 +134,54 @@ impl EffectiveVisibilities { } self.map.insert(id, effective_vis); } + + pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) { + if !cfg!(debug_assertions) { + return; + } + for (&def_id, ev) in &self.map { + // More direct visibility levels can never go farther than less direct ones, + // neither of effective visibilities can go farther than nominal visibility, + // and all effective visibilities are larger or equal than private visibility. + let private_vis = Visibility::Restricted(tcx.parent_module_from_def_id(def_id)); + let span = tcx.def_span(def_id.to_def_id()); + if !ev.direct.is_at_least(private_vis, tcx) { + span_bug!(span, "private {:?} > direct {:?}", private_vis, ev.direct); + } + if !ev.reexported.is_at_least(ev.direct, tcx) { + span_bug!(span, "direct {:?} > reexported {:?}", ev.direct, ev.reexported); + } + if !ev.reachable.is_at_least(ev.reexported, tcx) { + span_bug!(span, "reexported {:?} > reachable {:?}", ev.reexported, ev.reachable); + } + if !ev.reachable_through_impl_trait.is_at_least(ev.reachable, tcx) { + span_bug!( + span, + "reachable {:?} > reachable_through_impl_trait {:?}", + ev.reachable, + ev.reachable_through_impl_trait + ); + } + let nominal_vis = tcx.visibility(def_id); + let def_kind = tcx.opt_def_kind(def_id); + // FIXME: `rustc_privacy` is not yet updated for the new logic and can set + // effective visibilities that are larger than the nominal one. + if !nominal_vis.is_at_least(ev.reachable_through_impl_trait, tcx) && early { + span_bug!( + span, + "{:?}: reachable_through_impl_trait {:?} > nominal {:?}", + def_id, + ev.reachable_through_impl_trait, + nominal_vis + ); + } + // Fully private items are never put into the table, this is important for performance. + // FIXME: Fully private `mod` items are currently put into the table. + if ev.reachable_through_impl_trait == private_vis && def_kind != Some(DefKind::Mod) { + span_bug!(span, "fully private item in the table {:?}: {:?}", def_id, ev.direct); + } + } + } } impl EffectiveVisibilities { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index bda3b55cfc33f..e17f85c1aae0f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -2139,6 +2139,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { changed: false, }; + visitor.effective_visibilities.check_invariants(tcx, true); loop { tcx.hir().walk_toplevel_module(&mut visitor); if visitor.changed { @@ -2147,6 +2148,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { break; } } + visitor.effective_visibilities.check_invariants(tcx, false); let mut check_visitor = TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; From 0df57ba0746f26efc324e177574724d5992a5632 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 5 Nov 2022 16:54:45 +0400 Subject: [PATCH 227/482] resolve: Fill effective visibilities for import def ids in a separate pass This should result in less update calls than doing it repeatedly during the fix point iteration. --- compiler/rustc_middle/src/middle/privacy.rs | 30 ++++++++- .../src/effective_visibilities.rs | 65 ++++++++++--------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 11fbefefcc9ef..3a91522d36229 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -113,8 +113,30 @@ impl EffectiveVisibilities { }) } - pub fn iter(&self) -> impl Iterator { - self.map.iter() + // FIXME: Share code with `fn update`. + pub fn update_eff_vis( + &mut self, + def_id: LocalDefId, + eff_vis: &EffectiveVisibility, + tree: impl DefIdTree, + ) { + use std::collections::hash_map::Entry; + match self.map.entry(def_id) { + Entry::Occupied(mut occupied) => { + let old_eff_vis = occupied.get_mut(); + for l in Level::all_levels() { + let vis_at_level = eff_vis.at_level(l); + let old_vis_at_level = old_eff_vis.at_level_mut(l); + if vis_at_level != old_vis_at_level + && vis_at_level.is_at_least(*old_vis_at_level, tree) + { + *old_vis_at_level = *vis_at_level + } + } + old_eff_vis + } + Entry::Vacant(vacant) => vacant.insert(*eff_vis), + }; } pub fn set_public_at_level( @@ -185,6 +207,10 @@ impl EffectiveVisibilities { } impl EffectiveVisibilities { + pub fn iter(&self) -> impl Iterator { + self.map.iter() + } + pub fn effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { self.map.get(&id) } diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 56dde6f8ca74e..fa6d34be0cc37 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -55,6 +55,38 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { visit::walk_crate(&mut visitor, krate); } + // Update visibilities for import def ids. These are not used during the + // `EffectiveVisibilitiesVisitor` pass, because we have more detailed binding-based + // information, but are used by later passes. Effective visibility of an import def id + // is the maximum value among visibilities of bindings corresponding to that def id. + for (binding, eff_vis) in visitor.import_effective_visibilities.iter() { + let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; + if let Some(node_id) = import.id() { + let mut update = |node_id| { + r.effective_visibilities.update_eff_vis( + r.local_def_id(node_id), + eff_vis, + ResolverTree(&r.definitions, &r.crate_loader), + ) + }; + update(node_id); + if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind { + // In theory all the single import IDs have individual visibilities and + // effective visibilities, but in practice these IDs go straigth to HIR + // where all their few uses assume that their (effective) visibility + // applies to the whole syntactic `use` item. So they all get the same + // value which is the maximum of all bindings. Maybe HIR for imports + // shouldn't use three IDs at all. + if id1 != ast::DUMMY_NODE_ID { + update(id1); + } + if id2 != ast::DUMMY_NODE_ID { + update(id2); + } + } + } + } + info!("resolve::effective_visibilities: {:#?}", r.effective_visibilities); } @@ -75,41 +107,10 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { // sets the rest of the `use` chain to `Level::Reexported` until // we hit the actual exported item. let mut parent_id = ParentId::Def(module_id); - while let NameBindingKind::Import { binding: nested_binding, import, .. } = - binding.kind - { + while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { let binding_id = ImportId::new_unchecked(binding); self.update_import(binding_id, parent_id); - // Update visibilities for import ids. These are not used during this pass, - // because we have more detailed binding-based information, but are used by - // later passes. Effective visibility of an import def id is the maximum value - // among visibilities of bindings corresponding to that def id. - if let Some(node_id) = import.id() { - let mut update = |node_id| { - self.update_def( - self.r.local_def_id(node_id), - binding.vis.expect_local(), - parent_id, - ) - }; - update(node_id); - if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind { - // In theory all the single import IDs have individual visibilities and - // effective visibilities, but in practice these IDs go straigth to HIR - // where all their few uses assume that their (effective) visibility - // applies to the whole syntactic `use` item. So they all get the same - // value which is the maximum of all bindings. Maybe HIR for imports - // shouldn't use three IDs at all. - if id1 != ast::DUMMY_NODE_ID { - update(id1); - } - if id2 != ast::DUMMY_NODE_ID { - update(id2); - } - } - } - parent_id = ParentId::Import(binding_id); binding = nested_binding; } From 1daf8b66bc6d71e2f519bf0ff7471366827090e7 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 19 Oct 2022 17:17:19 +0200 Subject: [PATCH 228/482] selection failure: recompute applicable impls --- compiler/rustc_middle/src/traits/mod.rs | 3 -- compiler/rustc_middle/src/ty/mod.rs | 8 +-- .../src/traits/chalk_fulfill.rs | 15 +++++- .../src/traits/engine.rs | 17 +++--- .../src/traits/error_reporting/ambiguity.rs | 52 +++++++++++++++++++ .../src/traits/error_reporting/mod.rs | 38 +++++++------- .../src/traits/select/candidate_assembly.rs | 12 +---- .../src/traits/select/mod.rs | 4 -- src/test/ui/error-codes/E0282.rs | 3 +- src/test/ui/error-codes/E0401.rs | 4 +- src/test/ui/error-codes/E0401.stderr | 27 ++++++++-- .../impl-trait/cross-return-site-inference.rs | 9 ++-- .../cross-return-site-inference.stderr | 4 +- src/test/ui/inference/cannot-infer-async.rs | 3 +- src/test/ui/inference/cannot-infer-closure.rs | 3 +- src/test/ui/inference/issue-71732.rs | 3 +- src/test/ui/inference/issue-72616.rs | 3 +- src/test/ui/inference/issue-72616.stderr | 18 ++++++- .../ui/inference/question-mark-type-infer.rs | 3 +- src/test/ui/issues/issue-71584.rs | 3 +- src/test/ui/traits/issue-77982.stderr | 7 +-- 21 files changed, 166 insertions(+), 73 deletions(-) create mode 100644 compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a29f0722ff705..05382bd887cd9 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -576,9 +576,6 @@ pub enum SelectionError<'tcx> { /// Signaling that an error has already been emitted, to avoid /// multiple errors being shown. ErrorReporting, - /// Multiple applicable `impl`s where found. The `DefId`s correspond to - /// all the `impl`s' Items. - Ambiguous(Vec), } /// When performing resolution, it is typically the case that there diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 27090c62d21ed..b509ae6dd3b85 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2550,11 +2550,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` /// with the name of the crate containing the impl. - pub fn span_of_impl(self, impl_did: DefId) -> Result { - if let Some(impl_did) = impl_did.as_local() { - Ok(self.def_span(impl_did)) + pub fn span_of_impl(self, impl_def_id: DefId) -> Result { + if let Some(impl_def_id) = impl_def_id.as_local() { + Ok(self.def_span(impl_def_id)) } else { - Err(self.crate_name(impl_did.krate)) + Err(self.crate_name(impl_def_id.krate)) } } diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index 81e1d64493e14..d32a990f182dc 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -14,6 +14,8 @@ pub struct FulfillmentContext<'tcx> { obligations: FxIndexSet>, relationships: FxHashMap, + + usable_in_snapshot: bool, } impl FulfillmentContext<'_> { @@ -21,8 +23,13 @@ impl FulfillmentContext<'_> { FulfillmentContext { obligations: FxIndexSet::default(), relationships: FxHashMap::default(), + usable_in_snapshot: false, } } + + pub(crate) fn new_in_snapshot() -> Self { + FulfillmentContext { usable_in_snapshot: true, ..Self::new() } + } } impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { @@ -41,7 +48,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { infcx: &InferCtxt<'tcx>, obligation: PredicateObligation<'tcx>, ) { - assert!(!infcx.is_in_snapshot()); + if !self.usable_in_snapshot { + assert!(!infcx.is_in_snapshot()); + } let obligation = infcx.resolve_vars_if_possible(obligation); super::relationships::update(self, infcx, &obligation); @@ -72,7 +81,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { } fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { - assert!(!infcx.is_in_snapshot()); + if !self.usable_in_snapshot { + assert!(!infcx.is_in_snapshot()); + } let mut errors = Vec::new(); let mut next_round = FxIndexSet::default(); diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 21516c93efb53..0eafc49816d49 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -38,7 +38,7 @@ impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box { if tcx.sess.opts.unstable_opts.chalk { - Box::new(ChalkFulfillmentContext::new()) + Box::new(ChalkFulfillmentContext::new_in_snapshot()) } else { Box::new(FulfillmentContext::new_in_snapshot()) } @@ -119,13 +119,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { expected: T, actual: T, ) -> Result<(), TypeError<'tcx>> { - match self.infcx.at(cause, param_env).eq(expected, actual) { - Ok(InferOk { obligations, value: () }) => { - self.register_obligations(obligations); - Ok(()) - } - Err(e) => Err(e), - } + self.infcx + .at(cause, param_env) + .eq(expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } pub fn sup>( @@ -144,6 +141,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { } } + pub fn select_where_possible(&self) -> Vec> { + self.engine.borrow_mut().select_where_possible(self.infcx) + } + pub fn select_all_or_error(&self) -> Vec> { self.engine.borrow_mut().select_all_or_error(self.infcx) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs new file mode 100644 index 0000000000000..58da54afb75b9 --- /dev/null +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -0,0 +1,52 @@ +use rustc_hir::def_id::DefId; +use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::{Obligation, ObligationCause, TraitObligation}; +use rustc_span::DUMMY_SP; + +use crate::traits::ObligationCtxt; + +pub fn recompute_applicable_impls<'tcx>( + infcx: &InferCtxt<'tcx>, + obligation: &TraitObligation<'tcx>, +) -> Vec { + let tcx = infcx.tcx; + let param_env = obligation.param_env; + let dummy_cause = ObligationCause::dummy(); + let impl_may_apply = |impl_def_id| { + let ocx = ObligationCtxt::new_in_snapshot(infcx); + let placeholder_obligation = + infcx.replace_bound_vars_with_placeholders(obligation.predicate); + let obligation_trait_ref = + ocx.normalize(dummy_cause.clone(), param_env, placeholder_obligation.trait_ref); + + let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let impl_trait_ref = tcx.bound_impl_trait_ref(impl_def_id).unwrap().subst(tcx, impl_substs); + let impl_trait_ref = ocx.normalize(ObligationCause::dummy(), param_env, impl_trait_ref); + + if let Err(_) = ocx.eq(&dummy_cause, param_env, obligation_trait_ref, impl_trait_ref) { + return false; + } + + let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs); + ocx.register_obligations( + impl_predicates + .predicates + .iter() + .map(|&predicate| Obligation::new(dummy_cause.clone(), param_env, predicate)), + ); + + ocx.select_where_possible().is_empty() + }; + + let mut impls = Vec::new(); + tcx.for_each_relevant_impl( + obligation.predicate.def_id(), + obligation.predicate.skip_binder().trait_ref.self_ty(), + |impl_def_id| { + if infcx.probe(move |_snapshot| impl_may_apply(impl_def_id)) { + impls.push(impl_def_id) + } + }, + ); + impls +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c7dee4a18ac5d..bcb00796cbaba 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1,3 +1,4 @@ +mod ambiguity; pub mod on_unimplemented; pub mod suggestions; @@ -535,15 +536,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut span = obligation.cause.span; let mut err = match *error { - SelectionError::Ambiguous(ref impls) => { - let mut err = self.tcx.sess.struct_span_err( - obligation.cause.span, - &format!("multiple applicable `impl`s for `{}`", obligation.predicate), - ); - self.annotate_source_of_ambiguity(&mut err, impls, obligation.predicate); - err.emit(); - return; - } SelectionError::Unimplemented => { // If this obligation was generated as a result of well-formedness checking, see if we // can get a better error message by performing HIR-based well-formedness checking. @@ -2144,8 +2136,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { crate::traits::TraitQueryMode::Standard, ); match selcx.select_from_obligation(&obligation) { - Err(SelectionError::Ambiguous(impls)) if impls.len() > 1 => { - self.annotate_source_of_ambiguity(&mut err, &impls, predicate); + Ok(None) => { + let impls = ambiguity::recompute_applicable_impls(self.infcx, &obligation); + let has_non_region_infer = + trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer()); + // It doesn't make sense to talk about applicable impls if there are more + // than a handful of them. + if impls.len() > 1 && impls.len() < 5 && has_non_region_infer { + self.annotate_source_of_ambiguity(&mut err, &impls, predicate); + } else { + if self.is_tainted_by_errors() { + err.cancel(); + return; + } + err.note(&format!("cannot satisfy `{}`", predicate)); + } } _ => { if self.is_tainted_by_errors() { @@ -2441,7 +2446,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } } - let msg = format!("multiple `impl`s satisfying `{}` found", predicate); let mut crate_names: Vec<_> = crates.iter().map(|n| format!("`{}`", n)).collect(); crate_names.sort(); crate_names.dedup(); @@ -2462,13 +2466,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.downgrade_to_delayed_bug(); return; } - let post = if post.len() > 4 { - format!( - ":\n{}\nand {} more", - post.iter().map(|p| format!("- {}", p)).take(4).collect::>().join("\n"), - post.len() - 4, - ) - } else if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) { + + let msg = format!("multiple `impl`s satisfying `{}` found", predicate); + let post = if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) { format!(":\n{}", post.iter().map(|p| format!("- {}", p)).collect::>().join("\n"),) } else if post.len() == 1 { format!(": `{}`", post[0]) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 4c5bc333961dc..3671a0d87df57 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -20,7 +20,7 @@ use crate::traits; use crate::traits::coherence::Conflict; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{util, SelectionResult}; -use crate::traits::{Ambiguous, ErrorReporting, Overflow, Unimplemented}; +use crate::traits::{ErrorReporting, Overflow, Unimplemented}; use super::BuiltinImplConditions; use super::IntercrateAmbiguityCause; @@ -200,15 +200,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // and report ambiguity. if i > 1 { debug!("multiple matches, ambig"); - return Err(Ambiguous( - candidates - .into_iter() - .filter_map(|c| match c.candidate { - SelectionCandidate::ImplCandidate(def_id) => Some(def_id), - _ => None, - }) - .collect(), - )); + return Ok(None); } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 84be1ced520fe..2954a2c163f40 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -294,9 +294,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { assert!(self.query_mode == TraitQueryMode::Canonical); return Err(SelectionError::Overflow(OverflowError::Canonical)); } - Err(SelectionError::Ambiguous(_)) => { - return Ok(None); - } Err(e) => { return Err(e); } @@ -931,7 +928,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.candidate_from_obligation(stack) { Ok(Some(c)) => self.evaluate_candidate(stack, &c), - Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical), Err(ErrorReporting) => Err(OverflowError::ErrorReporting), diff --git a/src/test/ui/error-codes/E0282.rs b/src/test/ui/error-codes/E0282.rs index 9bd16abb7bb83..f1f93b3aed615 100644 --- a/src/test/ui/error-codes/E0282.rs +++ b/src/test/ui/error-codes/E0282.rs @@ -1,3 +1,4 @@ fn main() { - let x = "hello".chars().rev().collect(); //~ ERROR E0282 + let x = "hello".chars().rev().collect(); + //~^ ERROR E0282 } diff --git a/src/test/ui/error-codes/E0401.rs b/src/test/ui/error-codes/E0401.rs index c30e5f4718871..8f8d6b87ef209 100644 --- a/src/test/ui/error-codes/E0401.rs +++ b/src/test/ui/error-codes/E0401.rs @@ -8,7 +8,9 @@ fn foo(x: T) { W: Fn()> (y: T) { //~ ERROR E0401 } - bfnr(x); //~ ERROR type annotations needed + bfnr(x); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index b0e2ef5b6f7e3..9687eca61fab0 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -21,7 +21,7 @@ LL | (y: T) { | ^ use of generic parameter from outer function error[E0401]: can't use generic parameters from outer function - --> $DIR/E0401.rs:22:25 + --> $DIR/E0401.rs:24:25 | LL | impl Iterator for A { | ---- `Self` type implicitly declared here, by this `impl` @@ -43,7 +43,28 @@ help: consider specifying the generic arguments LL | bfnr::(x); | +++++++++++ -error: aborting due to 4 previous errors +error[E0283]: type annotations needed + --> $DIR/E0401.rs:11:5 + | +LL | bfnr(x); + | ^^^^ cannot infer type of the type parameter `W` declared on the function `bfnr` + | + = note: multiple `impl`s satisfying `_: Fn<()>` found in the following crates: `alloc`, `core`: + - impl Fn for &F + where A: Tuple, F: Fn, F: ?Sized; + - impl Fn for Box + where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; +note: required by a bound in `bfnr` + --> $DIR/E0401.rs:4:30 + | +LL | fn bfnr, W: Fn()>(y: T) { + | ^^^^ required by this bound in `bfnr` +help: consider specifying the type arguments in the function call + | +LL | bfnr::(x); + | +++++++++++ + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0282, E0401. +Some errors have detailed explanations: E0282, E0283, E0401. For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs index d881af9ed8fe1..00aed2ad95a28 100644 --- a/src/test/ui/impl-trait/cross-return-site-inference.rs +++ b/src/test/ui/impl-trait/cross-return-site-inference.rs @@ -30,16 +30,19 @@ fn baa(b: bool) -> impl std::fmt::Debug { fn muh() -> Result<(), impl std::fmt::Debug> { Err("whoops")?; - Ok(()) //~ ERROR type annotations needed + Ok(()) + //~^ ERROR type annotations needed } fn muh2() -> Result<(), impl std::fmt::Debug> { - return Err(From::from("foo")); //~ ERROR type annotations needed + return Err(From::from("foo")); + //~^ ERROR type annotations needed Ok(()) } fn muh3() -> Result<(), impl std::fmt::Debug> { - Err(From::from("foo")) //~ ERROR type annotations needed + Err(From::from("foo")) + //~^ ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/impl-trait/cross-return-site-inference.stderr b/src/test/ui/impl-trait/cross-return-site-inference.stderr index 1ff777e65037c..766614e9e50ff 100644 --- a/src/test/ui/impl-trait/cross-return-site-inference.stderr +++ b/src/test/ui/impl-trait/cross-return-site-inference.stderr @@ -10,7 +10,7 @@ LL | Ok::<(), E>(()) | +++++++++ error[E0282]: type annotations needed - --> $DIR/cross-return-site-inference.rs:37:12 + --> $DIR/cross-return-site-inference.rs:38:12 | LL | return Err(From::from("foo")); | ^^^ cannot infer type of the type parameter `E` declared on the enum `Result` @@ -21,7 +21,7 @@ LL | return Err::<(), E>(From::from("foo")); | +++++++++ error[E0282]: type annotations needed - --> $DIR/cross-return-site-inference.rs:42:5 + --> $DIR/cross-return-site-inference.rs:44:5 | LL | Err(From::from("foo")) | ^^^ cannot infer type of the type parameter `E` declared on the enum `Result` diff --git a/src/test/ui/inference/cannot-infer-async.rs b/src/test/ui/inference/cannot-infer-async.rs index e7fabd0ffbc8b..b5152d04f6959 100644 --- a/src/test/ui/inference/cannot-infer-async.rs +++ b/src/test/ui/inference/cannot-infer-async.rs @@ -10,6 +10,7 @@ fn main() { let fut = async { make_unit()?; - Ok(()) //~ ERROR type annotations needed + Ok(()) + //~^ ERROR type annotations needed }; } diff --git a/src/test/ui/inference/cannot-infer-closure.rs b/src/test/ui/inference/cannot-infer-closure.rs index 1c350b18f5a6f..bd5d10b417342 100644 --- a/src/test/ui/inference/cannot-infer-closure.rs +++ b/src/test/ui/inference/cannot-infer-closure.rs @@ -1,6 +1,7 @@ fn main() { let x = |a: (), b: ()| { Err(a)?; - Ok(b) //~ ERROR type annotations needed + Ok(b) + //~^ ERROR type annotations needed }; } diff --git a/src/test/ui/inference/issue-71732.rs b/src/test/ui/inference/issue-71732.rs index 30063a0957c74..8a9d2b235f0e4 100644 --- a/src/test/ui/inference/issue-71732.rs +++ b/src/test/ui/inference/issue-71732.rs @@ -15,7 +15,8 @@ use std::collections::hash_map::HashMap; fn foo(parameters: &HashMap) -> bool { parameters - .get(&"key".into()) //~ ERROR: type annotations needed + .get(&"key".into()) + //~^ ERROR type annotations needed .and_then(|found: &String| Some(false)) .unwrap_or(false) } diff --git a/src/test/ui/inference/issue-72616.rs b/src/test/ui/inference/issue-72616.rs index 5e5a3babfe020..7b0f5936d84ec 100644 --- a/src/test/ui/inference/issue-72616.rs +++ b/src/test/ui/inference/issue-72616.rs @@ -18,7 +18,8 @@ pub fn main() { } { if String::from("a") == "a".try_into().unwrap() {} - //~^ ERROR: type annotations needed + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } { let _: String = match "_".try_into() { diff --git a/src/test/ui/inference/issue-72616.stderr b/src/test/ui/inference/issue-72616.stderr index a71ce9a8ef27a..da1a7ccdee15e 100644 --- a/src/test/ui/inference/issue-72616.stderr +++ b/src/test/ui/inference/issue-72616.stderr @@ -16,6 +16,22 @@ help: try using a fully qualified path to specify the expected types LL | if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} | +++++++++++++++++++++++++++++++ ~ -error: aborting due to previous error +error[E0283]: type annotations needed + --> $DIR/issue-72616.rs:20:37 + | +LL | if String::from("a") == "a".try_into().unwrap() {} + | ^^^^^^^^ + | + = note: multiple `impl`s satisfying `_: TryFrom<&str>` found in the following crates: `core`, `std`: + - impl<> TryFrom<&str> for std::sys_common::net::LookupHost; + - impl TryFrom for T + where U: Into; + = note: required for `&str` to implement `TryInto<_>` +help: try using a fully qualified path to specify the expected types + | +LL | if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} + | +++++++++++++++++++++++++++++++ ~ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/inference/question-mark-type-infer.rs b/src/test/ui/inference/question-mark-type-infer.rs index 64333a29313b3..10560f85ed480 100644 --- a/src/test/ui/inference/question-mark-type-infer.rs +++ b/src/test/ui/inference/question-mark-type-infer.rs @@ -7,7 +7,8 @@ fn f(x: &i32) -> Result { fn g() -> Result, ()> { let l = [1, 2, 3, 4]; - l.iter().map(f).collect()? //~ ERROR type annotations needed + l.iter().map(f).collect()? + //~^ ERROR type annotations needed } fn main() { diff --git a/src/test/ui/issues/issue-71584.rs b/src/test/ui/issues/issue-71584.rs index c96cd598f0ce0..7bf3ed60ec104 100644 --- a/src/test/ui/issues/issue-71584.rs +++ b/src/test/ui/issues/issue-71584.rs @@ -1,5 +1,6 @@ fn main() { let n: u32 = 1; let mut d: u64 = 2; - d = d % n.into(); //~ ERROR type annotations needed + d = d % n.into(); + //~^ ERROR type annotations needed } diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index e210f11b3e0c1..b6a04585583c9 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -46,12 +46,7 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | | | required by a bound introduced by this call | - = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for u32; - and 3 more + = note: cannot satisfy `u32: From<_>` help: try using a fully qualified path to specify the expected types | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); From 680cbbad5442aae297985661edef156b9a6eff0f Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 31 Oct 2022 10:27:51 +0100 Subject: [PATCH 229/482] delay errors as bug --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index bcb00796cbaba..0f5d05afcf809 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2146,7 +2146,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.annotate_source_of_ambiguity(&mut err, &impls, predicate); } else { if self.is_tainted_by_errors() { - err.cancel(); + err.delay_as_bug(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); @@ -2154,7 +2154,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } _ => { if self.is_tainted_by_errors() { - err.cancel(); + err.delay_as_bug(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); From d7fdaeea77f40fce1560ceb283e7a5747c4198bb Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 8 Nov 2022 14:16:49 +0100 Subject: [PATCH 230/482] ignore wasm in test --- src/test/ui/inference/issue-72616.rs | 2 ++ src/test/ui/inference/issue-72616.stderr | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/ui/inference/issue-72616.rs b/src/test/ui/inference/issue-72616.rs index 7b0f5936d84ec..69ade1a7515cb 100644 --- a/src/test/ui/inference/issue-72616.rs +++ b/src/test/ui/inference/issue-72616.rs @@ -1,3 +1,5 @@ +// ignore-wasm32 FIXME: ignoring wasm as it suggests slightly different impls + // Regression test for #72616, it used to emit incorrect diagnostics, like: // error[E0283]: type annotations needed for `String` // --> src/main.rs:8:30 diff --git a/src/test/ui/inference/issue-72616.stderr b/src/test/ui/inference/issue-72616.stderr index da1a7ccdee15e..6ee0626cab857 100644 --- a/src/test/ui/inference/issue-72616.stderr +++ b/src/test/ui/inference/issue-72616.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/issue-72616.rs:20:37 + --> $DIR/issue-72616.rs:22:37 | LL | if String::from("a") == "a".try_into().unwrap() {} | -- ^^^^^^^^ @@ -17,7 +17,7 @@ LL | if String::from("a") == <&str as TryInto>::try_into("a").unwrap( | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed - --> $DIR/issue-72616.rs:20:37 + --> $DIR/issue-72616.rs:22:37 | LL | if String::from("a") == "a".try_into().unwrap() {} | ^^^^^^^^ From 9c0fe9d945cc53781312c3c5aee3cf5a2bafcac7 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 3 Nov 2022 14:15:17 +0800 Subject: [PATCH 231/482] add 'ty_error_with_guaranteed' and 'const_error_with_guaranteed' --- .../src/region_infer/opaque_types.rs | 4 +-- .../src/type_check/free_region_relations.rs | 5 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +-- .../rustc_errors/src/diagnostic_builder.rs | 4 +-- .../rustc_hir_analysis/src/astconv/mod.rs | 26 +++++++++++-------- .../src/check/compare_method.rs | 4 +-- compiler/rustc_hir_analysis/src/collect.rs | 3 +-- .../rustc_hir_analysis/src/collect/type_of.rs | 4 +-- compiler/rustc_hir_typeck/src/coercion.rs | 4 +-- compiler/rustc_hir_typeck/src/expr.rs | 19 +++++++------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 ++-- compiler/rustc_hir_typeck/src/op.rs | 4 +-- compiler/rustc_hir_typeck/src/pat.rs | 6 ++--- compiler/rustc_hir_typeck/src/place_op.rs | 7 +++-- compiler/rustc_middle/src/ty/context.rs | 16 ++++++++++++ 15 files changed, 68 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 103c7ed8ef701..dd222485daf2c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -299,8 +299,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { if errors.is_empty() { definition_ty } else { - infcx.err_ctxt().report_fulfillment_errors(&errors, None); - self.tcx.ty_error() + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); + self.tcx.ty_error_with_guaranteed(reported) } } } diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 02909592637d8..14cfc3613bf0c 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) .unwrap_or_else(|_| { - self.infcx + let reported = self + .infcx .tcx .sess .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); TypeOpOutput { - output: self.infcx.tcx.ty_error(), + output: self.infcx.tcx.ty_error_with_guaranteed(reported), constraints: None, error_info: None, } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 50af229baaaed..9c1d0bb8b2357 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -233,11 +233,11 @@ pub(crate) fn type_check<'mir, 'tcx>( let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); if hidden_type.has_non_region_infer() { - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), ); - hidden_type.ty = infcx.tcx.ty_error(); + hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported); } (opaque_type_key, (hidden_type, decl.origin)) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index ecf8570e81f71..730061fca9936 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -482,9 +482,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// In the meantime, though, callsites are required to deal with the "bug" /// locally in whichever way makes the most sense. #[track_caller] - pub fn delay_as_bug(&mut self) { + pub fn delay_as_bug(&mut self) -> G { self.downgrade_to_delayed_bug(); - self.emit(); + self.emit() } forward!( diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8b1cc50a3a1f9..2665813478c2c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1201,7 +1201,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; let expected = def_kind.descr(assoc_item_def_id); - tcx.sess + let reported = tcx + .sess .struct_span_err( binding.span, &format!("expected {expected} bound, found {got}"), @@ -1212,11 +1213,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) .emit(); term = match def_kind { - hir::def::DefKind::AssocTy => tcx.ty_error().into(), + hir::def::DefKind::AssocTy => { + tcx.ty_error_with_guaranteed(reported).into() + } hir::def::DefKind::AssocConst => tcx - .const_error( + .const_error_with_guaranteed( tcx.bound_type_of(assoc_item_def_id) .subst(tcx, projection_ty.skip_binder().substs), + reported, ) .into(), _ => unreachable!(), @@ -1334,8 +1338,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .map(|&(trait_ref, _, _)| trait_ref.def_id()) .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) .map(|trait_ref| tcx.def_span(trait_ref)); - tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - return tcx.ty_error(); + let reported = + tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); + return tcx.ty_error_with_guaranteed(reported); } // Check that there are no gross object safety violations; @@ -1345,14 +1350,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let object_safety_violations = astconv_object_safety_violations(tcx, item.trait_ref().def_id()); if !object_safety_violations.is_empty() { - report_object_safety_error( + let reported = report_object_safety_error( tcx, span, item.trait_ref().def_id(), &object_safety_violations, ) .emit(); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported); } } @@ -2112,13 +2117,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "Type" }; - self.report_ambiguous_associated_type( + let reported = self.report_ambiguous_associated_type( span, type_name, &path_str, item_segment.ident.name, ); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported) }; debug!("qpath_to_ty: self_type={:?}", self_ty); @@ -2560,8 +2565,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { err.span_note(impl_.self_ty.span, "not a concrete type"); } - err.emit(); - tcx.ty_error() + tcx.ty_error_with_guaranteed(err.emit()) } else { self.normalize_ty(span, ty) } diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 0e8ac17fb71b1..660c56ee8b011 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -611,11 +611,11 @@ pub fn collect_trait_impl_trait_tys<'tcx>( collected_tys.insert(def_id, ty); } Err(err) => { - tcx.sess.delay_span_bug( + let reported = tcx.sess.delay_span_bug( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, tcx.ty_error()); + collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported)); } } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 25faacadf3d0c..4bca16c3a1cce 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -512,8 +512,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { } _ => {} } - err.emit(); - self.tcx().ty_error() + self.tcx().ty_error_with_guaranteed(err.emit()) } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c29a645eb4a88..2402495c2e4a6 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -698,7 +698,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T } let Some(hidden) = locator.found else { - tcx.sess.emit_err(UnconstrainedOpaqueType { + let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), what: match tcx.hir().get(scope) { @@ -708,7 +708,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T _ => "item", }, }); - return tcx.ty_error(); + return tcx.ty_error_with_guaranteed(reported); }; // Only check against typeck if we didn't already error diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 25306ebf35679..4d8ab2c1c7ad9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1639,9 +1639,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if visitor.ret_exprs.len() > 0 && let Some(expr) = expression { self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs); } - err.emit_unless(unsized_return); + let reported = err.emit_unless(unsized_return); - self.final_ty = Some(fcx.tcx.ty_error()); + self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported)); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 89b5e5161a9c2..e84734f46cb46 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -80,14 +80,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // coercions from ! to `expected`. if ty.is_never() { if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { - self.tcx().sess.delay_span_bug( + let reported = self.tcx().sess.delay_span_bug( expr.span, "expression with never type wound up being adjusted", ); return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] { target.to_owned() } else { - self.tcx().ty_error() + self.tcx().ty_error_with_guaranteed(reported) }; } @@ -396,8 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - err.emit(); - oprnd_t = tcx.ty_error(); + oprnd_t = tcx.ty_error_with_guaranteed(err.emit()); } } hir::UnOp::Not => { @@ -1097,12 +1096,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the assignment expression itself is ill-formed, don't // bother emitting another error - if lhs_ty.references_error() || rhs_ty.references_error() { + let reported = if lhs_ty.references_error() || rhs_ty.references_error() { err.delay_as_bug() } else { - err.emit(); - } - return self.tcx.ty_error(); + err.emit() + }; + return self.tcx.ty_error_with_guaranteed(reported); } let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); @@ -2777,8 +2776,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - err.emit(); - self.tcx.ty_error() + let reported = err.emit(); + self.tcx.ty_error_with_guaranteed(reported) } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 35323137e2d5a..6ed7a93d46332 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1212,9 +1212,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - - return (tcx.ty_error(), res); + let reported = err.emit(); + return (tcx.ty_error_with_guaranteed(reported), res); } } } else { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index c3bcbcc993b7c..38b3dd218a971 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -529,8 +529,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - self.tcx.ty_error() + let reported = err.emit(); + self.tcx.ty_error_with_guaranteed(reported) } }; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ea90da4a6dc35..c248deb892b1d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1278,12 +1278,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let element_tys = tcx.mk_type_list(element_tys_iter); let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) { - err.emit(); + let reported = err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| tcx.ty_error()); + let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported)); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, tcx.ty_error(), def_bm, ti); + self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti); } tcx.mk_tup(element_tys_iter) } else { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index ba8cf6926f30b..952ea14887f7b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -90,8 +90,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } - err.emit(); - Some((self.tcx.ty_error(), self.tcx.ty_error())) + let reported = err.emit(); + Some(( + self.tcx.ty_error_with_guaranteed(reported), + self.tcx.ty_error_with_guaranteed(reported), + )) } /// To type-check `base_expr[index_expr]`, we progressively autoderef diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fc706b890d5fb..4016a93caa869 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1283,6 +1283,12 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` + #[track_caller] + pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> { + self.mk_ty(Error(reported)) + } + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] pub fn ty_error(self) -> Ty<'tcx> { @@ -1297,6 +1303,16 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Error(reported)) } + /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` + #[track_caller] + pub fn const_error_with_guaranteed( + self, + ty: Ty<'tcx>, + reported: ErrorGuaranteed, + ) -> Const<'tcx> { + self.mk_const(ty::ConstS { kind: ty::ConstKind::Error(reported), ty }) + } + /// Like [TyCtxt::ty_error] but for constants. #[track_caller] pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> { From 74a39747067b31f6d54dc14134c6ccc3f9a5c011 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Nov 2022 10:02:54 +0800 Subject: [PATCH 232/482] deprecate unchecked_claim_error_was_emitted in error_reported --- compiler/rustc_middle/src/ty/visit.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index f0e9f990a8115..5e366ef703f25 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -97,7 +97,11 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { } fn error_reported(&self) -> Result<(), ErrorGuaranteed> { if self.references_error() { - Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + if let Some(reported) = ty::tls::with(|tcx| tcx.sess.has_errors()) { + Err(reported) + } else { + bug!("expect tcx.sess.has_errors return true"); + } } else { Ok(()) } From 43bf7320ea9ac0a2230915661a1cee4107938cd9 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Nov 2022 16:10:32 +0800 Subject: [PATCH 233/482] code cleanup with err.emit_unless --- compiler/rustc_hir_typeck/src/expr.rs | 6 +----- compiler/rustc_middle/src/ty/context.rs | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e84734f46cb46..43669489e69bb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1096,11 +1096,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the assignment expression itself is ill-formed, don't // bother emitting another error - let reported = if lhs_ty.references_error() || rhs_ty.references_error() { - err.delay_as_bug() - } else { - err.emit() - }; + let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error()); return self.tcx.ty_error_with_guaranteed(reported); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4016a93caa869..50eece3011280 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1310,7 +1310,7 @@ impl<'tcx> TyCtxt<'tcx> { ty: Ty<'tcx>, reported: ErrorGuaranteed, ) -> Const<'tcx> { - self.mk_const(ty::ConstS { kind: ty::ConstKind::Error(reported), ty }) + self.mk_const(ty::ConstKind::Error(reported), ty) } /// Like [TyCtxt::ty_error] but for constants. From 4c512afe6850d15e8bf535757f10479638c1b966 Mon Sep 17 00:00:00 2001 From: Tanner Davies Date: Sat, 5 Nov 2022 15:07:10 -0600 Subject: [PATCH 234/482] Place config.toml in current working directory if config not found --- src/bootstrap/bin/main.rs | 2 +- src/bootstrap/config.rs | 4 ++-- src/bootstrap/setup.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 9b4861ccd95f4..be69f819c6428 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -35,7 +35,7 @@ fn main() { // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the // changelog warning, not the `x.py setup` message. - let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. }); + let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { println!("warning: you have not made a `config.toml`"); println!( diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 21dc11c48081e..c086d248e5ce1 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -80,7 +80,7 @@ pub struct Config { pub keep_stage_std: Vec, pub src: PathBuf, /// defaults to `config.toml` - pub config: PathBuf, + pub config: Option, pub jobs: Option, pub cmd: Subcommand, pub incremental: bool, @@ -942,7 +942,7 @@ impl Config { } config.changelog_seen = toml.changelog_seen; - config.config = toml_path; + config.config = if toml_path.exists() { Some(toml_path) } else { None }; let build = toml.build.unwrap_or_default(); diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index eb7da1bda73cb..04480277fe047 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -82,7 +82,7 @@ impl fmt::Display for Profile { } pub fn setup(config: &Config, profile: Profile) { - let path = &config.config; + let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml")); if path.exists() { eprintln!( From c54bc07cc4be57f1c18b53c975cc7a3f33ddfdca Mon Sep 17 00:00:00 2001 From: Tanner Davies Date: Mon, 7 Nov 2022 15:27:42 -0700 Subject: [PATCH 235/482] Only set config.config to None when using default path --- src/bootstrap/config.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c086d248e5ce1..ba50ce9ec2426 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -926,8 +926,10 @@ impl Config { // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, // but not if `config.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { + config.config = Some(toml_path.clone()); get_toml(&toml_path) } else { + config.config = None; TomlConfig::default() }; @@ -942,7 +944,6 @@ impl Config { } config.changelog_seen = toml.changelog_seen; - config.config = if toml_path.exists() { Some(toml_path) } else { None }; let build = toml.build.unwrap_or_default(); From f6c04daeff451ed97929b15afaa71c72d725b490 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Nov 2022 09:29:14 +0100 Subject: [PATCH 236/482] disable btree size tests on Miri --- library/alloc/src/collections/btree/node/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs index aadb0dc9c40d9..64bce0ff8c048 100644 --- a/library/alloc/src/collections/btree/node/tests.rs +++ b/library/alloc/src/collections/btree/node/tests.rs @@ -94,6 +94,7 @@ fn test_partial_eq() { #[test] #[cfg(target_arch = "x86_64")] +#[cfg_attr(miri, ignore)] // We'd like to run Miri with layout randomization fn test_sizes() { assert_eq!(core::mem::size_of::>(), 16); assert_eq!(core::mem::size_of::>(), 16 + CAPACITY * 2 * 8); From ce06c8eb83ebc555b767f76a842b2c3e065fd3cc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Nov 2022 10:33:54 +0100 Subject: [PATCH 237/482] run alloc benchmarks in Miri and fix UB --- library/alloc/src/alloc/tests.rs | 1 - .../alloc/src/collections/vec_deque/tests.rs | 34 +++++++++++-------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs index b2f0194599b28..1a5938fd34cf1 100644 --- a/library/alloc/src/alloc/tests.rs +++ b/library/alloc/src/alloc/tests.rs @@ -22,7 +22,6 @@ fn allocate_zeroed() { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn alloc_owned_small(b: &mut Bencher) { b.iter(|| { let _: Box<_> = Box::new(10); diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 1f2daef213c3b..a103531a20f20 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -3,7 +3,6 @@ use core::iter::TrustedLen; use super::*; #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_push_back_100(b: &mut test::Bencher) { let mut deq = VecDeque::with_capacity(101); b.iter(|| { @@ -16,7 +15,6 @@ fn bench_push_back_100(b: &mut test::Bencher) { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_push_front_100(b: &mut test::Bencher) { let mut deq = VecDeque::with_capacity(101); b.iter(|| { @@ -29,12 +27,15 @@ fn bench_push_front_100(b: &mut test::Bencher) { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_pop_back_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); + let size = 100; + let mut deq = VecDeque::::with_capacity(size+1); + // We'll mess with private state to pretend like `deq` is filled. + // Make sure the buffer is initialized so that we don't read uninit memory. + unsafe { deq.ptr().write_bytes(0u8, size+1) }; b.iter(|| { - deq.head = 100; + deq.head = size; deq.tail = 0; while !deq.is_empty() { test::black_box(deq.pop_back()); @@ -43,9 +44,9 @@ fn bench_pop_back_100(b: &mut test::Bencher) { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_retain_whole_10000(b: &mut test::Bencher) { - let v = (1..100000).collect::>(); + let size = if cfg!(miri) { 1000 } else { 100000 }; + let v = (1..size).collect::>(); b.iter(|| { let mut v = v.clone(); @@ -54,9 +55,9 @@ fn bench_retain_whole_10000(b: &mut test::Bencher) { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_retain_odd_10000(b: &mut test::Bencher) { - let v = (1..100000).collect::>(); + let size = if cfg!(miri) { 1000 } else { 100000 }; + let v = (1..size).collect::>(); b.iter(|| { let mut v = v.clone(); @@ -65,23 +66,26 @@ fn bench_retain_odd_10000(b: &mut test::Bencher) { } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_retain_half_10000(b: &mut test::Bencher) { - let v = (1..100000).collect::>(); + let size = if cfg!(miri) { 1000 } else { 100000 }; + let v = (1..size).collect::>(); b.iter(|| { let mut v = v.clone(); - v.retain(|x| *x > 50000) + v.retain(|x| *x > size/2) }) } #[bench] -#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks fn bench_pop_front_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); + let size = 100; + let mut deq = VecDeque::::with_capacity(size+1); + // We'll mess with private state to pretend like `deq` is filled. + // Make sure the buffer is initialized so that we don't read uninit memory. + unsafe { deq.ptr().write_bytes(0u8, size+1) }; b.iter(|| { - deq.head = 100; + deq.head = size; deq.tail = 0; while !deq.is_empty() { test::black_box(deq.pop_front()); From e6142067ccfac4eb1a4a038d9ae5556b414984b4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Nov 2022 15:24:49 +0100 Subject: [PATCH 238/482] fmt --- library/alloc/src/collections/vec_deque/tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index a103531a20f20..6e0f83020f957 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -29,10 +29,10 @@ fn bench_push_front_100(b: &mut test::Bencher) { #[bench] fn bench_pop_back_100(b: &mut test::Bencher) { let size = 100; - let mut deq = VecDeque::::with_capacity(size+1); + let mut deq = VecDeque::::with_capacity(size + 1); // We'll mess with private state to pretend like `deq` is filled. // Make sure the buffer is initialized so that we don't read uninit memory. - unsafe { deq.ptr().write_bytes(0u8, size+1) }; + unsafe { deq.ptr().write_bytes(0u8, size + 1) }; b.iter(|| { deq.head = size; @@ -72,17 +72,17 @@ fn bench_retain_half_10000(b: &mut test::Bencher) { b.iter(|| { let mut v = v.clone(); - v.retain(|x| *x > size/2) + v.retain(|x| *x > size / 2) }) } #[bench] fn bench_pop_front_100(b: &mut test::Bencher) { let size = 100; - let mut deq = VecDeque::::with_capacity(size+1); + let mut deq = VecDeque::::with_capacity(size + 1); // We'll mess with private state to pretend like `deq` is filled. // Make sure the buffer is initialized so that we don't read uninit memory. - unsafe { deq.ptr().write_bytes(0u8, size+1) }; + unsafe { deq.ptr().write_bytes(0u8, size + 1) }; b.iter(|| { deq.head = size; From 02a866a9d6d0ebc26e8d11fbc9f2a3585c756aee Mon Sep 17 00:00:00 2001 From: Kamil Koczurek Date: Mon, 7 Nov 2022 15:21:35 +0100 Subject: [PATCH 239/482] Add --print=split-debuginfo This option prints all supported values for -Csplit-debuginfo=.., i.e. only stable ones on stable/beta and all of them on nightly/dev. --- compiler/rustc_driver/src/lib.rs | 11 +++++++++++ compiler/rustc_session/src/config.rs | 2 ++ .../valid-print-requests/valid-print-requests.stderr | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index cf4bcc7c158fc..423f0cdddfd5c 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -736,6 +736,17 @@ fn print_crate_info( // Any output here interferes with Cargo's parsing of other printed output NativeStaticLibs => {} LinkArgs => {} + SplitDebuginfo => { + use rustc_target::spec::SplitDebuginfo::{Off, Packed, Unpacked}; + + for split in &[Off, Packed, Unpacked] { + let stable = sess.target.options.supported_split_debuginfo.contains(split); + let unstable_ok = sess.unstable_options(); + if stable || unstable_ok { + println!("{}", split); + } + } + } } } Compilation::Stop diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index aece29ca0cbf6..be084adb7b724 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -548,6 +548,7 @@ pub enum PrintRequest { NativeStaticLibs, StackProtectorStrategies, LinkArgs, + SplitDebuginfo, } pub enum Input { @@ -1806,6 +1807,7 @@ fn collect_print_requests( ("stack-protector-strategies", PrintRequest::StackProtectorStrategies), ("target-spec-json", PrintRequest::TargetSpec), ("link-args", PrintRequest::LinkArgs), + ("split-debuginfo", PrintRequest::SplitDebuginfo), ]; prints.extend(matches.opt_strs("print").into_iter().map(|req| { diff --git a/src/test/run-make/valid-print-requests/valid-print-requests.stderr b/src/test/run-make/valid-print-requests/valid-print-requests.stderr index 85782866d125a..5191e4676486a 100644 --- a/src/test/run-make/valid-print-requests/valid-print-requests.stderr +++ b/src/test/run-make/valid-print-requests/valid-print-requests.stderr @@ -1,2 +1,2 @@ -error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args` +error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`, `split-debuginfo` From 503d62585b02235e96829b190e99609f2508b21f Mon Sep 17 00:00:00 2001 From: yancy Date: Mon, 7 Nov 2022 16:51:23 +0100 Subject: [PATCH 240/482] rustdoc: Add mutable to the description --- library/core/src/slice/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 4f1bb17344b29..0fde931140fbe 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3524,8 +3524,8 @@ impl [T] { } } - /// Transmute the slice to a slice of another type, ensuring alignment of the types is - /// maintained. + /// Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the + /// types is maintained. /// /// This method splits the slice into three distinct slices: prefix, correctly aligned middle /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest From f86e5decb3e37cb2bbcee037d89d30022f66e9bb Mon Sep 17 00:00:00 2001 From: onestacked Date: Mon, 7 Nov 2022 17:41:58 +0100 Subject: [PATCH 241/482] Fix `const_fn_trait_ref_impl`, add test for it --- library/core/src/ops/function.rs | 25 ++++++++++++--------- src/test/ui/consts/fn_trait_refs.rs | 35 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/consts/fn_trait_refs.rs diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 8d4b0a7ccacdb..11b43b621c7b8 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -576,9 +576,10 @@ mod impls { use crate::marker::Tuple; #[stable(feature = "rust1", since = "1.0.0")] - impl Fn for &F + #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] + impl const Fn for &F where - F: Fn, + F: ~const Fn, { extern "rust-call" fn call(&self, args: A) -> F::Output { (**self).call(args) @@ -586,9 +587,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnMut for &F + #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] + impl const FnMut for &F where - F: Fn, + F: ~const Fn, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (**self).call(args) @@ -596,9 +598,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnOnce for &F + #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] + impl const FnOnce for &F where - F: Fn, + F: ~const Fn, { type Output = F::Output; @@ -608,9 +611,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnMut for &mut F + #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] + impl const FnMut for &mut F where - F: FnMut, + F: ~const FnMut, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (*self).call_mut(args) @@ -618,9 +622,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnOnce for &mut F + #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] + impl const FnOnce for &mut F where - F: FnMut, + F: ~const FnMut, { type Output = F::Output; extern "rust-call" fn call_once(self, args: A) -> F::Output { diff --git a/src/test/ui/consts/fn_trait_refs.rs b/src/test/ui/consts/fn_trait_refs.rs new file mode 100644 index 0000000000000..57465c5592580 --- /dev/null +++ b/src/test/ui/consts/fn_trait_refs.rs @@ -0,0 +1,35 @@ +// run-pass +#![feature(const_fn_trait_ref_impls)] +#![feature(fn_traits)] +#![feature(unboxed_closures)] +#![feature(const_trait_impl)] +#![feature(const_mut_refs)] + +use std::marker::Destruct; + +const fn test(i: i32) -> i32 { + i + 1 +} + +const fn call i32 + ~const Destruct>(mut f: F) -> F::Output { + f(5) +} + +const fn use_fn i32 + ~const Destruct>(mut f: F) -> F::Output { + call(&mut f) +} + +const fn test_fn() {} + +const fn tester(_fn: T) +where + T: ~const Fn() + ~const Destruct, +{ +} + +const fn main() { + tester(test_fn); + let test_ref = &test_fn; + tester(test_ref); + assert!(use_fn(test) == 6); +} From ff61d6ce43a07ad70b7580ae34455189a69813aa Mon Sep 17 00:00:00 2001 From: onestacked Date: Mon, 7 Nov 2022 21:16:22 +0100 Subject: [PATCH 242/482] Reworked const fn ref tests --- src/test/ui/consts/fn_trait_refs.rs | 73 +++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/src/test/ui/consts/fn_trait_refs.rs b/src/test/ui/consts/fn_trait_refs.rs index 57465c5592580..bc8766c74c60f 100644 --- a/src/test/ui/consts/fn_trait_refs.rs +++ b/src/test/ui/consts/fn_trait_refs.rs @@ -1,35 +1,80 @@ -// run-pass +// build-pass + #![feature(const_fn_trait_ref_impls)] #![feature(fn_traits)] #![feature(unboxed_closures)] #![feature(const_trait_impl)] #![feature(const_mut_refs)] +#![feature(const_cmp)] +#![feature(const_refs_to_cell)] use std::marker::Destruct; -const fn test(i: i32) -> i32 { - i + 1 +const fn tester_fn(f: T) -> T::Output +where + T: ~const Fn<()> + ~const Destruct, +{ + f() } -const fn call i32 + ~const Destruct>(mut f: F) -> F::Output { - f(5) +const fn tester_fn_mut(mut f: T) -> T::Output +where + T: ~const FnMut<()> + ~const Destruct, +{ + f() } -const fn use_fn i32 + ~const Destruct>(mut f: F) -> F::Output { - call(&mut f) +const fn tester_fn_once(f: T) -> T::Output +where + T: ~const FnOnce<()>, +{ + f() } -const fn test_fn() {} +const fn test_fn(mut f: T) -> (T::Output, T::Output, T::Output) +where + T: ~const Fn<()> + ~const Destruct, +{ + ( + // impl const Fn for &F + tester_fn(&f), + // impl const FnMut for &F + tester_fn_mut(&f), + // impl const FnOnce for &F + tester_fn_once(&f), + ) +} -const fn tester(_fn: T) +const fn test_fn_mut(mut f: T) -> (T::Output, T::Output) where - T: ~const Fn() + ~const Destruct, + T: ~const FnMut<()> + ~const Destruct, { + ( + // impl const FnMut for &mut F + tester_fn_mut(&mut f), + // impl const FnOnce for &mut F + tester_fn_once(&mut f), + ) +} +const fn test(i: i32) -> i32 { + i + 1 } const fn main() { - tester(test_fn); - let test_ref = &test_fn; - tester(test_ref); - assert!(use_fn(test) == 6); + const fn one() -> i32 { + 1 + }; + const fn two() -> i32 { + 2 + }; + + // FIXME(const_cmp_tuple) + let test_one = test_fn(one); + assert!(test_one.0 == 1); + assert!(test_one.1 == 1); + assert!(test_one.2 == 1); + + let test_two = test_fn_mut(two); + assert!(test_two.0 == 1); + assert!(test_two.1 == 1); } From 2e3cfbb1d8b4d6a0f519a1f3fa990014cf768b16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 7 Nov 2022 17:46:46 +0100 Subject: [PATCH 243/482] Fix invalid background-image file name --- src/librustdoc/html/static/css/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a38c0e42ab455..f58d2c609426d 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -854,7 +854,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ background-size: 20px; background-position: calc(100% - 2px) 56%; /* image is black color, themes should apply a "filter" property to change the color */ - background-image: url("down-arrow-2d685a4bae708e15.svg"); + background-image: url("down-arrow-927217e04c7463ac.svg"); } #crate-search > option { font-size: 1rem; From 241068401b1813bb19b37badeb877965d98d593c Mon Sep 17 00:00:00 2001 From: Rejyr Date: Mon, 7 Nov 2022 19:23:29 -0500 Subject: [PATCH 244/482] fix: lint against lint functions fix: lint against the functions `LintContext::{lookup_with_diagnostics,lookup,struct_span_lint,lint}`, `TyCtxt::struct_lint_node`, `LintLevelsBuilder::struct_lint`. --- compiler/rustc_lint/src/context.rs | 4 ++++ compiler/rustc_lint/src/levels.rs | 1 + compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_middle/src/ty/context.rs | 1 + 4 files changed, 7 insertions(+) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cec0003ffea78..28f6ac61c5bdd 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -579,6 +579,7 @@ pub trait LintContext: Sized { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] fn lookup_with_diagnostics( &self, lint: &'static Lint, @@ -882,6 +883,7 @@ pub trait LintContext: Sized { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] fn lookup>( &self, lint: &'static Lint, @@ -908,6 +910,7 @@ pub trait LintContext: Sized { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] fn struct_span_lint>( &self, lint: &'static Lint, @@ -933,6 +936,7 @@ pub trait LintContext: Sized { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] fn lint( &self, lint: &'static Lint, diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index db0a3419e6a5d..dfe52312ff00d 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1073,6 +1073,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] pub(crate) fn struct_lint( &self, lint: &'static Lint, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 5288fc542d79a..ebb7de70e0570 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -36,6 +36,7 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] +#![feature(rustc_attrs)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 50eece3011280..2a93df771e1e2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2872,6 +2872,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature + #[rustc_lint_diagnostics] pub fn struct_lint_node( self, lint: &'static Lint, From 4c41db5783e6ec8310022a90d14c662db3c606af Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 8 Nov 2022 09:36:08 +0100 Subject: [PATCH 245/482] clarify licensing situation of mpsc and spsc queue --- library/std/src/sync/mpsc/mpsc_queue.rs | 11 +++++++++-- library/std/src/sync/mpsc/spsc_queue.rs | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/mpsc/mpsc_queue.rs b/library/std/src/sync/mpsc/mpsc_queue.rs index cdd64a5def506..7322512e3b458 100644 --- a/library/std/src/sync/mpsc/mpsc_queue.rs +++ b/library/std/src/sync/mpsc/mpsc_queue.rs @@ -8,8 +8,15 @@ //! method, and see the method for more information about it. Due to this //! caveat, this queue might not be appropriate for all use-cases. -// https://www.1024cores.net/home/lock-free-algorithms -// /queues/non-intrusive-mpsc-node-based-queue +// The original implementation is based off: +// https://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue +// +// Note that back when the code was imported, it was licensed under the BSD-2-Clause license: +// http://web.archive.org/web/20110411011612/https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue +// +// The original author of the code agreed to relicense it under `MIT OR Apache-2.0` in 2017, so as +// of today the license of this file is the same as the rest of the codebase: +// https://github.com/rust-lang/rust/pull/42149 #[cfg(all(test, not(target_os = "emscripten")))] mod tests; diff --git a/library/std/src/sync/mpsc/spsc_queue.rs b/library/std/src/sync/mpsc/spsc_queue.rs index 7e745eb31de60..61f91313ea96d 100644 --- a/library/std/src/sync/mpsc/spsc_queue.rs +++ b/library/std/src/sync/mpsc/spsc_queue.rs @@ -4,7 +4,15 @@ //! concurrently between two threads. This data structure is safe to use and //! enforces the semantics that there is one pusher and one popper. +// The original implementation is based off: // https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue +// +// Note that back when the code was imported, it was licensed under the BSD-2-Clause license: +// http://web.archive.org/web/20110411011612/https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue +// +// The original author of the code agreed to relicense it under `MIT OR Apache-2.0` in 2017, so as +// of today the license of this file is the same as the rest of the codebase: +// https://github.com/rust-lang/rust/pull/42149 #[cfg(all(test, not(target_os = "emscripten")))] mod tests; From 4c671ccd5c250536a66f7a3ef865abe5b55c10c2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 8 Nov 2022 11:51:10 +0000 Subject: [PATCH 246/482] Remove an address comparison from the parser --- compiler/rustc_parse/src/parser/expr.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4a1162b959983..728435b602997 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -833,16 +833,11 @@ impl<'a> Parser<'a> { ("cast", None) }; - // Save the memory location of expr before parsing any following postfix operators. - // This will be compared with the memory location of the output expression. - // If they different we can assume we parsed another expression because the existing expression is not reallocated. - let addr_before = &*cast_expr as *const _ as usize; let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?; - let changed = addr_before != &*with_postfix as *const _ as usize; // Check if an illegal postfix operator has been added after the cast. // If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator. - if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed { + if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) { let msg = format!( "{cast_kind} cannot be followed by {}", match with_postfix.kind { From 342aee2cf2d47ce09cd99e35904a77c340a5c02b Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Tue, 8 Nov 2022 21:49:58 +0400 Subject: [PATCH 247/482] Fix outdated comment Co-authored-by: clubby789 --- compiler/rustc_parse/src/parser/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 728435b602997..d784fef2bed58 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -836,7 +836,7 @@ impl<'a> Parser<'a> { let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?; // Check if an illegal postfix operator has been added after the cast. - // If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator. + // If the resulting expression is not a cast, it is an illegal postfix operator. if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) { let msg = format!( "{cast_kind} cannot be followed by {}", From 347956b29a7a04f3db46bb669b4e765a4cb9d236 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 8 Nov 2022 11:29:58 -0800 Subject: [PATCH 248/482] Add llvm-main to triagebot.toml --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 202f9cad57a43..d3f9efcc41c3e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -12,6 +12,7 @@ allow-unauthenticated = [ "T-*", "WG-*", "const-hack", + "llvm-main", "needs-fcp", "relnotes", "requires-nightly", From 1f15e8b536a36014e8f18d72e491dd7255538a31 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Mon, 17 Oct 2022 22:08:15 -0400 Subject: [PATCH 249/482] Add an optional Span to BrAnon and use it to print better error for HRTB error from generator interior --- .../src/diagnostics/bound_region_errors.rs | 3 + .../src/diagnostics/region_name.rs | 2 +- .../rustc_hir_analysis/src/astconv/mod.rs | 4 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 17 ++-- .../src/generator_interior/mod.rs | 88 ++++++++++++++----- compiler/rustc_hir_typeck/src/lib.rs | 1 + .../src/errors/note_and_explain.rs | 7 +- .../src/infer/canonical/canonicalizer.rs | 2 +- .../src/infer/error_reporting/mod.rs | 7 +- .../error_reporting/nice_region_error/mod.rs | 5 +- .../nice_region_error/named_anon_conflict.rs | 2 +- .../nice_region_error/placeholder_relation.rs | 78 ++++++++++++++++ compiler/rustc_middle/src/infer/canonical.rs | 6 +- compiler/rustc_middle/src/ty/fold.rs | 8 +- compiler/rustc_middle/src/ty/print/pretty.rs | 8 +- .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 4 +- .../src/traits/select/mod.rs | 1 + compiler/rustc_traits/src/chalk/db.rs | 2 +- compiler/rustc_traits/src/chalk/lowering.rs | 20 +++-- .../bugs/issue-100013.rs | 22 +++++ .../bugs/issue-100013.stderr | 23 +++++ 23 files changed, 251 insertions(+), 63 deletions(-) create mode 100644 compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-100013.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-100013.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index dac6abe37f589..897a161f78563 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -158,6 +158,7 @@ trait TypeOpInfo<'tcx> { error_region: Option>, ) -> Option>; + #[instrument(level = "debug", skip(self, mbcx))] fn report_error( &self, mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, @@ -167,6 +168,7 @@ trait TypeOpInfo<'tcx> { ) { let tcx = mbcx.infcx.tcx; let base_universe = self.base_universe(); + debug!(?base_universe); let Some(adjusted_universe) = placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) @@ -389,6 +391,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( ) } +#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] fn try_extract_error_from_region_constraints<'tcx>( infcx: &InferCtxt<'tcx>, placeholder_region: ty::Region<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index c044dbaba47e2..f9741bacd1702 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -355,7 +355,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }) } - ty::BoundRegionKind::BrAnon(_) => None, + ty::BoundRegionKind::BrAnon(..) => None, }, ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 2665813478c2c..4518cf30acdd5 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2980,7 +2980,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) { for br in referenced_regions.difference(&constrained_regions) { let br_name = match *br { - ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(_) | ty::BrEnv => { + ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) | ty::BrEnv => { "an anonymous lifetime".to_string() } ty::BrNamed(_, name) => format!("lifetime `{}`", name), @@ -2988,7 +2988,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut err = generate_err(&br_name); - if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(_) = *br { + if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) = *br { // The only way for an anonymous lifetime to wind up // in the return type but **also** be unconstrained is // if it only appears in "associated types" in the diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 609095c9ceaa7..69e54b41d4c04 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -134,15 +134,18 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let name_str = intrinsic_name.as_str(); let bound_vars = tcx.mk_bound_variable_kinds( - [ty::BoundVariableKind::Region(ty::BrAnon(0)), ty::BoundVariableKind::Region(ty::BrEnv)] - .iter() - .copied(), + [ + ty::BoundVariableKind::Region(ty::BrAnon(0, None)), + ty::BoundVariableKind::Region(ty::BrEnv), + ] + .iter() + .copied(), ); let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { let region = tcx.mk_region(ty::ReLateBound( ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }, + ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }, )); let env_region = tcx.mk_region(ty::ReLateBound( ty::INNERMOST, @@ -364,7 +367,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ); let discriminant_def_id = assoc_items[0]; - let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }; + let br = + ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }; ( 1, vec![ @@ -418,7 +422,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), sym::raw_eq => { - let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }; + let br = + ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0, None) }; let param_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)); (1, vec![param_ty; 2], tcx.types.bool) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index b7dd599cd4321..06f6d84099090 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -13,8 +13,9 @@ use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdSet; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind}; +use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData}; -use rustc_middle::ty::{self, RvalueScopes, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitable}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -211,31 +212,52 @@ pub fn resolve_interior<'a, 'tcx>( debug!("types in generator {:?}, span = {:?}", types, body.value.span); - let mut counter = 0; + // We want to deduplicate if the lifetimes are the same modulo some non-informative counter. + // So, we need to actually do two passes: first by type to anonymize (preserving information + // required for diagnostics), then a second pass over all captured types to reassign disjoint + // region indices. let mut captured_tys = FxHashSet::default(); let type_causes: Vec<_> = types .into_iter() .filter_map(|mut cause| { - // Erase regions and canonicalize late-bound regions to deduplicate as many types as we - // can. - let ty = fcx.normalize_associated_types_in(cause.span, cause.ty); - let erased = fcx.tcx.erase_regions(ty); - if captured_tys.insert(erased) { - // Replace all regions inside the generator interior with late bound regions. - // Note that each region slot in the types gets a new fresh late bound region, - // which means that none of the regions inside relate to any other, even if - // typeck had previously found constraints that would cause them to be related. - let folded = fcx.tcx.fold_regions(erased, |_, current_depth| { - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(counter), - kind: ty::BrAnon(counter), - }; - let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); - counter += 1; - r - }); + // Replace all regions inside the generator interior with late bound regions. + // Note that each region slot in the types gets a new fresh late bound region, + // which means that none of the regions inside relate to any other, even if + // typeck had previously found constraints that would cause them to be related. - cause.ty = folded; + let mut counter = 0; + let ty = fcx.normalize_associated_types_in(cause.span, cause.ty); + let ty = fcx.tcx.fold_regions(ty, |region, current_depth| { + let br = match region.kind() { + ty::ReVar(vid) => { + let origin = fcx.region_var_origin(vid); + match origin { + RegionVariableOrigin::EarlyBoundRegion(span, _) => { + let kind = ty::BrAnon(counter, Some(span)); + let var = ty::BoundVar::from_u32(counter); + counter += 1; + ty::BoundRegion { var, kind } + } + _ => { + let kind = ty::BrAnon(counter, None); + let var = ty::BoundVar::from_u32(counter); + counter += 1; + ty::BoundRegion { var, kind } + } + } + } + _ => { + let kind = ty::BrAnon(counter, None); + let var = ty::BoundVar::from_u32(counter); + counter += 1; + ty::BoundRegion { var, kind } + } + }; + let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); + r + }); + if captured_tys.insert(ty) { + cause.ty = ty; Some(cause) } else { None @@ -243,11 +265,29 @@ pub fn resolve_interior<'a, 'tcx>( }) .collect(); + let mut bound_vars: Vec = vec![]; + let mut counter = 0; + let type_causes = fcx.tcx.fold_regions(type_causes, |region, current_depth| { + let br = match region.kind() { + ty::ReLateBound(_, br) => { + let kind = match br.kind { + ty::BrAnon(_, span) => ty::BrAnon(counter, span), + _ => br.kind, + }; + let var = ty::BoundVar::from_usize(bound_vars.len()); + bound_vars.push(ty::BoundVariableKind::Region(kind)); + counter += 1; + ty::BoundRegion { var, kind } + } + _ => bug!("All regions should have been replaced by ReLateBound"), + }; + let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); + r + }); + // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let bound_vars = fcx.tcx.mk_bound_variable_kinds( - (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))), - ); + let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.iter()); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 052fdef2fc518..183e80f2e0840 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -209,6 +209,7 @@ fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::T typeck_with_fallback(tcx, def_id, fallback) } +#[instrument(level = "debug", skip(tcx, fallback), ret)] fn typeck_with_fallback<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 6a29d85627a84..7aaa5ce2f4242 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -89,10 +89,13 @@ impl<'a> DescriptionCtx<'a> { }; me.span = Some(sp); } - ty::BrAnon(idx) => { + ty::BrAnon(idx, span) => { me.kind = "anon_num_here"; me.num_arg = idx+1; - me.span = Some(tcx.def_span(scope)); + me.span = match span { + Some(_) => span, + None => Some(tcx.def_span(scope)), + } }, _ => { me.kind = "defined_here_reg"; diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index aa44d582fd6ce..3dc0d60b1eb0f 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -738,7 +738,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); - let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32()) }; + let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) }; let region = ty::ReLateBound(self.binder_index, br); self.tcx().mk_region(region) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3dbc9b9f3f938..61519454a2cf5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -207,9 +207,12 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>( }; (text, sp) } - ty::BrAnon(idx) => ( + ty::BrAnon(idx, span) => ( format!("the anonymous lifetime #{} defined here", idx + 1), - tcx.def_span(scope) + match span { + Some(span) => span, + None => tcx.def_span(scope) + } ), _ => ( format!("the lifetime `{}` as defined here", region), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index aaf5a7af00afa..8a0e332f9c704 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -10,6 +10,7 @@ pub mod find_anon_type; mod mismatched_static_lifetime; mod named_anon_conflict; mod placeholder_error; +mod placeholder_relation; mod static_impl_trait; mod trait_impl_difference; mod util; @@ -52,7 +53,9 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { pub fn try_report_from_nll(&self) -> Option> { // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of // the nice region errors are required when running under the MIR borrow checker. - self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict()) + self.try_report_named_anon_conflict() + .or_else(|| self.try_report_placeholder_conflict()) + .or_else(|| self.try_report_placeholder_relation()) } pub fn try_report(&self) -> Option { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 76cb76d9ff4e5..3fe7c1598fc3f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -68,7 +68,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let is_impl_item = region_info.is_impl_item; match br { - ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(_) => {} + ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) => {} _ => { /* not an anonymous region */ debug!("try_report_named_anon_conflict: not an anonymous region"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs new file mode 100644 index 0000000000000..7f39de1944fd5 --- /dev/null +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs @@ -0,0 +1,78 @@ +use crate::infer::{ + error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin, +}; +use rustc_data_structures::intern::Interned; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; +use rustc_middle::ty::{self, RePlaceholder, Region}; + +impl<'tcx> NiceRegionError<'_, 'tcx> { + /// Emitted wwhen given a `ConcreteFailure` when relating two placeholders. + pub(super) fn try_report_placeholder_relation( + &self, + ) -> Option> { + match &self.error { + Some(RegionResolutionError::ConcreteFailure( + SubregionOrigin::RelateRegionParamBound(span), + Region(Interned(RePlaceholder(ty::Placeholder { name: sub_name, .. }), _)), + Region(Interned(RePlaceholder(ty::Placeholder { name: sup_name, .. }), _)), + )) => { + let msg = "lifetime bound not satisfied"; + let mut err = self.tcx().sess.struct_span_err(*span, msg); + let (sub_span, sub_symbol) = match sub_name { + ty::BrNamed(def_id, symbol) => { + (Some(self.tcx().def_span(def_id)), Some(symbol)) + } + ty::BrAnon(_, span) => (*span, None), + ty::BrEnv => (None, None), + }; + let (sup_span, sup_symbol) = match sup_name { + ty::BrNamed(def_id, symbol) => { + (Some(self.tcx().def_span(def_id)), Some(symbol)) + } + ty::BrAnon(_, span) => (*span, None), + ty::BrEnv => (None, None), + }; + match (sub_span, sup_span, sub_symbol, sup_symbol) { + (Some(sub_span), Some(sup_span), Some(sub_symbol), Some(sup_symbol)) => { + err.span_note( + sub_span, + format!("the lifetime `{sub_symbol}` defined here..."), + ); + err.span_note( + sup_span, + format!("...must outlive the lifetime `{sup_symbol}` defined here"), + ); + } + (Some(sub_span), Some(sup_span), _, Some(sup_symbol)) => { + err.span_note(sub_span, format!("the lifetime defined here...")); + err.span_note( + sup_span, + format!("...must outlive the lifetime `{sup_symbol}` defined here"), + ); + } + (Some(sub_span), Some(sup_span), Some(sub_symbol), _) => { + err.span_note( + sub_span, + format!("the lifetime `{sub_symbol}` defined here..."), + ); + err.span_note( + sup_span, + format!("...must outlive the lifetime defined here"), + ); + } + (Some(sub_span), Some(sup_span), _, _) => { + err.span_note(sub_span, format!("the lifetime defined here, ...")); + err.span_note( + sup_span, + format!("...must outlive the lifetime defined here"), + ); + } + _ => {} + } + Some(err) + } + + _ => None, + } + } +} diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 8d1ed4b2a5228..0331d764b38a1 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -336,8 +336,10 @@ impl<'tcx> CanonicalVarValues<'tcx> { tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() } GenericArgKind::Lifetime(..) => { - let br = - ty::BoundRegion { var: ty::BoundVar::from_u32(i), kind: ty::BrAnon(i) }; + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(i), + kind: ty::BrAnon(i, None), + }; tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() } GenericArgKind::Const(ct) => tcx diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index a329753726ef2..2842b3c3102d2 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -598,7 +598,7 @@ impl<'tcx> TyCtxt<'tcx> { .replace_late_bound_regions(sig, |_| { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), - kind: ty::BrAnon(counter), + kind: ty::BrAnon(counter, None), }; let r = self.mk_region(ty::ReLateBound(ty::INNERMOST, br)); counter += 1; @@ -606,7 +606,7 @@ impl<'tcx> TyCtxt<'tcx> { }) .0; let bound_vars = self.mk_bound_variable_kinds( - (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))), + (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))), ); Binder::bind_with_vars(inner, bound_vars) } @@ -626,7 +626,9 @@ impl<'tcx> TyCtxt<'tcx> { let index = entry.index(); let var = ty::BoundVar::from_usize(index); let kind = entry - .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon(index as u32))) + .or_insert_with(|| { + ty::BoundVariableKind::Region(ty::BrAnon(index as u32, None)) + }) .expect_region(); let br = ty::BoundRegion { var, kind }; self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fab85c39d2535..c8815537835b1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2115,7 +2115,7 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { // If this is an anonymous placeholder, don't rename. Otherwise, in some // async fns, we get a `for<'r> Send` bound match kind { - ty::BrAnon(_) | ty::BrEnv => r, + ty::BrAnon(..) | ty::BrEnv => r, _ => { // Index doesn't matter, since this is just for naming and these never get bound let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind }; @@ -2226,10 +2226,10 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { let ty::BoundVariableKind::Region(var) = var else { // This doesn't really matter because it doesn't get used, // it's just an empty value - return ty::BrAnon(0); + return ty::BrAnon(0, None); }; match var { - ty::BrAnon(_) | ty::BrEnv => { + ty::BrAnon(..) | ty::BrEnv => { start_or_continue(&mut self, "for<", ", "); let name = next_name(&self); debug!(?name); @@ -2271,7 +2271,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { binder_level_idx: ty::DebruijnIndex, br: ty::BoundRegion| { let (name, kind) = match br.kind { - ty::BrAnon(_) | ty::BrEnv => { + ty::BrAnon(..) | ty::BrEnv => { let name = next_name(&self); if let Some(lt_idx) = lifetime_idx { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index f2070869ce0cd..9f0598d0ba86b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -68,7 +68,7 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { impl fmt::Debug for ty::BoundRegionKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), + ty::BrAnon(n, span) => write!(f, "BrAnon({n:?}, {span:?})"), ty::BrNamed(did, name) => { if did.is_crate_root() { write!(f, "BrNamed({})", name) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 5f108bf0ef306..49d82b503a4bb 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -59,7 +59,7 @@ pub struct FreeRegion { #[derive(HashStable)] pub enum BoundRegionKind { /// An anonymous region parameter for a given fn (&T) - BrAnon(u32), + BrAnon(u32, Option), /// Named region parameters for functions (a in &'a T) /// diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 2109b3c24962e..e540e2f2a2192 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -218,7 +218,7 @@ impl<'tcx> SymbolMangler<'tcx> { let lifetimes = regions .into_iter() .map(|br| match br { - ty::BrAnon(i) => i, + ty::BrAnon(i, _) => i, _ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value), }) .max() @@ -335,7 +335,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // Late-bound lifetimes use indices starting at 1, // see `BinderLevel` for more details. - ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => { + ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i, _), .. }) => { let binder = &self.binders[self.binders.len() - 1 - debruijn.index()]; let depth = binder.lifetime_depths.start + i; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2954a2c163f40..c6ff83120a736 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1971,6 +1971,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Bar where struct Bar { x: T, y: u32 } -> [i32, u32] /// Zed where enum Zed { A(T), B(u32) } -> [i32, u32] /// ``` + #[instrument(level = "debug", skip(self), ret)] fn constituent_types_for_ty( &self, t: ty::Binder<'tcx, Ty<'tcx>>, diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 2035252fe39a6..07f92299f72b4 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -728,7 +728,7 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx ty::GenericParamDefKind::Lifetime => { let br = ty::BoundRegion { var: ty::BoundVar::from_usize(substs.len()), - kind: ty::BrAnon(substs.len() as u32), + kind: ty::BrAnon(substs.len() as u32, None), }; tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 0492e94b94e98..b64d53e60dee6 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -498,13 +498,13 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime unimplemented!(), chalk_ir::LifetimeData::Placeholder(p) => ty::RePlaceholder(ty::Placeholder { universe: ty::UniverseIndex::from_usize(p.ui.counter), - name: ty::BoundRegionKind::BrAnon(p.idx as u32), + name: ty::BoundRegionKind::BrAnon(p.idx as u32, None), }), chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static, chalk_ir::LifetimeData::Empty(_) => { @@ -933,7 +933,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { } } - ty::BoundRegionKind::BrAnon(var) => match self.parameters.entry(var) { + ty::BoundRegionKind::BrAnon(var, _) => match self.parameters.entry(var) { Entry::Vacant(entry) => { entry.insert(chalk_ir::VariableKind::Lifetime); } @@ -991,13 +991,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { ty::ReLateBound(index, br) if index == self.binder_index => match br.kind { ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { Some(idx) => { - let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) }; + let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx, None) }; return self.tcx.mk_region(ty::ReLateBound(index, new_br)); } None => panic!("Missing `BrNamed`."), }, ty::BrEnv => unimplemented!(), - ty::BrAnon(_) => {} + ty::BrAnon(..) => {} }, _ => (), }; @@ -1072,14 +1072,16 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { Some(idx) => { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(*idx), - kind: ty::BrAnon(*idx), + kind: ty::BrAnon(*idx, None), }; self.tcx.mk_region(ty::ReLateBound(self.binder_index, br)) } None => { let idx = self.named_regions.len() as u32; - let br = - ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) }; + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(idx), + kind: ty::BrAnon(idx, None), + }; self.named_regions.insert(_re.def_id, idx); self.tcx.mk_region(ty::ReLateBound(self.binder_index, br)) } @@ -1156,7 +1158,7 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { match *r { ty::RePlaceholder(p) if p.universe == self.universe_index => { - if let ty::BoundRegionKind::BrAnon(anon) = p.name { + if let ty::BoundRegionKind::BrAnon(anon, _) = p.name { self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon); } } diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.rs b/src/test/ui/generic-associated-types/bugs/issue-100013.rs new file mode 100644 index 0000000000000..f995591d76ca6 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-100013.rs @@ -0,0 +1,22 @@ +// check-fail +// known-bug +// edition: 2021 + +// We really should accept this, but we need implied bounds between the regions +// in a generator interior. + +pub trait FutureIterator { + type Future<'s, 'cx>: Send + where + 's: 'cx; +} + +fn call_2() -> impl Send { + async { // a generator checked for autotrait impl `Send` + //~^ lifetime bound not satisfied + let x = None::>; // a type referencing GAT + async {}.await; // a yield point + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr new file mode 100644 index 0000000000000..11d149faa8fb1 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr @@ -0,0 +1,23 @@ +error: lifetime bound not satisfied + --> $DIR/issue-100013.rs:15:5 + | +LL | / async { // a generator checked for autotrait impl `Send` +LL | | +LL | | let x = None::>; // a type referencing GAT +LL | | async {}.await; // a yield point +LL | | } + | |_____^ + | +note: the lifetime defined here, ... + --> $DIR/issue-100013.rs:17:38 + | +LL | let x = None::>; // a type referencing GAT + | ^^ +note: ...must outlive the lifetime defined here + --> $DIR/issue-100013.rs:17:34 + | +LL | let x = None::>; // a type referencing GAT + | ^^ + +error: aborting due to previous error + From a198591ad7e7fa0b344a13e69e22369f77003505 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Tue, 18 Oct 2022 20:08:13 -0400 Subject: [PATCH 250/482] Get spans for a couple more region types, add some optimizations, and extend test --- .../src/generator_interior/mod.rs | 82 +++++++++++-------- .../nice_region_error/placeholder_relation.rs | 2 +- .../bugs/issue-100013.rs | 19 ++++- .../bugs/issue-100013.stderr | 60 +++++++++++++- 4 files changed, 126 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 06f6d84099090..7bbfb70f2c3a3 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -15,9 +15,11 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind}; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData}; +use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitable}; use rustc_span::symbol::sym; use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; mod drop_ranges; @@ -226,6 +228,12 @@ pub fn resolve_interior<'a, 'tcx>( // typeck had previously found constraints that would cause them to be related. let mut counter = 0; + let mut mk_bound_region = |span| { + let kind = ty::BrAnon(counter, span); + let var = ty::BoundVar::from_u32(counter); + counter += 1; + ty::BoundRegion { var, kind } + }; let ty = fcx.normalize_associated_types_in(cause.span, cause.ty); let ty = fcx.tcx.fold_regions(ty, |region, current_depth| { let br = match region.kind() { @@ -233,25 +241,24 @@ pub fn resolve_interior<'a, 'tcx>( let origin = fcx.region_var_origin(vid); match origin { RegionVariableOrigin::EarlyBoundRegion(span, _) => { - let kind = ty::BrAnon(counter, Some(span)); - let var = ty::BoundVar::from_u32(counter); - counter += 1; - ty::BoundRegion { var, kind } - } - _ => { - let kind = ty::BrAnon(counter, None); - let var = ty::BoundVar::from_u32(counter); - counter += 1; - ty::BoundRegion { var, kind } + mk_bound_region(Some(span)) } + _ => mk_bound_region(None), } } - _ => { - let kind = ty::BrAnon(counter, None); - let var = ty::BoundVar::from_u32(counter); - counter += 1; - ty::BoundRegion { var, kind } + // FIXME: these should use `BrNamed` + ty::ReEarlyBound(region) => { + mk_bound_region(Some(fcx.tcx.def_span(region.def_id))) } + ty::ReLateBound(_, ty::BoundRegion { kind, .. }) + | ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind { + ty::BoundRegionKind::BrAnon(_, span) => mk_bound_region(span), + ty::BoundRegionKind::BrNamed(def_id, _) => { + mk_bound_region(Some(fcx.tcx.def_span(def_id))) + } + ty::BoundRegionKind::BrEnv => mk_bound_region(None), + }, + _ => mk_bound_region(None), }; let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); r @@ -265,25 +272,34 @@ pub fn resolve_interior<'a, 'tcx>( }) .collect(); - let mut bound_vars: Vec = vec![]; + let mut bound_vars: SmallVec<[BoundVariableKind; 4]> = smallvec![]; let mut counter = 0; - let type_causes = fcx.tcx.fold_regions(type_causes, |region, current_depth| { - let br = match region.kind() { - ty::ReLateBound(_, br) => { - let kind = match br.kind { - ty::BrAnon(_, span) => ty::BrAnon(counter, span), - _ => br.kind, - }; - let var = ty::BoundVar::from_usize(bound_vars.len()); - bound_vars.push(ty::BoundVariableKind::Region(kind)); - counter += 1; - ty::BoundRegion { var, kind } - } - _ => bug!("All regions should have been replaced by ReLateBound"), - }; - let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); - r - }); + // Optimization: If there is only one captured type, then we don't actually + // need to fold and reindex (since the first type doesn't change). + let type_causes = if captured_tys.len() > 0 { + // Optimization: Use `replace_escaping_bound_vars_uncached` instead of + // `fold_regions`, since we only have late bound regions, and it skips + // types without bound regions. + fcx.tcx.replace_escaping_bound_vars_uncached( + type_causes, + FnMutDelegate { + regions: &mut |br| { + let kind = match br.kind { + ty::BrAnon(_, span) => ty::BrAnon(counter, span), + _ => br.kind, + }; + let var = ty::BoundVar::from_usize(bound_vars.len()); + bound_vars.push(ty::BoundVariableKind::Region(kind)); + counter += 1; + fcx.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var, kind })) + }, + types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"), + consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"), + }, + ) + } else { + type_causes + }; // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs index 7f39de1944fd5..d0813ccd3b401 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs @@ -61,7 +61,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ); } (Some(sub_span), Some(sup_span), _, _) => { - err.span_note(sub_span, format!("the lifetime defined here, ...")); + err.span_note(sub_span, format!("the lifetime defined here...")); err.span_note( sup_span, format!("...must outlive the lifetime defined here"), diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.rs b/src/test/ui/generic-associated-types/bugs/issue-100013.rs index f995591d76ca6..fc4e47a3ba188 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-100013.rs +++ b/src/test/ui/generic-associated-types/bugs/issue-100013.rs @@ -11,7 +11,7 @@ pub trait FutureIterator { 's: 'cx; } -fn call_2() -> impl Send { +fn call() -> impl Send { async { // a generator checked for autotrait impl `Send` //~^ lifetime bound not satisfied let x = None::>; // a type referencing GAT @@ -19,4 +19,21 @@ fn call_2() -> impl Send { } } +fn call2<'a, 'b, I: FutureIterator>() -> impl Send { + async { // a generator checked for autotrait impl `Send` + //~^ lifetime bound not satisfied + let x = None::>; // a type referencing GAT + //~^ lifetime may not live long enough + async {}.await; // a yield point + } +} + +fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { + async { // a generator checked for autotrait impl `Send` + //~^ lifetime bound not satisfied + let x = None::>; // a type referencing GAT + async {}.await; // a yield point + } +} + fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr index 11d149faa8fb1..d9fcf8c48e2f7 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr @@ -8,7 +8,7 @@ LL | | async {}.await; // a yield point LL | | } | |_____^ | -note: the lifetime defined here, ... +note: the lifetime defined here... --> $DIR/issue-100013.rs:17:38 | LL | let x = None::>; // a type referencing GAT @@ -19,5 +19,61 @@ note: ...must outlive the lifetime defined here LL | let x = None::>; // a type referencing GAT | ^^ -error: aborting due to previous error +error: lifetime bound not satisfied + --> $DIR/issue-100013.rs:23:5 + | +LL | / async { // a generator checked for autotrait impl `Send` +LL | | +LL | | let x = None::>; // a type referencing GAT +LL | | +LL | | async {}.await; // a yield point +LL | | } + | |_____^ + | +note: the lifetime defined here... + --> $DIR/issue-100013.rs:22:14 + | +LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { + | ^^ +note: ...must outlive the lifetime defined here + --> $DIR/issue-100013.rs:22:10 + | +LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { + | ^^ + +error: lifetime may not live long enough + --> $DIR/issue-100013.rs:25:17 + | +LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let x = None::>; // a type referencing GAT + | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + +error: lifetime bound not satisfied + --> $DIR/issue-100013.rs:32:5 + | +LL | / async { // a generator checked for autotrait impl `Send` +LL | | +LL | | let x = None::>; // a type referencing GAT +LL | | async {}.await; // a yield point +LL | | } + | |_____^ + | +note: the lifetime defined here... + --> $DIR/issue-100013.rs:31:18 + | +LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { + | ^^ +note: ...must outlive the lifetime defined here + --> $DIR/issue-100013.rs:31:10 + | +LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { + | ^^ + +error: aborting due to 4 previous errors From efbab6701078ec7b78aa737bade288a477567699 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Mon, 7 Nov 2022 17:52:08 -0500 Subject: [PATCH 251/482] Add a known that this is a known limitation --- .../error_reporting/nice_region_error/placeholder_relation.rs | 1 + src/test/ui/generic-associated-types/bugs/issue-100013.stderr | 3 +++ 2 files changed, 4 insertions(+) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs index d0813ccd3b401..c42240f21724f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs @@ -69,6 +69,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { } _ => {} } + err.note("this is a known limitation that will be removed in the future (see issue #100013 for more information)"); Some(err) } diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr index d9fcf8c48e2f7..72ae288dcab64 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr @@ -18,6 +18,7 @@ note: ...must outlive the lifetime defined here | LL | let x = None::>; // a type referencing GAT | ^^ + = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) error: lifetime bound not satisfied --> $DIR/issue-100013.rs:23:5 @@ -40,6 +41,7 @@ note: ...must outlive the lifetime defined here | LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { | ^^ + = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) error: lifetime may not live long enough --> $DIR/issue-100013.rs:25:17 @@ -74,6 +76,7 @@ note: ...must outlive the lifetime defined here | LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { | ^^ + = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) error: aborting due to 4 previous errors From 61a9f71a80a6adfdcf06c9e25596ca8f80755e9d Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 6 Nov 2022 13:39:13 +0000 Subject: [PATCH 252/482] fixyfixfix --- .../src/collect/lifetimes.rs | 92 ++++++++++++++++++- src/test/ui/issues/issue-47511.stderr | 18 ---- .../downgraded_to_early_through_alias.rs | 24 +++++ .../issue-47511.rs | 7 +- .../mismatched_arg_count.rs | 12 +++ .../mismatched_arg_count.stderr | 17 ++++ 6 files changed, 141 insertions(+), 29 deletions(-) delete mode 100644 src/test/ui/issues/issue-47511.stderr create mode 100644 src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs rename src/test/ui/{issues => late-bound-lifetimes}/issue-47511.rs (52%) create mode 100644 src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs create mode 100644 src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 3d07f3fbc674d..b9583bd2244b9 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -18,7 +18,7 @@ use rustc_middle::bug; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; -use rustc_middle::ty::{self, DefIdTree, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -1781,7 +1781,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet< let mut late_bound = FxIndexSet::default(); - let mut constrained_by_input = ConstrainedCollector::default(); + let mut constrained_by_input = ConstrainedCollector { regions: Default::default(), tcx }; for arg_ty in decl.inputs { constrained_by_input.visit_ty(arg_ty); } @@ -1834,12 +1834,44 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet< debug!(?late_bound); return Some(tcx.arena.alloc(late_bound)); - #[derive(Default)] - struct ConstrainedCollector { + struct ConstrainedCollectorPostAstConv { + arg_is_constrained: Box<[bool]>, + } + + use std::ops::ControlFlow; + use ty::Ty; + impl<'tcx> TypeVisitor<'tcx> for ConstrainedCollectorPostAstConv { + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + match t.kind() { + ty::Param(param_ty) => { + self.arg_is_constrained[param_ty.index as usize] = true; + } + ty::Projection(_) => return ControlFlow::Continue(()), + _ => (), + } + t.super_visit_with(self) + } + + fn visit_const(&mut self, _: ty::Const<'tcx>) -> ControlFlow { + ControlFlow::Continue(()) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + debug!("r={:?}", r.kind()); + if let ty::RegionKind::ReEarlyBound(region) = r.kind() { + self.arg_is_constrained[region.index as usize] = true; + } + + ControlFlow::Continue(()) + } + } + + struct ConstrainedCollector<'tcx> { + tcx: TyCtxt<'tcx>, regions: FxHashSet, } - impl<'v> Visitor<'v> for ConstrainedCollector { + impl<'v> Visitor<'v> for ConstrainedCollector<'_> { fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { match ty.kind { hir::TyKind::Path( @@ -1850,6 +1882,56 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet< // (defined above) } + hir::TyKind::Path(hir::QPath::Resolved( + None, + hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span }, + )) => { + // If this is a top level type alias attempt to "look through" it to see if the args + // are constrained, instead of assuming they are and inserting all the lifetimes. + // This is necessary for the following case: + // ``` + // type Alias<'a, T> = >::Assoc; + // fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... } + // ``` + // If we considered `'a` constrained then it would become late bound causing an error + // during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc` + // but appears in the output type `<() as Trait<'a>>::Assoc`. + + let generics = self.tcx.generics_of(alias_def); + let mut walker = ConstrainedCollectorPostAstConv { + arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(), + }; + walker.visit_ty(self.tcx.type_of(alias_def)); + + match segments.last() { + Some(hir::PathSegment { args: Some(args), .. }) => { + let tcx = self.tcx; + for constrained_arg in + args.args.iter().enumerate().flat_map(|(n, arg)| { + match walker.arg_is_constrained.get(n) { + Some(true) => Some(arg), + Some(false) => None, + None => { + tcx.sess.delay_span_bug( + *span, + format!( + "Incorrect generic arg count for alias {:?}", + alias_def + ), + ); + None + } + } + }) + { + self.visit_generic_arg(constrained_arg); + } + } + Some(_) => (), + None => bug!("Path with no segments or self type"), + } + } + hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => { // consider only the lifetimes on the final // segment; I am not sure it's even currently diff --git a/src/test/ui/issues/issue-47511.stderr b/src/test/ui/issues/issue-47511.stderr deleted file mode 100644 index 9998ee0e8d0c6..0000000000000 --- a/src/test/ui/issues/issue-47511.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/issue-47511.rs:8:15 - | -LL | fn f(_: X) -> X { - | ^ - | - = note: lifetimes appearing in an associated or opaque type are not considered constrained - = note: consider introducing a named lifetime parameter - -error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types - --> $DIR/issue-47511.rs:12:23 - | -LL | fn g<'a>(_: X<'a>) -> X<'a> { - | ^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0581`. diff --git a/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs b/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs new file mode 100644 index 0000000000000..e56a34218e231 --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs @@ -0,0 +1,24 @@ +// check-pass + +trait Gats<'a> { + type Assoc; + type Assoc2; +} + +trait Trait: for<'a> Gats<'a> { + fn foo<'a>(_: &mut >::Assoc) -> >::Assoc2; +} + +impl<'a> Gats<'a> for () { + type Assoc = &'a u32; + type Assoc2 = (); +} + +type GatsAssoc<'a, T> = >::Assoc; +type GatsAssoc2<'a, T> = >::Assoc2; + +impl Trait for () { + fn foo<'a>(_: &mut GatsAssoc<'a, Self>) -> GatsAssoc2<'a, Self> {} +} + +fn main() {} diff --git a/src/test/ui/issues/issue-47511.rs b/src/test/ui/late-bound-lifetimes/issue-47511.rs similarity index 52% rename from src/test/ui/issues/issue-47511.rs rename to src/test/ui/late-bound-lifetimes/issue-47511.rs index eb4860e75d758..7894435154082 100644 --- a/src/test/ui/issues/issue-47511.rs +++ b/src/test/ui/late-bound-lifetimes/issue-47511.rs @@ -1,9 +1,4 @@ -// check-fail -// known-bug: #47511 - -// Regression test for #47511: anonymous lifetimes can appear -// unconstrained in a return type, but only if they appear just once -// in the input, as the input to a projection. +// check-pass fn f(_: X) -> X { unimplemented!() diff --git a/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs new file mode 100644 index 0000000000000..0b331e2039f25 --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs @@ -0,0 +1,12 @@ +// ensures that we don't ICE when there are too many args supplied to the alias. + +trait Trait<'a> { + type Assoc; +} + +type Alias<'a, T> = >::Assoc; + +fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} +//~^ error: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied + +fn main() {} diff --git a/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr new file mode 100644 index 0000000000000..3704d9bb957ed --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr @@ -0,0 +1,17 @@ +error[E0107]: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/mismatched_arg_count.rs:9:29 + | +LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} + | ^^^^^ -- help: remove this lifetime argument + | | + | expected 1 lifetime argument + | +note: type alias defined here, with 1 lifetime parameter: `'a` + --> $DIR/mismatched_arg_count.rs:7:6 + | +LL | type Alias<'a, T> = >::Assoc; + | ^^^^^ -- + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. From 743da2a08cebd343d76ea63a0c392075fb10a974 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 8 Nov 2022 21:59:58 +0000 Subject: [PATCH 253/482] comment --- .../src/collect/lifetimes.rs | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index b9583bd2244b9..c64177eea3f83 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1834,6 +1834,27 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet< debug!(?late_bound); return Some(tcx.arena.alloc(late_bound)); + /// Visits a `ty::Ty` collecting information about what generic parameters are constrained. + /// + /// The visitor does not operate on `hir::Ty` so that it can be called on the rhs of a `type Alias<...> = ...;` + /// which may live in a separate crate so there would not be any hir available. Instead we use the `type_of` + /// query to obtain a `ty::Ty` which will be present even in cross crate scenarios. It also naturally + /// handles cycle detection as we go through the query system. + /// + /// This is necessary in the first place for the following case: + /// ``` + /// type Alias<'a, T> = >::Assoc; + /// fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... } + /// ``` + /// + /// If we conservatively considered `'a` unconstrained then we could break users who had written code before + /// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound + /// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc` + /// but appears in the output type `<() as Trait<'a>>::Assoc`. + /// + /// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not. + /// + /// See #100508 #85533 #47511 for additional context struct ConstrainedCollectorPostAstConv { arg_is_constrained: Box<[bool]>, } @@ -1886,17 +1907,8 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet< None, hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span }, )) => { - // If this is a top level type alias attempt to "look through" it to see if the args - // are constrained, instead of assuming they are and inserting all the lifetimes. - // This is necessary for the following case: - // ``` - // type Alias<'a, T> = >::Assoc; - // fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... } - // ``` - // If we considered `'a` constrained then it would become late bound causing an error - // during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc` - // but appears in the output type `<() as Trait<'a>>::Assoc`. - + // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider + // substs to be unconstrained. let generics = self.tcx.generics_of(alias_def); let mut walker = ConstrainedCollectorPostAstConv { arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(), From 700d1057bde56f70805daea7be2feb3ea4d5ac1b Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 8 Nov 2022 22:15:40 +0000 Subject: [PATCH 254/482] tests --- .../auxiliary/upstream_alias.rs | 5 +++++ .../ui/late-bound-lifetimes/cross_crate_alias.rs | 10 ++++++++++ .../late_bound_through_alias.rs | 16 ++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs create mode 100644 src/test/ui/late-bound-lifetimes/cross_crate_alias.rs create mode 100644 src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs diff --git a/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs b/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs new file mode 100644 index 0000000000000..5b9dc0e43087c --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs @@ -0,0 +1,5 @@ +pub trait Trait<'a> { + type Assoc; +} + +pub type Alias<'a, T> = >::Assoc; diff --git a/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs b/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs new file mode 100644 index 0000000000000..4154c27924323 --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs @@ -0,0 +1,10 @@ +// aux-build:upstream_alias.rs +// check-pass + +extern crate upstream_alias; + +fn foo<'a, T: for<'b> upstream_alias::Trait<'b>>(_: upstream_alias::Alias<'a, T>) -> &'a () { + todo!() +} + +fn main() {} diff --git a/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs b/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs new file mode 100644 index 0000000000000..91839673c1f7a --- /dev/null +++ b/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs @@ -0,0 +1,16 @@ +// check-pass + +fn f(_: X) -> X { + unimplemented!() +} + +fn g<'a>(_: X<'a>) -> X<'a> { + unimplemented!() +} + +type X<'a> = &'a (); + +fn main() { + let _: for<'a> fn(X<'a>) -> X<'a> = g; + let _: for<'a> fn(X<'a>) -> X<'a> = f; +} From 445ad2021005500bed74ade47259ce9f1f363234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRANSTETT?= Date: Mon, 21 Feb 2022 01:45:03 +0100 Subject: [PATCH 255/482] Test that target feature mix up with homogeneous floats is sound This is basically is ripoff of src/test/ui/simd/target-feature-mixup.rs but for floats and without #[repr(simd)] --- .../homogenous-floats-target-feature-mixup.rs | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/test/ui/abi/homogenous-floats-target-feature-mixup.rs diff --git a/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs b/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs new file mode 100644 index 0000000000000..d7f5e19219ed6 --- /dev/null +++ b/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs @@ -0,0 +1,192 @@ +// This test check that even if we mixup target feature of function with homogenous floats, +// the abi is sound and still produce the right answer. +// +// This is basically the same test as src/test/ui/simd/target-feature-mixup.rs but for floats and +// without #[repr(simd)] + +// run-pass +// ignore-emscripten +// ignore-sgx no processes + +#![feature(avx512_target_feature)] + +#![allow(overflowing_literals)] +#![allow(unused_variables)] + +use std::process::{Command, ExitStatus}; +use std::env; + +fn main() { + if let Some(level) = env::args().nth(1) { + return test::main(&level) + } + + match std::env::var("TARGET") { + Ok(s) => { + // Skip this tests on i586-unknown-linux-gnu where sse2 is disabled + if s.contains("i586") { + return + } + } + Err(_) => return, + } + + let me = env::current_exe().unwrap(); + for level in ["sse", "avx", "avx512"].iter() { + let status = Command::new(&me).arg(level).status().unwrap(); + if status.success() { + println!("success with {}", level); + continue + } + + // We don't actually know if our computer has the requisite target features + // for the test below. Testing for that will get added to libstd later so + // for now just assume sigill means this is a machine that can't run this test. + if is_sigill(status) { + println!("sigill with {}, assuming spurious", level); + continue + } + panic!("invalid status at {}: {}", level, status); + } +} + +#[cfg(unix)] +fn is_sigill(status: ExitStatus) -> bool { + use std::os::unix::prelude::*; + status.signal() == Some(4) +} + +#[cfg(windows)] +fn is_sigill(status: ExitStatus) -> bool { + status.code() == Some(0xc000001d) +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[allow(nonstandard_style)] +mod test { + #[derive(PartialEq, Debug, Clone, Copy)] + struct f32x2(f32, f32); + + #[derive(PartialEq, Debug, Clone, Copy)] + struct f32x4(f32, f32, f32, f32); + + #[derive(PartialEq, Debug, Clone, Copy)] + struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + + pub fn main(level: &str) { + unsafe { + main_normal(level); + main_sse(level); + if level == "sse" { + return + } + main_avx(level); + if level == "avx" { + return + } + main_avx512(level); + } + } + + macro_rules! mains { + ($( + $(#[$attr:meta])* + unsafe fn $main:ident(level: &str) { + ... + } + )*) => ($( + $(#[$attr])* + unsafe fn $main(level: &str) { + let m128 = f32x2(1., 2.); + let m256 = f32x4(3., 4., 5., 6.); + let m512 = f32x8(7., 8., 9., 10., 11., 12., 13., 14.); + assert_eq!(id_sse_128(m128), m128); + assert_eq!(id_sse_256(m256), m256); + assert_eq!(id_sse_512(m512), m512); + + if level == "sse" { + return + } + assert_eq!(id_avx_128(m128), m128); + assert_eq!(id_avx_256(m256), m256); + assert_eq!(id_avx_512(m512), m512); + + if level == "avx" { + return + } + assert_eq!(id_avx512_128(m128), m128); + assert_eq!(id_avx512_256(m256), m256); + assert_eq!(id_avx512_512(m512), m512); + } + )*) + } + + mains! { + unsafe fn main_normal(level: &str) { ... } + #[target_feature(enable = "sse2")] + unsafe fn main_sse(level: &str) { ... } + #[target_feature(enable = "avx")] + unsafe fn main_avx(level: &str) { ... } + #[target_feature(enable = "avx512bw")] + unsafe fn main_avx512(level: &str) { ... } + } + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_128(a: f32x2) -> f32x2 { + assert_eq!(a, f32x2(1., 2.)); + a.clone() + } + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_256(a: f32x4) -> f32x4 { + assert_eq!(a, f32x4(3., 4., 5., 6.)); + a.clone() + } + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_512(a: f32x8) -> f32x8 { + assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_128(a: f32x2) -> f32x2 { + assert_eq!(a, f32x2(1., 2.)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_256(a: f32x4) -> f32x4 { + assert_eq!(a, f32x4(3., 4., 5., 6.)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_512(a: f32x8) -> f32x8 { + assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_128(a: f32x2) -> f32x2 { + assert_eq!(a, f32x2(1., 2.)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_256(a: f32x4) -> f32x4 { + assert_eq!(a, f32x4(3., 4., 5., 6.)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_512(a: f32x8) -> f32x8 { + assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.)); + a.clone() + } +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +mod test { + pub fn main(level: &str) {} +} From 44f83b0189c4b9479dec2947f8695fa178dcf35c Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Tue, 25 Oct 2022 16:57:21 -0400 Subject: [PATCH 256/482] Add test case --- .../codegen/auxiliary/static_dllimport_aux.rs | 13 +++++++++++++ .../issue-81408-dllimport-thinlto-windows.rs | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/codegen/auxiliary/static_dllimport_aux.rs create mode 100644 src/test/codegen/issue-81408-dllimport-thinlto-windows.rs diff --git a/src/test/codegen/auxiliary/static_dllimport_aux.rs b/src/test/codegen/auxiliary/static_dllimport_aux.rs new file mode 100644 index 0000000000000..afb0dc42f443a --- /dev/null +++ b/src/test/codegen/auxiliary/static_dllimport_aux.rs @@ -0,0 +1,13 @@ +use std::sync::atomic::{AtomicPtr, Ordering}; + +#[inline(always)] +pub fn memrchr() { + fn detect() {} + + static CROSS_CRATE_STATIC_ITEM: AtomicPtr<()> = AtomicPtr::new(detect as *mut ()); + + unsafe { + let fun = CROSS_CRATE_STATIC_ITEM.load(Ordering::SeqCst); + std::mem::transmute::<*mut (), fn()>(fun)() + } +} diff --git a/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs new file mode 100644 index 0000000000000..e674c0561d3b8 --- /dev/null +++ b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs @@ -0,0 +1,15 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no +// only-windows +// aux-build:static_dllimport_aux.rs + +// Test that on Windows, when performing ThinLTO, we do not mark cross-crate static items with +// dllimport because lld does not fix the symbol names for us. + +extern crate static_dllimport_aux; + +// CHECK-LABEL: @{{.+}}CROSS_CRATE_STATIC_ITEM{{.+}} = +// CHECK-SAME: external dllimport local_unnamed_addr global %"{{.+}}::AtomicPtr + +pub fn main() { + static_dllimport_aux::memrchr(); +} From f395daef5b09bacd1ed83967c32dfcd18c7c59f8 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 20 Oct 2022 17:45:09 -0400 Subject: [PATCH 257/482] Fix Access Violation when using lld & ThinLTO on windows-msvc Users report an AV at runtime of the compiled binary when using lld and ThinLTO on windows-msvc. The AV occurs when accessing a static value which is defined in one crate but used in another. Based on the disassembly of the cross-crate use, it appears that the use is not correctly linked with the definition and is instead assigned a garbage pointer value. If we look at the symbol tables for each crates' obj file, we can see what is happening: *lib.obj*: ``` COFF SYMBOL TABLE ... 00E 00000000 SECT2 notype External | _ZN10reproducer7memrchr2FN17h612b61ca0e168901E ... ``` *bin.obj*: ``` COFF SYMBOL TABLE ... 010 00000000 UNDEF notype External | __imp__ZN10reproducer7memrchr2FN17h612b61ca0e168901E ... ``` The use of the symbol has the "import" style symbol name but the declaration doesn't generate any symbol with the same name. As a result, linking the files generates a warning from lld: > rust-lld: warning: bin.obj: locally defined symbol imported: reproducer::memrchr::FN::h612b61ca0e168901 (defined in lib.obj) [LNK4217] and the symbol reference remains undefined at runtime leading to the AV. To fix this, we just need to detect that we are performing ThinLTO (and thus, static linking) and omit the `dllimport` attribute on the extern item in LLVM IR. --- compiler/rustc_codegen_llvm/src/consts.rs | 4 +++- src/test/codegen/issue-81408-dllimport-thinlto-windows.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index dd3c43ba5ca7c..bf5ac4e503e3f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -19,6 +19,7 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; +use rustc_session::config::Lto; use rustc_target::abi::{ AddressSpace, Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange, }; @@ -303,7 +304,8 @@ impl<'ll> CodegenCx<'ll, '_> { // ThinLTO can't handle this workaround in all cases, so we don't // emit the attrs. Instead we make them unnecessary by disallowing // dynamic linking when linker plugin based LTO is enabled. - !self.tcx.sess.opts.cg.linker_plugin_lto.enabled(); + !self.tcx.sess.opts.cg.linker_plugin_lto.enabled() && + self.tcx.sess.lto() != Lto::Thin; // If this assertion triggers, there's something wrong with commandline // argument validation. diff --git a/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs index e674c0561d3b8..0b6ab4f7ecb3b 100644 --- a/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs +++ b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs @@ -8,7 +8,7 @@ extern crate static_dllimport_aux; // CHECK-LABEL: @{{.+}}CROSS_CRATE_STATIC_ITEM{{.+}} = -// CHECK-SAME: external dllimport local_unnamed_addr global %"{{.+}}::AtomicPtr +// CHECK-SAME: external local_unnamed_addr global %"{{.+}}AtomicPtr pub fn main() { static_dllimport_aux::memrchr(); From 1cc9764a7d41e6272daf94a5f1119ee932990df0 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 25 Oct 2022 20:47:19 +0800 Subject: [PATCH 258/482] Fix #103451, find_width_of_character_at_span return width with 1 when reaching end --- compiler/rustc_span/src/source_map.rs | 8 ++---- compiler/rustc_span/src/source_map/tests.rs | 11 +++---- src/test/ui/parser/issue-103451.rs | 5 ++++ src/test/ui/parser/issue-103451.stderr | 32 +++++++++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/parser/issue-103451.rs create mode 100644 src/test/ui/parser/issue-103451.stderr diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index f9566eeee9465..3baa2e03cbad7 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -855,7 +855,8 @@ impl SourceMap { /// Returns a new span representing the next character after the end-point of this span. /// Special cases: /// - if span is a dummy one, returns the same span - /// - if next_point reached the end of source, return span with lo = hi + /// - if next_point reached the end of source, return a span exceeding the end of source, + /// which means sm.span_to_snippet(next_point) will get `Err` /// - respect multi-byte characters pub fn next_point(&self, sp: Span) -> Span { if sp.is_dummy() { @@ -864,9 +865,6 @@ impl SourceMap { let start_of_next_point = sp.hi().0; let width = self.find_width_of_character_at_span(sp, true); - if width == 0 { - return Span::new(sp.hi(), sp.hi(), sp.ctxt(), None); - } // If the width is 1, then the next span should only contain the next char besides current ending. // However, in the case of a multibyte character, where the width != 1, the next span should // span multiple bytes to include the whole character. @@ -938,7 +936,7 @@ impl SourceMap { // Ensure indexes are also not malformed. if start_index > end_index || end_index > source_len - 1 { debug!("find_width_of_character_at_span: source indexes are malformed"); - return 0; + return 1; } let src = local_begin.sf.external_src.borrow(); diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 1fd81018fa05c..3cab59e8dbe6c 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -511,16 +511,17 @@ fn test_next_point() { assert_eq!(span.lo().0, 4); assert_eq!(span.hi().0, 5); - // A non-empty span at the last byte should advance to create an empty - // span pointing at the end of the file. + // Reaching to the end of file, return a span that will get error with `span_to_snippet` let span = Span::with_root_ctxt(BytePos(4), BytePos(5)); let span = sm.next_point(span); assert_eq!(span.lo().0, 5); - assert_eq!(span.hi().0, 5); + assert_eq!(span.hi().0, 6); + assert!(sm.span_to_snippet(span).is_err()); - // Empty span pointing just past the last byte. + // Reaching to the end of file, return a span that will get error with `span_to_snippet` let span = Span::with_root_ctxt(BytePos(5), BytePos(5)); let span = sm.next_point(span); assert_eq!(span.lo().0, 5); - assert_eq!(span.hi().0, 5); + assert_eq!(span.hi().0, 6); + assert!(sm.span_to_snippet(span).is_err()); } diff --git a/src/test/ui/parser/issue-103451.rs b/src/test/ui/parser/issue-103451.rs new file mode 100644 index 0000000000000..1fdb001488155 --- /dev/null +++ b/src/test/ui/parser/issue-103451.rs @@ -0,0 +1,5 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected value, found struct `R` +struct R { } +struct S { + x: [u8; R diff --git a/src/test/ui/parser/issue-103451.stderr b/src/test/ui/parser/issue-103451.stderr new file mode 100644 index 0000000000000..eb3c92fb43d9b --- /dev/null +++ b/src/test/ui/parser/issue-103451.stderr @@ -0,0 +1,32 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-103451.rs:5:15 + | +LL | struct S { + | - unclosed delimiter +LL | x: [u8; R + | - ^ + | | + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-103451.rs:5:15 + | +LL | struct S { + | - unclosed delimiter +LL | x: [u8; R + | - ^ + | | + | unclosed delimiter + +error[E0423]: expected value, found struct `R` + --> $DIR/issue-103451.rs:5:13 + | +LL | struct R { } + | ------------ `R` defined here +LL | struct S { +LL | x: [u8; R + | ^ help: use struct literal syntax instead: `R {}` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0423`. From c641bde742f341baf88f9b4e01aeba118350a77a Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Wed, 26 Oct 2022 10:42:05 +0800 Subject: [PATCH 259/482] first move on a nested span_label Apply suggestions from code review Co-authored-by: David Wood --- .../src/diagnostics/conflict_errors.rs | 14 ++++++--- .../rustc_borrowck/src/diagnostics/mod.rs | 20 +++++++++++++ .../rustc_borrowck/src/session_diagnostics.rs | 30 +++++++++++++++++++ .../locales/en-US/borrowck.ftl | 12 ++++++++ 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8987a51757cd5..7f26e970e3094 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -724,13 +724,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - - borrow_spans.var_span_label( + borrow_spans.var_subdiag( &mut err, - { + |var_span| { + use crate::session_diagnostics::CaptureVarCause::*; let place = &borrow.borrowed_place; let desc_place = self.describe_any_place(place.as_ref()); - format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe()) + match borrow_spans { + UseSpans::ClosureUse { generator_kind, .. } => match generator_kind { + Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, + None => BorrowUsePlaceClosure { place: desc_place, var_span }, + }, + _ => BorrowUsePlace { place: desc_place, var_span }, + } }, "mutable", ); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 534d9ecae6e6f..61518378e3d0c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -623,6 +623,26 @@ impl UseSpans<'_> { } } + /// Add a subdiagnostic to the use of the captured variable, if it exists. + pub(super) fn var_subdiag( + self, + err: &mut Diagnostic, + f: impl Fn(Span) -> crate::session_diagnostics::CaptureVarCause, + kind_desc: impl Into, + ) { + if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self { + if capture_kind_span == path_span { + err.subdiagnostic(f(capture_kind_span)); + } else { + err.subdiagnostic(crate::session_diagnostics::CaptureVarKind { + kind_desc: kind_desc.into(), + kind_span: capture_kind_span, + }); + err.subdiagnostic(f(path_span)); + } + } + } + /// Returns `false` if this place is not used in a closure. pub(super) fn for_closure(&self) -> bool { match *self { diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index fe24f85fae10a..824f20a31bb09 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -148,3 +148,33 @@ pub(crate) enum RequireStaticErr { multi_span: MultiSpan, }, } + +#[derive(Subdiagnostic)] +#[label(borrowck_capture_kind_label)] +pub(crate) struct CaptureVarKind { + pub kind_desc: String, + #[primary_span] + pub kind_span: Span, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarCause { + #[label(borrowck_var_borrow_by_use_place)] + BorrowUsePlace { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_borrow_by_use_place_in_generator)] + BorrowUsePlaceGenerator { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_borrow_by_use_place_in_closure)] + BorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 67f2156f32e50..80fc4c6e4f5d3 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -58,3 +58,15 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement + +borrowck_capture_kind_label = + capture is {$kind_desc} because of use here + +borrowck_var_borrow_by_use_place_in_generator = + borrow occurs due to use of {$place} in closure in generator + +borrowck_var_borrow_by_use_place_in_closure = + borrow occurs due to use of {$place} in closure + +borrowck_var_borrow_by_use_place = + borrow occurs due to use of {$place} From 65417fda7a6ced3428cd7dc1d035fc88cea98e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Sat, 5 Nov 2022 12:19:55 +0100 Subject: [PATCH 260/482] Update several crates for improved support of the new targets This helps with `*-windows-gnullvm` targets --- Cargo.lock | 64 +++++++++++-------- compiler/rustc_data_structures/Cargo.toml | 2 +- src/bootstrap/Cargo.lock | 75 ++++++++++++++++++++--- src/bootstrap/Cargo.toml | 2 +- 4 files changed, 107 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28684a310a3c7..544cb4faef222 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2496,7 +2496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.3", + "parking_lot_core 0.9.4", ] [[package]] @@ -2515,15 +2515,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -2748,9 +2748,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.16" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" dependencies = [ "cc", ] @@ -4651,9 +4651,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stacker" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90939d5171a4420b3ff5fbc8954d641e7377335454c259dcb80786f3f21dc9b4" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" dependencies = [ "cc", "cfg-if 1.0.0", @@ -5473,17 +5473,25 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.28.0" @@ -5492,9 +5500,9 @@ checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" @@ -5504,9 +5512,9 @@ checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" @@ -5516,9 +5524,9 @@ checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" @@ -5528,9 +5536,15 @@ checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" @@ -5540,9 +5554,9 @@ checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "xattr" diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 5152d5ab0465c..5afce15e26bfc 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -23,7 +23,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] } stable_deref_trait = "1.0.0" -stacker = "0.1.14" +stacker = "0.1.15" tempfile = "3.2" thin-vec = "0.2.9" tracing = "0.1" diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index baecca44cd987..e1a108cea9574 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -224,13 +224,13 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11dcc7e4d79a8c89b9ab4c6f5c30b1fc4a83c420792da3542fd31179ed5f517" +checksum = "0c93a581058d957dc4176875aad04f82f81613e6611d64aa1a9c755bdfb16711" dependencies = [ "cfg-if", "rustix", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -528,7 +528,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -721,43 +721,100 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "xattr" version = "0.2.3" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 95e711737738a..f74738437ea3a 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -36,7 +36,7 @@ test = false [dependencies] cmake = "0.1.38" -fd-lock = "3.0.6" +fd-lock = "3.0.7" filetime = "0.2" getopts = "0.2.19" cc = "1.0.69" From 43026f6d5d996a7880e9f75308452192c7069276 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 1 Nov 2022 01:34:59 +0000 Subject: [PATCH 261/482] Check for substs compatibility for RPITITs --- .../src/traits/project.rs | 18 +++++++++++++++--- .../impl-trait/in-trait/generics-mismatch.rs | 17 +++++++++++++++++ .../in-trait/generics-mismatch.stderr | 12 ++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/impl-trait/in-trait/generics-mismatch.rs create mode 100644 src/test/ui/impl-trait/in-trait/generics-mismatch.stderr diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7f829e46bbb1b..7fe44962d8432 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2187,7 +2187,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( // Verify that the trait item and its implementation have compatible substs lists fn check_substs_compatible<'tcx>( tcx: TyCtxt<'tcx>, - assoc_ty: &ty::AssocItem, + assoc_item: &ty::AssocItem, substs: ty::SubstsRef<'tcx>, ) -> bool { fn check_substs_compatible_inner<'tcx>( @@ -2219,7 +2219,10 @@ fn check_substs_compatible<'tcx>( true } - check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice()) + let generics = tcx.generics_of(assoc_item.def_id); + // Chop off any additional substs (RPITIT) substs + let substs = &substs[0..generics.count().min(substs.len())]; + check_substs_compatible_inner(tcx, generics, substs) } fn confirm_impl_trait_in_trait_candidate<'tcx>( @@ -2248,12 +2251,21 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( }; } - let impl_fn_def_id = leaf_def.item.def_id; // Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque}, // since `data.substs` are the impl substs. let impl_fn_substs = obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs); + if !check_substs_compatible(tcx, &leaf_def.item, impl_fn_substs) { + let err = tcx.ty_error_with_message( + obligation.cause.span, + "impl method and trait method have different parameters", + ); + return Progress { term: err.into(), obligations }; + } + + let impl_fn_def_id = leaf_def.item.def_id; + let cause = ObligationCause::new( obligation.cause.span, obligation.cause.body_id, diff --git a/src/test/ui/impl-trait/in-trait/generics-mismatch.rs b/src/test/ui/impl-trait/in-trait/generics-mismatch.rs new file mode 100644 index 0000000000000..cc0fc720ebbfd --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/generics-mismatch.rs @@ -0,0 +1,17 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +struct U; + +trait Foo { + fn bar(&self) -> impl Sized; +} + +impl Foo for U { + fn bar(&self) {} + //~^ ERROR method `bar` has 1 type parameter but its trait declaration has 0 type parameters +} + +fn main() { + U.bar(); +} diff --git a/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr b/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr new file mode 100644 index 0000000000000..cd42683e0224d --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr @@ -0,0 +1,12 @@ +error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/generics-mismatch.rs:11:12 + | +LL | fn bar(&self) -> impl Sized; + | - expected 0 type parameters +... +LL | fn bar(&self) {} + | ^ found 1 type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0049`. From c038f3b23c6297eb9166e5f105c7e9e17998ec83 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 1 Nov 2022 01:36:50 +0000 Subject: [PATCH 262/482] Remap RPITIT substs properly --- .../src/traits/project.rs | 7 ++++++ .../in-trait/specialization-substs-remap.rs | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7fe44962d8432..572f82117cc0e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2255,6 +2255,13 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( // since `data.substs` are the impl substs. let impl_fn_substs = obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs); + let impl_fn_substs = translate_substs( + selcx.infcx(), + obligation.param_env, + data.impl_def_id, + impl_fn_substs, + leaf_def.defining_node, + ); if !check_substs_compatible(tcx, &leaf_def.item, impl_fn_substs) { let err = tcx.ty_error_with_message( diff --git a/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs b/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs new file mode 100644 index 0000000000000..c9ee877db8ec5 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(specialization)] +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn bar(&self) -> impl Sized; +} + +impl Foo for U +where + U: Copy, +{ + fn bar(&self) -> U { + *self + } +} + +impl Foo for i32 {} + +fn main() { + let _: i32 = 1i32.bar(); +} From 6dd8f670df823b51a32196672505dd6070cf28b9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 1 Nov 2022 01:42:47 +0000 Subject: [PATCH 263/482] Fix ICE in default impl error reporting --- compiler/rustc_middle/src/ty/error.rs | 4 ++- .../in-trait/specialization-broken.rs | 26 +++++++++++++++++++ .../in-trait/specialization-broken.stderr | 23 ++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/impl-trait/in-trait/specialization-broken.rs create mode 100644 src/test/ui/impl-trait/in-trait/specialization-broken.stderr diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 4e6cdb786025e..dc13374f992eb 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -430,7 +430,9 @@ impl<'tcx> TyCtxt<'tcx> { (ty::Projection(_), ty::Projection(_)) => { diag.note("an associated type was expected, but a different one was found"); } - (ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) => { + (ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) + if self.def_kind(proj.item_def_id) != DefKind::ImplTraitPlaceholder => + { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { diff --git a/src/test/ui/impl-trait/in-trait/specialization-broken.rs b/src/test/ui/impl-trait/in-trait/specialization-broken.rs new file mode 100644 index 0000000000000..9d27d3710a601 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/specialization-broken.rs @@ -0,0 +1,26 @@ +// FIXME(compiler-errors): I'm not exactly sure if this is expected to pass or not. +// But we fixed an ICE anyways. + +#![feature(specialization)] +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn bar(&self) -> impl Sized; +} + +default impl Foo for U +where + U: Copy, +{ + fn bar(&self) -> U { + //~^ ERROR method `bar` has an incompatible type for trait + *self + } +} + +impl Foo for i32 {} + +fn main() { + 1i32.bar(); +} diff --git a/src/test/ui/impl-trait/in-trait/specialization-broken.stderr b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr new file mode 100644 index 0000000000000..a30e6346b2927 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr @@ -0,0 +1,23 @@ +error[E0053]: method `bar` has an incompatible type for trait + --> $DIR/specialization-broken.rs:16:22 + | +LL | default impl Foo for U + | - this type parameter +... +LL | fn bar(&self) -> U { + | ^ + | | + | expected associated type, found type parameter `U` + | help: change the output type to match the trait: `impl Sized` + | +note: type in trait + --> $DIR/specialization-broken.rs:9:22 + | +LL | fn bar(&self) -> impl Sized; + | ^^^^^^^^^^ + = note: expected fn pointer `fn(&U) -> impl Sized` + found fn pointer `fn(&U) -> U` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. From 61192b55ad10a8c4bd9116b27c3a1e305a9219ff Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 9 Nov 2022 02:08:22 +0000 Subject: [PATCH 264/482] Use `nominal_obligations_without_const` in wf for FnDef --- compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- src/test/ui/consts/issue-104155.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/issue-104155.rs diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8908fe230b0eb..fc0a9f6900336 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -547,7 +547,7 @@ impl<'tcx> WfPredicates<'tcx> { } ty::FnDef(did, substs) => { - let obligations = self.nominal_obligations(did, substs); + let obligations = self.nominal_obligations_without_const(did, substs); self.out.extend(obligations); } diff --git a/src/test/ui/consts/issue-104155.rs b/src/test/ui/consts/issue-104155.rs new file mode 100644 index 0000000000000..1cc8f81b0d257 --- /dev/null +++ b/src/test/ui/consts/issue-104155.rs @@ -0,0 +1,5 @@ +// check-pass +const _: () = core::mem::forget(Box::::default); +const _: () = core::mem::forget(|| Box::::default()); + +fn main() {} From 51ab862c03efe46370f80f26503876232afcfd37 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 1 Oct 2022 23:05:32 -0500 Subject: [PATCH 265/482] More build-manifest docs --- src/tools/build-manifest/README.md | 32 +++++++++++++++++----------- src/tools/build-manifest/src/main.rs | 6 +----- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 44c96f31d0ba8..b5c6371e553a5 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -1,7 +1,16 @@ # build-manifest -This tool generates the manifests uploaded to static.rust-lang.org and used by -rustup. The tool is invoked by the bootstrap tool. +This tool generates the manifests uploaded to static.rust-lang.org and used by rustup. +You can see a full list of all manifests at . + +This gets called by `promote-release` via `x.py dist hash-and-sign`. + +## Adding a new component + +There are several steps involved here. +1. Add a new `Step` to `dist.rs`. This should usually be named after the filename of the uploaded tarball. See https://github.com/rust-lang/rust/pull/101799/files#diff-2c56335faa24486df09ba392d8900c57e2fac4633e1f7038469bcf9ed3feb871 for an example. + a. If appropriate, call `tarball.is_preview(true)` for the component. +3. Add a new `PkgType` to build-manifest. Fix all the compile errors as appropriate. ## Testing changes locally @@ -9,19 +18,16 @@ In order to test the changes locally you need to have a valid dist directory available locally. If you don't want to build all the compiler, you can easily create one from the nightly artifacts with: -``` -#!/bin/bash -for cmpn in rust rustc rust-std rust-docs cargo; do - wget https://static.rust-lang.org/dist/${cmpn}-nightly-x86_64-unknown-linux-gnu.tar.gz +```sh +for component in rust rustc rust-std rust-docs cargo; do + wget -P build/dist https://static.rust-lang.org/dist/${component}-nightly-x86_64-unknown-linux-gnu.tar.gz done ``` -Then, you can generate the manifest and all the packages from `path/to/dist` to -`path/to/output` with: +Then, you can generate the manifest and all the packages from `build/dist` to +`build/manifest` with: +```sh +mkdir -p build/manifest +cargo +nightly run -p build-manifest build/dist build/manifest 1970-01-01 http://example.com nightly ``` -$ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com CHANNEL -``` - -Remember to replace `CHANNEL` with the channel you produced dist artifacts of -and `VERSION` with the current Rust version. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index b0006cb90bdd6..983f4ca713882 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,8 +1,4 @@ -//! Build a dist manifest, hash and sign everything. -//! This gets called by `promote-release` -//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release) -//! via `x.py dist hash-and-sign`; the cmdline arguments are set up -//! by rustbuild (in `src/bootstrap/dist.rs`). +#![doc = include_str!("../README.md")] mod checksum; mod manifest; From af0946d9c8cd840d25eddec18e17b00a1ac75c7b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 1 Oct 2022 23:42:21 -0500 Subject: [PATCH 266/482] build-manifest: Add a macro that makes it impossible to typo `-preview`, or have a mismatch between parsing and stringifying --- src/tools/build-manifest/src/versions.rs | 84 +++++++++++------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 0186194a41f55..61e8825753c5d 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -8,58 +8,48 @@ use tar::Archive; const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; -#[derive(Debug, Hash, Eq, PartialEq, Clone)] -pub(crate) enum PkgType { - Rust, - RustSrc, - Rustc, - Cargo, - Rls, - RustAnalyzer, - Clippy, - Rustfmt, - LlvmTools, - Miri, - JsonDocs, - Other(String), -} - -impl PkgType { - pub(crate) fn from_component(component: &str) -> Self { - match component { - "rust" => PkgType::Rust, - "rust-src" => PkgType::RustSrc, - "rustc" => PkgType::Rustc, - "cargo" => PkgType::Cargo, - "rls" | "rls-preview" => PkgType::Rls, - "rust-analyzer" | "rust-analyzer-preview" => PkgType::RustAnalyzer, - "clippy" | "clippy-preview" => PkgType::Clippy, - "rustfmt" | "rustfmt-preview" => PkgType::Rustfmt, - "llvm-tools" | "llvm-tools-preview" => PkgType::LlvmTools, - "miri" | "miri-preview" => PkgType::Miri, - "rust-docs-json" | "rust-docs-json-preview" => PkgType::JsonDocs, - other => PkgType::Other(other.into()), +macro_rules! pkg_type { + ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? ),+ $(,)? ) => { + #[derive(Debug, Hash, Eq, PartialEq, Clone)] + pub(crate) enum PkgType { + $($variant,)+ + Other(String), } - } - /// First part of the tarball name. - fn tarball_component_name(&self) -> &str { - match self { - PkgType::Rust => "rust", - PkgType::RustSrc => "rust-src", - PkgType::Rustc => "rustc", - PkgType::Cargo => "cargo", - PkgType::Rls => "rls", - PkgType::RustAnalyzer => "rust-analyzer", - PkgType::Clippy => "clippy", - PkgType::Rustfmt => "rustfmt", - PkgType::LlvmTools => "llvm-tools", - PkgType::Miri => "miri", - PkgType::JsonDocs => "rust-docs-json", - PkgType::Other(component) => component, + impl PkgType { + pub(crate) fn from_component(component: &str) -> Self { + match component { + $( $component $( | concat!($($is_preview)? $component, "-preview") )? => PkgType::$variant,)+ + _ => PkgType::Other(component.into()), + } + } + + /// First part of the tarball name. + fn tarball_component_name(&self) -> &str { + match self { + $( PkgType::$variant => $component,)+ + PkgType::Other(component) => component, + } + } } } +} +pkg_type! { + Rust = "rust", + RustSrc = "rust-src", + Rustc = "rustc", + Cargo = "cargo", + Rls = "rls"; preview = true, + RustAnalyzer = "rust-analyzer"; preview = true, + Clippy = "clippy"; preview = true, + Rustfmt = "rustfmt"; preview = true, + LlvmTools = "llvm-tools"; preview = true, + Miri = "miri"; preview = true, + JsonDocs = "rust-docs-json"; preview = true, +} + +impl PkgType { /// Whether this package has the same version as Rust itself, or has its own `version` and /// `git-commit-hash` files inside the tarball. fn should_use_rust_version(&self) -> bool { From 4c15dfe8b2592890c25c64aa59860b0b8e3ce942 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Oct 2022 00:25:08 -0500 Subject: [PATCH 267/482] Use `PkgType` to determine which packages to add to the manifest Previously, these had to be hard-coded (i.e. specified in both `PkgType` and `fn package`). Now they only have to be specified in `PkgType`. --- src/tools/build-manifest/src/main.rs | 35 +++++------- src/tools/build-manifest/src/versions.rs | 70 ++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 983f4ca713882..726275988e095 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -283,28 +283,15 @@ impl Builder { } fn add_packages_to(&mut self, manifest: &mut Manifest) { - macro_rules! package { - ($name:expr, $targets:expr) => { - self.package($name, &mut manifest.pkg, $targets, &[]) - }; + for pkg in PkgType::all() { + let fallback = if pkg.use_docs_fallback() { DOCS_FALLBACK } else { &[] }; + self.package( + &pkg.manifest_component_name(), + &mut manifest.pkg, + pkg.targets(), + fallback, + ); } - package!("rustc", HOSTS); - package!("rustc-dev", HOSTS); - package!("reproducible-artifacts", HOSTS); - package!("rustc-docs", HOSTS); - package!("cargo", HOSTS); - package!("rust-mingw", MINGW); - package!("rust-std", TARGETS); - self.package("rust-docs", &mut manifest.pkg, HOSTS, DOCS_FALLBACK); - self.package("rust-docs-json-preview", &mut manifest.pkg, HOSTS, DOCS_FALLBACK); - package!("rust-src", &["*"]); - package!("rls-preview", HOSTS); - package!("rust-analyzer-preview", HOSTS); - package!("clippy-preview", HOSTS); - package!("miri-preview", HOSTS); - package!("rustfmt-preview", HOSTS); - package!("rust-analysis", TARGETS); - package!("llvm-tools-preview", TARGETS); } fn add_artifacts_to(&mut self, manifest: &mut Manifest) { @@ -500,6 +487,12 @@ impl Builder { targets: &[&str], fallback: &[(&str, &str)], ) { + if pkgname == "rust" { + // This is handled specially by `rust_package` later. + // Order is important, so don't call `rust_package` here. + return; + } + let version_info = self .versions .version(&PkgType::from_component(pkgname)) diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 61e8825753c5d..5aef232d7abf4 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -17,6 +17,13 @@ macro_rules! pkg_type { } impl PkgType { + fn is_preview(&self) -> bool { + match self { + $( $( $($is_preview)? PkgType::$variant => true, )? )+ + _ => false, + } + } + pub(crate) fn from_component(component: &str) -> Self { match component { $( $component $( | concat!($($is_preview)? $component, "-preview") )? => PkgType::$variant,)+ @@ -31,6 +38,11 @@ macro_rules! pkg_type { PkgType::Other(component) => component, } } + + /// Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate. + pub(crate) fn all() -> &'static [PkgType] { + &[ $(PkgType::$variant),+ ] + } } } } @@ -39,7 +51,14 @@ pkg_type! { Rust = "rust", RustSrc = "rust-src", Rustc = "rustc", + RustcDev = "rustc-dev", + RustcDocs = "rustc-docs", + ReproducibleArtifacts = "reproducible-artifacts", + RustMingw = "rust-mingw", + RustStd = "rust-std", Cargo = "cargo", + HtmlDocs = "rust-docs", + RustAnalysis = "rust-analysis", Rls = "rls"; preview = true, RustAnalyzer = "rust-analyzer"; preview = true, Clippy = "clippy"; preview = true, @@ -50,6 +69,15 @@ pkg_type! { } impl PkgType { + // / Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate. + pub(crate) fn manifest_component_name(&self) -> String { + if self.is_preview() { + format!("{}-preview", self.tarball_component_name()) + } else { + self.tarball_component_name().to_string() + } + } + /// Whether this package has the same version as Rust itself, or has its own `version` and /// `git-commit-hash` files inside the tarball. fn should_use_rust_version(&self) -> bool { @@ -63,17 +91,59 @@ impl PkgType { PkgType::Miri => false, PkgType::Rust => true, + PkgType::RustStd => true, PkgType::RustSrc => true, PkgType::Rustc => true, PkgType::JsonDocs => true, + PkgType::HtmlDocs => true, + PkgType::RustcDev => true, + PkgType::RustcDocs => true, + PkgType::ReproducibleArtifacts => true, + PkgType::RustMingw => true, + PkgType::RustAnalysis => true, PkgType::Other(_) => true, } } + pub(crate) fn targets(&self) -> &[&str] { + use crate::{HOSTS, MINGW, TARGETS}; + use PkgType::*; + + match self { + Rust => HOSTS, // doesn't matter in practice, but return something to avoid panicking + Rustc => HOSTS, + RustcDev => HOSTS, + ReproducibleArtifacts => HOSTS, + RustcDocs => HOSTS, + Cargo => HOSTS, + RustMingw => MINGW, + RustStd => TARGETS, + HtmlDocs => HOSTS, + JsonDocs => HOSTS, + RustSrc => &["*"], + Rls => HOSTS, + RustAnalyzer => HOSTS, + Clippy => HOSTS, + Miri => HOSTS, + Rustfmt => HOSTS, + RustAnalysis => TARGETS, + LlvmTools => TARGETS, + Other(pkg) => panic!("add {pkg} to the list of known `PkgType`s"), + } + } + /// Whether this package is target-independent or not. fn target_independent(&self) -> bool { *self == PkgType::RustSrc } + + /// Whether to package these target-specific docs for another similar target. + pub(crate) fn use_docs_fallback(&self) -> bool { + match self { + PkgType::JsonDocs | PkgType::HtmlDocs => true, + _ => false, + } + } } #[derive(Debug, Default, Clone)] From 7cb8ebd679f9add968ff31dd25627ac5ddd46a07 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Oct 2022 00:28:25 -0500 Subject: [PATCH 268/482] Use `PkgType::is_preview` to determine whether to add a rename to the manifest This caught a missing preview rename for `llvm-tools`. --- src/tools/build-manifest/src/main.rs | 11 +++++------ src/tools/build-manifest/src/versions.rs | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 726275988e095..f09e1e5718ee3 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -365,12 +365,11 @@ impl Builder { let mut rename = |from: &str, to: &str| { manifest.renames.insert(from.to_owned(), Rename { to: to.to_owned() }) }; - rename("rls", "rls-preview"); - rename("rustfmt", "rustfmt-preview"); - rename("clippy", "clippy-preview"); - rename("miri", "miri-preview"); - rename("rust-docs-json", "rust-docs-json-preview"); - rename("rust-analyzer", "rust-analyzer-preview"); + for pkg in PkgType::all() { + if pkg.is_preview() { + rename(pkg.tarball_component_name(), &pkg.manifest_component_name()); + } + } } fn rust_package(&mut self, manifest: &Manifest) -> Package { diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 5aef232d7abf4..967433a86ad3e 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -17,7 +17,7 @@ macro_rules! pkg_type { } impl PkgType { - fn is_preview(&self) -> bool { + pub(crate) fn is_preview(&self) -> bool { match self { $( $( $($is_preview)? PkgType::$variant => true, )? )+ _ => false, @@ -32,7 +32,7 @@ macro_rules! pkg_type { } /// First part of the tarball name. - fn tarball_component_name(&self) -> &str { + pub(crate) fn tarball_component_name(&self) -> &str { match self { $( PkgType::$variant => $component,)+ PkgType::Other(component) => component, From 166abd3515d31f79f758726696071ca5bf757431 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 2 Oct 2022 00:48:50 -0500 Subject: [PATCH 269/482] Use an exhaustive match in `target_host_combination`. This avoids bugs where components are added to one part of the manifest but not another. --- src/tools/build-manifest/src/main.rs | 83 ++++++++++++++---------- src/tools/build-manifest/src/versions.rs | 3 +- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index f09e1e5718ee3..efe4412726a9a 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -401,42 +401,55 @@ impl Builder { let mut components = Vec::new(); let mut extensions = Vec::new(); - let host_component = |pkg| Component::from_str(pkg, host); - - // rustc/rust-std/cargo/docs are all required, - // and so is rust-mingw if it's available for the target. - components.extend(vec![ - host_component("rustc"), - host_component("rust-std"), - host_component("cargo"), - host_component("rust-docs"), - ]); - if host.contains("pc-windows-gnu") { - components.push(host_component("rust-mingw")); - } + let host_component = |pkg: &_| Component::from_str(pkg, host); - // Tools are always present in the manifest, - // but might be marked as unavailable if they weren't built. - extensions.extend(vec![ - host_component("clippy-preview"), - host_component("miri-preview"), - host_component("rls-preview"), - host_component("rust-analyzer-preview"), - host_component("rustfmt-preview"), - host_component("llvm-tools-preview"), - host_component("rust-analysis"), - host_component("rust-docs-json-preview"), - ]); - - extensions.extend( - TARGETS - .iter() - .filter(|&&target| target != host) - .map(|target| Component::from_str("rust-std", target)), - ); - extensions.extend(HOSTS.iter().map(|target| Component::from_str("rustc-dev", target))); - extensions.extend(HOSTS.iter().map(|target| Component::from_str("rustc-docs", target))); - extensions.push(Component::from_str("rust-src", "*")); + for pkg in PkgType::all() { + match pkg { + // rustc/rust-std/cargo/docs are all required + PkgType::Rustc | PkgType::Cargo | PkgType::HtmlDocs => { + components.push(host_component(&pkg.manifest_component_name())); + } + PkgType::RustStd => { + components.push(host_component(&pkg.manifest_component_name())); + extensions.extend( + TARGETS.iter().filter(|&&target| target != host).map(|target| { + Component::from_str(&pkg.manifest_component_name(), target) + }), + ); + } + // so is rust-mingw if it's available for the target + PkgType::RustMingw => { + if host.contains("pc-windows-gnu") { + components.push(host_component("rust-mingw")); + } + } + // Tools are always present in the manifest, + // but might be marked as unavailable if they weren't built. + PkgType::Clippy + | PkgType::Miri + | PkgType::Rls + | PkgType::RustAnalyzer + | PkgType::Rustfmt + | PkgType::LlvmTools + | PkgType::RustAnalysis + | PkgType::JsonDocs => { + extensions.push(host_component(&pkg.manifest_component_name())); + } + PkgType::RustcDev | PkgType::RustcDocs => { + extensions.extend( + HOSTS.iter().map(|target| { + Component::from_str(&pkg.manifest_component_name(), target) + }), + ); + } + PkgType::RustSrc => { + extensions.push(Component::from_str(&pkg.manifest_component_name(), "*")); + } + PkgType::Rust | PkgType::Other(_) => {} + // FIXME: is this correct? maybe we should add it so rustup knows about it ... + PkgType::ReproducibleArtifacts => {} + } + } // If the components/extensions don't actually exist for this // particular host/target combination then nix it entirely from our diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 967433a86ad3e..cea34905db6aa 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -39,7 +39,6 @@ macro_rules! pkg_type { } } - /// Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate. pub(crate) fn all() -> &'static [PkgType] { &[ $(PkgType::$variant),+ ] } @@ -69,7 +68,7 @@ pkg_type! { } impl PkgType { - // / Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate. + /// Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate. pub(crate) fn manifest_component_name(&self) -> String { if self.is_preview() { format!("{}-preview", self.tarball_component_name()) From 3c9572e5c270ff9eb9061bd8c929c7a526a29288 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 27 Oct 2022 12:07:34 -0500 Subject: [PATCH 270/482] Use PkgType in more places In particular, this avoids serializing and parsing the pkg to a string, which allows getting rid of `PkgType::Other` altogether --- src/tools/build-manifest/README.md | 1 + src/tools/build-manifest/src/main.rs | 57 ++++++++++-------------- src/tools/build-manifest/src/manifest.rs | 5 ++- src/tools/build-manifest/src/versions.rs | 11 ----- 4 files changed, 27 insertions(+), 47 deletions(-) diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index b5c6371e553a5..40dce38742a14 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -2,6 +2,7 @@ This tool generates the manifests uploaded to static.rust-lang.org and used by rustup. You can see a full list of all manifests at . +This listing is updated by every 7 days. This gets called by `promote-release` via `x.py dist hash-and-sign`. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index efe4412726a9a..ebc220cfce590 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -180,7 +180,7 @@ static PKG_INSTALLERS: &[&str] = &["x86_64-apple-darwin", "aarch64-apple-darwin" static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"]; -static NIGHTLY_ONLY_COMPONENTS: &[&str] = &["miri-preview", "rust-docs-json-preview"]; +static NIGHTLY_ONLY_COMPONENTS: &[PkgType] = &[PkgType::Miri, PkgType::JsonDocs]; macro_rules! t { ($e:expr) => { @@ -285,12 +285,7 @@ impl Builder { fn add_packages_to(&mut self, manifest: &mut Manifest) { for pkg in PkgType::all() { let fallback = if pkg.use_docs_fallback() { DOCS_FALLBACK } else { &[] }; - self.package( - &pkg.manifest_component_name(), - &mut manifest.pkg, - pkg.targets(), - fallback, - ); + self.package(pkg, &mut manifest.pkg, fallback); } } @@ -401,26 +396,27 @@ impl Builder { let mut components = Vec::new(); let mut extensions = Vec::new(); - let host_component = |pkg: &_| Component::from_str(pkg, host); + let host_component = |pkg: &_| Component::from_pkg(pkg, host); for pkg in PkgType::all() { match pkg { // rustc/rust-std/cargo/docs are all required PkgType::Rustc | PkgType::Cargo | PkgType::HtmlDocs => { - components.push(host_component(&pkg.manifest_component_name())); + components.push(host_component(pkg)); } PkgType::RustStd => { - components.push(host_component(&pkg.manifest_component_name())); + components.push(host_component(pkg)); extensions.extend( - TARGETS.iter().filter(|&&target| target != host).map(|target| { - Component::from_str(&pkg.manifest_component_name(), target) - }), + TARGETS + .iter() + .filter(|&&target| target != host) + .map(|target| Component::from_pkg(pkg, target)), ); } // so is rust-mingw if it's available for the target PkgType::RustMingw => { if host.contains("pc-windows-gnu") { - components.push(host_component("rust-mingw")); + components.push(host_component(pkg)); } } // Tools are always present in the manifest, @@ -433,20 +429,16 @@ impl Builder { | PkgType::LlvmTools | PkgType::RustAnalysis | PkgType::JsonDocs => { - extensions.push(host_component(&pkg.manifest_component_name())); + extensions.push(host_component(pkg)); } PkgType::RustcDev | PkgType::RustcDocs => { - extensions.extend( - HOSTS.iter().map(|target| { - Component::from_str(&pkg.manifest_component_name(), target) - }), - ); + extensions.extend(HOSTS.iter().map(|target| Component::from_pkg(pkg, target))); } PkgType::RustSrc => { - extensions.push(Component::from_str(&pkg.manifest_component_name(), "*")); + extensions.push(Component::from_pkg(pkg, "*")); } - PkgType::Rust | PkgType::Other(_) => {} - // FIXME: is this correct? maybe we should add it so rustup knows about it ... + PkgType::Rust => {} + // NOTE: this is intentional, these artifacts aren't intended to be used with rustup PkgType::ReproducibleArtifacts => {} } } @@ -494,31 +486,27 @@ impl Builder { fn package( &mut self, - pkgname: &str, + pkg: &PkgType, dst: &mut BTreeMap, - targets: &[&str], fallback: &[(&str, &str)], ) { - if pkgname == "rust" { + if *pkg == PkgType::Rust { // This is handled specially by `rust_package` later. // Order is important, so don't call `rust_package` here. return; } - let version_info = self - .versions - .version(&PkgType::from_component(pkgname)) - .expect("failed to load package version"); + let version_info = self.versions.version(&pkg).expect("failed to load package version"); let mut is_present = version_info.present; // Never ship nightly-only components for other trains. - if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkgname) { + if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkg) { is_present = false; // Pretend the component is entirely missing. } macro_rules! tarball_name { ($target_name:expr) => { - self.versions.tarball_name(&PkgType::from_component(pkgname), $target_name).unwrap() + self.versions.tarball_name(pkg, $target_name).unwrap() }; } let mut target_from_compressed_tar = |target_name| { @@ -547,7 +535,8 @@ impl Builder { Target::unavailable() }; - let targets = targets + let targets = pkg + .targets() .iter() .map(|name| { let target = if is_present { @@ -562,7 +551,7 @@ impl Builder { .collect(); dst.insert( - pkgname.to_string(), + pkg.manifest_component_name(), Package { version: version_info.version.unwrap_or_default(), git_commit_hash: version_info.git_commit, diff --git a/src/tools/build-manifest/src/manifest.rs b/src/tools/build-manifest/src/manifest.rs index 547c270d89ab7..a9f19d8e5653f 100644 --- a/src/tools/build-manifest/src/manifest.rs +++ b/src/tools/build-manifest/src/manifest.rs @@ -1,3 +1,4 @@ +use crate::versions::PkgType; use crate::Builder; use serde::{Serialize, Serializer}; use std::collections::BTreeMap; @@ -116,8 +117,8 @@ pub(crate) struct Component { } impl Component { - pub(crate) fn from_str(pkg: &str, target: &str) -> Self { - Self { pkg: pkg.to_string(), target: target.to_string() } + pub(crate) fn from_pkg(pkg: &PkgType, target: &str) -> Self { + Self { pkg: pkg.manifest_component_name(), target: target.to_string() } } } diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index cea34905db6aa..dde9745afb785 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -13,7 +13,6 @@ macro_rules! pkg_type { #[derive(Debug, Hash, Eq, PartialEq, Clone)] pub(crate) enum PkgType { $($variant,)+ - Other(String), } impl PkgType { @@ -24,18 +23,10 @@ macro_rules! pkg_type { } } - pub(crate) fn from_component(component: &str) -> Self { - match component { - $( $component $( | concat!($($is_preview)? $component, "-preview") )? => PkgType::$variant,)+ - _ => PkgType::Other(component.into()), - } - } - /// First part of the tarball name. pub(crate) fn tarball_component_name(&self) -> &str { match self { $( PkgType::$variant => $component,)+ - PkgType::Other(component) => component, } } @@ -100,7 +91,6 @@ impl PkgType { PkgType::ReproducibleArtifacts => true, PkgType::RustMingw => true, PkgType::RustAnalysis => true, - PkgType::Other(_) => true, } } @@ -127,7 +117,6 @@ impl PkgType { Rustfmt => HOSTS, RustAnalysis => TARGETS, LlvmTools => TARGETS, - Other(pkg) => panic!("add {pkg} to the list of known `PkgType`s"), } } From 60d1afcbb34d13118553451dec620d7fbb302516 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 27 Oct 2022 12:23:27 -0500 Subject: [PATCH 271/482] Use PkgType for profiles, too This makes it easier to remove `is_preview` from components in the future if we choose to do so. --- src/tools/build-manifest/src/main.rs | 61 +++++++++++----------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index ebc220cfce590..92be95c9420c5 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -311,44 +311,28 @@ impl Builder { } fn add_profiles_to(&mut self, manifest: &mut Manifest) { - let mut profile = |name, pkgs| self.profile(name, &mut manifest.profiles, pkgs); - profile("minimal", &["rustc", "cargo", "rust-std", "rust-mingw"]); - profile( - "default", - &[ - "rustc", - "cargo", - "rust-std", - "rust-mingw", - "rust-docs", - "rustfmt-preview", - "clippy-preview", - ], - ); - profile( - "complete", - &[ - "rustc", - "cargo", - "rust-std", - "rust-mingw", - "rust-docs", - "rustfmt-preview", - "clippy-preview", - "rls-preview", - "rust-analyzer-preview", - "rust-src", - "llvm-tools-preview", - "rust-analysis", - "miri-preview", - ], - ); + use PkgType::*; + + let mut profile = |name, pkgs: &_| self.profile(name, &mut manifest.profiles, pkgs); + + // Use a Vec here to make sure we don't exclude any components in an earlier profile. + let minimal = vec![Rustc, Cargo, RustStd, RustMingw]; + profile("minimal", &minimal); + + let mut default = minimal; + default.extend([HtmlDocs, Rustfmt, Clippy]); + profile("default", &default); + + // NOTE: this profile is effectively deprecated; do not add new components to it. + let mut complete = default; + complete.extend([Rls, RustAnalyzer, RustSrc, LlvmTools, RustAnalysis, Miri]); + profile("complete", &complete); // The compiler libraries are not stable for end users, and they're also huge, so we only // `rustc-dev` for nightly users, and only in the "complete" profile. It's still possible // for users to install the additional component manually, if needed. if self.versions.channel() == "nightly" { - self.extend_profile("complete", &mut manifest.profiles, &["rustc-dev"]); + self.extend_profile("complete", &mut manifest.profiles, &[RustcDev]); // Do not include the rustc-docs component for now, as it causes // conflicts with the rust-docs component when installed. See // #75833. @@ -468,20 +452,23 @@ impl Builder { &mut self, profile_name: &str, dst: &mut BTreeMap>, - pkgs: &[&str], + pkgs: &[PkgType], ) { - dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect()); + dst.insert( + profile_name.to_owned(), + pkgs.iter().map(|s| s.manifest_component_name()).collect(), + ); } fn extend_profile( &mut self, profile_name: &str, dst: &mut BTreeMap>, - pkgs: &[&str], + pkgs: &[PkgType], ) { dst.get_mut(profile_name) .expect("existing profile") - .extend(pkgs.iter().map(|s| (*s).to_owned())); + .extend(pkgs.iter().map(|s| s.manifest_component_name())); } fn package( From eca35cafb480eb66c3c8d25988e43fa2da1ba3de Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 1 Oct 2022 23:05:32 -0500 Subject: [PATCH 272/482] More build-manifest docs --- src/tools/build-manifest/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 40dce38742a14..9d30c554186be 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -8,10 +8,9 @@ This gets called by `promote-release` Date: Sun, 30 Oct 2022 16:38:40 -0500 Subject: [PATCH 273/482] Remove unnecessary argument to `package` --- src/tools/build-manifest/src/main.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 92be95c9420c5..371e60f969e58 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -284,8 +284,7 @@ impl Builder { fn add_packages_to(&mut self, manifest: &mut Manifest) { for pkg in PkgType::all() { - let fallback = if pkg.use_docs_fallback() { DOCS_FALLBACK } else { &[] }; - self.package(pkg, &mut manifest.pkg, fallback); + self.package(pkg, &mut manifest.pkg); } } @@ -471,18 +470,14 @@ impl Builder { .extend(pkgs.iter().map(|s| s.manifest_component_name())); } - fn package( - &mut self, - pkg: &PkgType, - dst: &mut BTreeMap, - fallback: &[(&str, &str)], - ) { + fn package(&mut self, pkg: &PkgType, dst: &mut BTreeMap) { if *pkg == PkgType::Rust { // This is handled specially by `rust_package` later. // Order is important, so don't call `rust_package` here. return; } + let fallback = if pkg.use_docs_fallback() { DOCS_FALLBACK } else { &[] }; let version_info = self.versions.version(&pkg).expect("failed to load package version"); let mut is_present = version_info.present; From ac7bfd238797125d7eba98d92971903a419bf498 Mon Sep 17 00:00:00 2001 From: CastilloDel Date: Fri, 28 Oct 2022 23:32:41 +0200 Subject: [PATCH 274/482] Reduce the scope of allow(rustc::potential_query_instability) in rustc_trait_selection Make InferCtxtExt use a FxIndexMap This should be faster, because the map is only being used to iterate, which is supposed to be faster with the IndexMap Make the user_computed_preds use an IndexMap It is being used mostly for iteration, so the change shouldn't result in a perf hit Make the RegionDeps fields use an IndexMap This change could be a perf hit. Both `larger` and `smaller` are used for iteration, but they are also used for insertions. Make types_without_default_bounds use an IndexMap It uses extend, but it also iterates and removes items. Not sure if this will be a perf hit. Make InferTtxt.reported_trait_errors use an IndexMap This change brought a lot of other changes. The map seems to have been mostly used for iteration, so the performance shouldn't suffer. Add FIXME to change ProvisionalEvaluationCache.map to use an IndexMap Right now this results in a perf hit. IndexMap doesn't have the `drain_filter` API, so in `on_completion` we now need to iterate two times over the map. --- .../src/check/compare_method.rs | 6 +++--- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 16 ++++++++-------- compiler/rustc_infer/src/infer/mod.rs | 3 ++- compiler/rustc_trait_selection/src/lib.rs | 1 - .../src/traits/auto_trait.rs | 12 ++++++------ .../rustc_trait_selection/src/traits/engine.rs | 6 +++--- .../src/traits/error_reporting/mod.rs | 4 ++-- .../src/traits/outlives_bounds.rs | 6 +++--- .../src/traits/select/mod.rs | 9 ++++++++- .../src/traits/specialize/mod.rs | 4 ++-- 10 files changed, 37 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 660c56ee8b011..04bf7c83b3208 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1,7 +1,7 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; use hir::def_id::{DefId, LocalDefId}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -256,7 +256,7 @@ fn compare_predicate_entailment<'tcx>( // Compute placeholder form of impl and trait method tys. let tcx = infcx.tcx; - let mut wf_tys = FxHashSet::default(); + let mut wf_tys = FxIndexSet::default(); let impl_sig = infcx.replace_bound_vars_with_fresh_vars( impl_m_span, @@ -479,7 +479,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( let trait_sig = ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_sig); let trait_return_ty = trait_sig.output(); - let wf_tys = FxHashSet::from_iter( + let wf_tys = FxIndexSet::from_iter( unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()), ); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e2c967d0b0836..6a12db9d36ade 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,7 +1,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; use hir::def::DefKind; use rustc_ast as ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -412,7 +412,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe .iter() .copied() .collect::>(), - &FxHashSet::default(), + &FxIndexSet::default(), gat_def_id.def_id, gat_generics, ) @@ -462,10 +462,10 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe .into_iter() .filter(|clause| match clause.kind().skip_binder() { ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { - !region_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b) + !region_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b) } ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => { - !ty_known_to_outlive(tcx, gat_hir, param_env, &FxHashSet::default(), a, b) + !ty_known_to_outlive(tcx, gat_hir, param_env, &FxIndexSet::default(), a, b) } _ => bug!("Unexpected PredicateKind"), }) @@ -547,7 +547,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( param_env: ty::ParamEnv<'tcx>, item_hir: hir::HirId, to_check: T, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, gat_def_id: LocalDefId, gat_generics: &'tcx ty::Generics, ) -> Option>> { @@ -654,7 +654,7 @@ fn ty_known_to_outlive<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, ty: Ty<'tcx>, region: ty::Region<'tcx>, ) -> bool { @@ -671,7 +671,7 @@ fn region_known_to_outlive<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, region_a: ty::Region<'tcx>, region_b: ty::Region<'tcx>, ) -> bool { @@ -695,7 +695,7 @@ fn resolve_regions_with_wf_tys<'tcx>( tcx: TyCtxt<'tcx>, id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - wf_tys: &FxHashSet>, + wf_tys: &FxIndexSet>, add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'tcx>, &'a RegionBoundPairs<'tcx>), ) -> bool { // Unfortunately, we have to use a new `InferCtxt` each call, because diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index d5be9983ea7c6..ccba197dc80b7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -10,6 +10,7 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine, TraitEngineExt}; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::Rollback; @@ -294,7 +295,7 @@ pub struct InferCtxt<'tcx> { /// the set of predicates on which errors have been reported, to /// avoid reporting the same error twice. - pub reported_trait_errors: RefCell>>>, + pub reported_trait_errors: RefCell>>>, pub reported_closure_mismatch: RefCell)>>, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 5d52aa0752301..2dce18e2d3cad 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -10,7 +10,6 @@ //! //! This API is completely unstable and subject to change. -#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index ed34ab95ad6c0..188f8bb7e2a58 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{PolyTraitRef, Region, RegionVid}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use std::collections::hash_map::Entry; use std::collections::VecDeque; @@ -27,8 +27,8 @@ pub enum RegionTarget<'tcx> { #[derive(Default, Debug, Clone)] pub struct RegionDeps<'tcx> { - larger: FxHashSet>, - smaller: FxHashSet>, + larger: FxIndexSet>, + smaller: FxIndexSet>, } pub enum AutoTraitResult { @@ -266,7 +266,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { })); let computed_preds = param_env.caller_bounds().iter(); - let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect(); + let mut user_computed_preds: FxIndexSet<_> = user_env.caller_bounds().iter().collect(); let mut new_env = param_env; let dummy_cause = ObligationCause::dummy(); @@ -389,7 +389,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { /// not just one specific lifetime (e.g., `'static`). fn add_user_pred( &self, - user_computed_preds: &mut FxHashSet>, + user_computed_preds: &mut FxIndexSet>, new_pred: ty::Predicate<'tcx>, ) { let mut should_add_new = true; @@ -585,7 +585,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { &self, ty: Ty<'_>, nested: impl Iterator>>, - computed_preds: &mut FxHashSet>, + computed_preds: &mut FxIndexSet>, fresh_preds: &mut FxHashSet>, predicates: &mut VecDeque>, select: &mut SelectionContext<'_, 'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 0eafc49816d49..ae29c9f561791 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use super::TraitEngine; use super::{ChalkFulfillmentContext, FulfillmentContext}; use crate::infer::InferCtxtExt; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{ @@ -154,10 +154,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, span: Span, def_id: LocalDefId, - ) -> FxHashSet> { + ) -> FxIndexSet> { let tcx = self.infcx.tcx; let assumed_wf_types = tcx.assumed_wf_types(def_id); - let mut implied_bounds = FxHashSet::default(); + let mut implied_bounds = FxIndexSet::default(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let cause = ObligationCause::misc(span, hir_id); for ty in assumed_wf_types { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 0f5d05afcf809..e64586407c923 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -15,7 +15,7 @@ use crate::traits::query::normalize::AtExt as _; use crate::traits::specialize::to_pretty_impl_header; use on_unimplemented::OnUnimplementedNote; use on_unimplemented::TypeErrCtxtExt as _; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, Style, @@ -379,7 +379,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { index: Option, // None if this is an old error } - let mut error_map: FxHashMap<_, Vec<_>> = self + let mut error_map: FxIndexMap<_, Vec<_>> = self .reported_trait_errors .borrow() .iter() diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index b1a161c353637..e1092a788e32b 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -2,7 +2,7 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; use crate::traits::ObligationCause; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::HirId; use rustc_middle::ty::{self, ParamEnv, Ty}; @@ -22,7 +22,7 @@ pub trait InferCtxtExt<'a, 'tcx> { &'a self, param_env: ty::ParamEnv<'tcx>, body_id: hir::HirId, - tys: FxHashSet>, + tys: FxIndexSet>, ) -> Bounds<'a, 'tcx>; } @@ -103,7 +103,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { &'a self, param_env: ParamEnv<'tcx>, body_id: HirId, - tys: FxHashSet>, + tys: FxIndexSet>, ) -> Bounds<'a, 'tcx> { tys.into_iter() .map(move |ty| { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c6ff83120a736..de158a15d54b8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2,6 +2,12 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection +// FIXME: The `map` field in ProvisionalEvaluationCache should be changed to +// a `FxIndexMap` to avoid query instability, but right now it causes a perf regression. This would be +// fixed or at least lightened by the addition of the `drain_filter` method to `FxIndexMap` +// Relevant: https://github.com/rust-lang/rust/pull/103723 and https://github.com/bluss/indexmap/issues/242 +#![allow(rustc::potential_query_instability)] + use self::EvaluationResult::*; use self::SelectionCandidate::*; @@ -24,7 +30,8 @@ use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c891658582a0a..43819b3f490b1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -16,7 +16,7 @@ use crate::errors::NegativePositiveConflict; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::{self, ImplSubject, TyCtxt}; @@ -435,7 +435,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti // FIXME: Currently only handles ?Sized. // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxHashSet::default(); + let mut types_without_default_bounds = FxIndexSet::default(); let sized_trait = tcx.lang_items().sized_trait(); if !substs.is_empty() { From 7086df77742a6d67fb96882fd88a2b8ba5724230 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Wed, 26 Oct 2022 11:58:33 +0200 Subject: [PATCH 275/482] stabilize `int_log` --- library/core/benches/lib.rs | 1 - library/core/src/num/int_macros.rs | 29 +++++++++++++----------- library/core/src/num/nonzero.rs | 8 +++---- library/core/src/num/uint_macros.rs | 29 +++++++++++++----------- library/core/tests/lib.rs | 1 - src/tools/miri/src/lib.rs | 1 - src/tools/miri/tests/pass/integer-ops.rs | 1 - 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs index cf5a7cada93ce..f1244d93285e3 100644 --- a/library/core/benches/lib.rs +++ b/library/core/benches/lib.rs @@ -1,7 +1,6 @@ // wasm32 does not support benches (no time). #![cfg(not(target_arch = "wasm32"))] #![feature(flt2dec)] -#![feature(int_log)] #![feature(test)] #![feature(trusted_random_access)] #![feature(iter_array_chunks)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 81f050cb283d4..404ddff4f9dab 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2271,15 +2271,16 @@ macro_rules! int_impl { /// # Panics /// /// This function will panic if `self` is less than or equal to zero, - /// or if `base` is less then 2. + /// or if `base` is less than 2. /// /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".ilog(5), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2298,10 +2299,11 @@ macro_rules! int_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".ilog2(), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2319,10 +2321,11 @@ macro_rules! int_impl { /// # Example /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".ilog10(), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2343,10 +2346,10 @@ macro_rules! int_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_ilog(5), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2379,10 +2382,10 @@ macro_rules! int_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_ilog2(), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2403,10 +2406,10 @@ macro_rules! int_impl { /// # Example /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_ilog10(), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 6b6f3417f8ad5..5b7521220acdb 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -460,14 +460,14 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")] #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")] #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -485,14 +485,14 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")] #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")] #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 93f65c5c7aaf3..0563f28278d36 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -692,15 +692,16 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `self` is zero, or if `base` is less then 2. + /// This function will panic if `self` is zero, or if `base` is less than 2. /// /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".ilog(5), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -719,10 +720,11 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".ilog2(), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -740,10 +742,11 @@ macro_rules! uint_impl { /// # Example /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".ilog10(), 1);")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -764,10 +767,10 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_ilog(5), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -800,10 +803,10 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_ilog2(), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -822,10 +825,10 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - /// #![feature(int_log)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_ilog10(), Some(1));")] /// ``` - #[unstable(feature = "int_log", issue = "70887")] + #[stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "int_log", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index eda176d9fcbe6..a7db2a02bd743 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -64,7 +64,6 @@ #![feature(try_trait_v2)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] -#![feature(int_log)] #![feature(iter_advance_by)] #![feature(iter_array_chunks)] #![feature(iter_collect_into)] diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 3b73d05907b4e..8028ce7535488 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -3,7 +3,6 @@ #![feature(never_type)] #![feature(try_blocks)] #![feature(io_error_more)] -#![feature(int_log)] #![feature(variant_count)] #![feature(yeet_expr)] #![feature(is_some_and)] diff --git a/src/tools/miri/tests/pass/integer-ops.rs b/src/tools/miri/tests/pass/integer-ops.rs index 724be9efc9f82..0ec1f8e9c6935 100644 --- a/src/tools/miri/tests/pass/integer-ops.rs +++ b/src/tools/miri/tests/pass/integer-ops.rs @@ -1,5 +1,4 @@ //@compile-flags: -Coverflow-checks=off -#![feature(int_log)] #![allow(arithmetic_overflow)] pub fn main() { From 4ab354153a09bb0e7311f3e2d898e1e810d6760c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 28 Oct 2022 19:48:38 +0400 Subject: [PATCH 276/482] Add examples for `pointer::mask` --- library/core/src/ptr/const_ptr.rs | 25 +++++++++++++++++++++++++ library/core/src/ptr/mut_ptr.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 5a083227bb0ef..926d2ae511398 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -568,6 +568,31 @@ impl *const T { /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. + /// + /// ## Examples + /// + /// ``` + /// #![feature(ptr_mask, strict_provenance)] + /// let v = 17_u32; + /// let ptr: *const u32 = &v; + /// + /// // `u32` is 4 bytes aligned, + /// // which means that lower 2 bits are always 0. + /// let tag_mask = 0b11; + /// let ptr_mask = !tag_mask; + /// + /// // We can store something in these lower bits + /// let tagged_ptr = ptr.map_addr(|a| a | 0b10); + /// + /// // Get the "tag" back + /// let tag = tagged_ptr.addr() & tag_mask; + /// assert_eq!(tag, 0b10); + /// + /// // Note that `tagged_ptr` is unaligned, it's UB to read from it. + /// // To get original pointer `mask` can be used: + /// let masked_ptr = tagged_ptr.mask(ptr_mask); + /// assert_eq!(unsafe { *masked_ptr }, 17); + /// ``` #[unstable(feature = "ptr_mask", issue = "98290")] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 6764002bcd434..f71696e9ca0fa 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -588,6 +588,34 @@ impl *mut T { /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. + /// + /// ## Examples + /// + /// ``` + /// #![feature(ptr_mask, strict_provenance)] + /// let mut v = 17_u32; + /// let ptr: *mut u32 = &mut v; + /// + /// // `u32` is 4 bytes aligned, + /// // which means that lower 2 bits are always 0. + /// let tag_mask = 0b11; + /// let ptr_mask = !tag_mask; + /// + /// // We can store something in these lower bits + /// let tagged_ptr = ptr.map_addr(|a| a | 0b10); + /// + /// // Get the "tag" back + /// let tag = tagged_ptr.addr() & tag_mask; + /// assert_eq!(tag, 0b10); + /// + /// // Note that `tagged_ptr` is unaligned, it's UB to read from/write to it. + /// // To get original pointer `mask` can be used: + /// let masked_ptr = tagged_ptr.mask(ptr_mask); + /// assert_eq!(unsafe { *masked_ptr }, 17); + /// + /// unsafe { *masked_ptr = 0 }; + /// assert_eq!(v, 0); + /// ``` #[unstable(feature = "ptr_mask", issue = "98290")] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] From cc4083aafbbaf1a02ccc35a1de72cb62e3452856 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 11:31:07 +1100 Subject: [PATCH 277/482] Rename some variables. These have been bugging me for a while. - `literal_text`: `src` is also used and is shorter and better. - `first_char`: used even when "first" doesn't make sense; `c` is shorter and better. - `curr`: `c` is shorter and better. - `unescaped_char`: `result` is also used and is shorter and better. - `second_char`: these have a single use and can be elided. --- compiler/rustc_lexer/src/unescape.rs | 70 +++++++++++++--------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 8f64b5f5158e4..a6752c82bd3c5 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -78,54 +78,52 @@ impl EscapeError { /// Takes a contents of a literal (without quotes) and produces a /// sequence of escaped characters or errors. /// Values are returned through invoking of the provided callback. -pub fn unescape_literal(literal_text: &str, mode: Mode, callback: &mut F) +pub fn unescape_literal(src: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { match mode { Mode::Char | Mode::Byte => { - let mut chars = literal_text.chars(); + let mut chars = src.chars(); let result = unescape_char_or_byte(&mut chars, mode); // The Chars iterator moved forward. - callback(0..(literal_text.len() - chars.as_str().len()), result); + callback(0..(src.len() - chars.as_str().len()), result); } - Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(literal_text, mode, callback), + Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode, callback), // NOTE: Raw strings do not perform any explicit character escaping, here we // only translate CRLF to LF and produce errors on bare CR. - Mode::RawStr | Mode::RawByteStr => { - unescape_raw_str_or_raw_byte_str(literal_text, mode, callback) - } + Mode::RawStr | Mode::RawByteStr => unescape_raw_str_or_raw_byte_str(src, mode, callback), } } /// Takes a contents of a byte, byte string or raw byte string (without quotes) /// and produces a sequence of bytes or errors. /// Values are returned through invoking of the provided callback. -pub fn unescape_byte_literal(literal_text: &str, mode: Mode, callback: &mut F) +pub fn unescape_byte_literal(src: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { debug_assert!(mode.is_bytes()); - unescape_literal(literal_text, mode, &mut |range, result| { + unescape_literal(src, mode, &mut |range, result| { callback(range, result.map(byte_from_char)); }) } /// Takes a contents of a char literal (without quotes), and returns an /// unescaped char or an error -pub fn unescape_char(literal_text: &str) -> Result { - let mut chars = literal_text.chars(); +pub fn unescape_char(src: &str) -> Result { + let mut chars = src.chars(); unescape_char_or_byte(&mut chars, Mode::Char) - .map_err(|err| (literal_text.len() - chars.as_str().len(), err)) + .map_err(|err| (src.len() - chars.as_str().len(), err)) } /// Takes a contents of a byte literal (without quotes), and returns an /// unescaped byte or an error. -pub fn unescape_byte(literal_text: &str) -> Result { - let mut chars = literal_text.chars(); +pub fn unescape_byte(src: &str) -> Result { + let mut chars = src.chars(); unescape_char_or_byte(&mut chars, Mode::Byte) .map(byte_from_char) - .map_err(|err| (literal_text.len() - chars.as_str().len(), err)) + .map_err(|err| (src.len() - chars.as_str().len(), err)) } /// What kind of literal do we parse. @@ -157,10 +155,7 @@ impl Mode { fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { // Previous character was '\\', unescape what follows. - - let second_char = chars.next().ok_or(EscapeError::LoneSlash)?; - - let res = match second_char { + let res = match chars.next().ok_or(EscapeError::LoneSlash)? { '"' => '"', 'n' => '\n', 'r' => '\r', @@ -249,23 +244,23 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { } #[inline] -fn ascii_check(first_char: char, mode: Mode) -> Result { - if mode.is_bytes() && !first_char.is_ascii() { +fn ascii_check(c: char, mode: Mode) -> Result { + if mode.is_bytes() && !c.is_ascii() { // Byte literal can't be a non-ascii character. Err(EscapeError::NonAsciiCharInByte) } else { - Ok(first_char) + Ok(c) } } fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result { debug_assert!(mode == Mode::Char || mode == Mode::Byte); - let first_char = chars.next().ok_or(EscapeError::ZeroChars)?; - let res = match first_char { + let c = chars.next().ok_or(EscapeError::ZeroChars)?; + let res = match c { '\\' => scan_escape(chars, mode), '\n' | '\t' | '\'' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), - _ => ascii_check(first_char, mode), + _ => ascii_check(c, mode), }?; if chars.next().is_some() { return Err(EscapeError::MoreThanOneChar); @@ -282,13 +277,12 @@ where debug_assert!(mode == Mode::Str || mode == Mode::ByteStr); let initial_len = src.len(); let mut chars = src.chars(); - while let Some(first_char) = chars.next() { - let start = initial_len - chars.as_str().len() - first_char.len_utf8(); + while let Some(c) = chars.next() { + let start = initial_len - chars.as_str().len() - c.len_utf8(); - let unescaped_char = match first_char { + let result = match c { '\\' => { - let second_char = chars.clone().next(); - match second_char { + match chars.clone().next() { Some('\n') => { // Rust language specification requires us to skip whitespaces // if unescaped '\' character is followed by '\n'. @@ -304,10 +298,10 @@ where '\t' => Ok('\t'), '"' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), - _ => ascii_check(first_char, mode), + _ => ascii_check(c, mode), }; let end = initial_len - chars.as_str().len(); - callback(start..end, unescaped_char); + callback(start..end, result); } fn skip_ascii_whitespace(chars: &mut Chars<'_>, start: usize, callback: &mut F) @@ -341,18 +335,18 @@ where /// sequence of characters or errors. /// NOTE: Raw strings do not perform any explicit character escaping, here we /// only translate CRLF to LF and produce errors on bare CR. -fn unescape_raw_str_or_raw_byte_str(literal_text: &str, mode: Mode, callback: &mut F) +fn unescape_raw_str_or_raw_byte_str(src: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { debug_assert!(mode == Mode::RawStr || mode == Mode::RawByteStr); - let initial_len = literal_text.len(); + let initial_len = src.len(); - let mut chars = literal_text.chars(); - while let Some(curr) = chars.next() { - let start = initial_len - chars.as_str().len() - curr.len_utf8(); + let mut chars = src.chars(); + while let Some(c) = chars.next() { + let start = initial_len - chars.as_str().len() - c.len_utf8(); - let result = match curr { + let result = match c { '\r' => Err(EscapeError::BareCarriageReturnInRawString), c if mode.is_bytes() && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), c => Ok(c), From e2cca15c1f52ab81b2496dfd8eddefd7b0aef1c1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 12:15:55 +1100 Subject: [PATCH 278/482] Clarify range calculations. There is some subtlety here. --- compiler/rustc_lexer/src/unescape.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index a6752c82bd3c5..dc2fd359e278e 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -275,11 +275,13 @@ where F: FnMut(Range, Result), { debug_assert!(mode == Mode::Str || mode == Mode::ByteStr); - let initial_len = src.len(); let mut chars = src.chars(); - while let Some(c) = chars.next() { - let start = initial_len - chars.as_str().len() - c.len_utf8(); + // The `start` and `end` computation here is complicated because + // `skip_ascii_whitespace` makes us to skip over chars without counting + // them in the range computation. + while let Some(c) = chars.next() { + let start = src.len() - chars.as_str().len() - c.len_utf8(); let result = match c { '\\' => { match chars.clone().next() { @@ -300,7 +302,7 @@ where '\r' => Err(EscapeError::BareCarriageReturn), _ => ascii_check(c, mode), }; - let end = initial_len - chars.as_str().len(); + let end = src.len() - chars.as_str().len(); callback(start..end, result); } @@ -340,19 +342,19 @@ where F: FnMut(Range, Result), { debug_assert!(mode == Mode::RawStr || mode == Mode::RawByteStr); - let initial_len = src.len(); - let mut chars = src.chars(); - while let Some(c) = chars.next() { - let start = initial_len - chars.as_str().len() - c.len_utf8(); + // The `start` and `end` computation here matches the one in + // `unescape_str_or_byte_str` for consistency, even though this function + // doesn't have to worry about skipping any chars. + while let Some(c) = chars.next() { + let start = src.len() - chars.as_str().len() - c.len_utf8(); let result = match c { '\r' => Err(EscapeError::BareCarriageReturnInRawString), c if mode.is_bytes() && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), c => Ok(c), }; - let end = initial_len - chars.as_str().len(); - + let end = src.len() - chars.as_str().len(); callback(start..end, result); } } From a452d5ede1c22f6fad2535342b08f64887bff5bf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 13:35:49 +1100 Subject: [PATCH 279/482] Use `Mode` less. It's passed to numerous places where we just need an `is_byte` bool. Passing the bool avoids the need for some assertions. Also rename `is_bytes()` as `is_byte()`, to better match `Mode::Byte`, `Mode::ByteStr`, and `Mode::RawByteStr`. --- compiler/rustc_lexer/src/unescape.rs | 46 +++++++++---------- .../src/lexer/unescape_error_reporting.rs | 14 +++--- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index dc2fd359e278e..f0042a397c2c5 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -85,14 +85,16 @@ where match mode { Mode::Char | Mode::Byte => { let mut chars = src.chars(); - let result = unescape_char_or_byte(&mut chars, mode); + let result = unescape_char_or_byte(&mut chars, mode == Mode::Byte); // The Chars iterator moved forward. callback(0..(src.len() - chars.as_str().len()), result); } - Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode, callback), + Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode == Mode::ByteStr, callback), // NOTE: Raw strings do not perform any explicit character escaping, here we // only translate CRLF to LF and produce errors on bare CR. - Mode::RawStr | Mode::RawByteStr => unescape_raw_str_or_raw_byte_str(src, mode, callback), + Mode::RawStr | Mode::RawByteStr => { + unescape_raw_str_or_raw_byte_str(src, mode == Mode::RawByteStr, callback) + } } } @@ -103,7 +105,7 @@ pub fn unescape_byte_literal(src: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { - debug_assert!(mode.is_bytes()); + debug_assert!(mode.is_byte()); unescape_literal(src, mode, &mut |range, result| { callback(range, result.map(byte_from_char)); }) @@ -113,15 +115,14 @@ where /// unescaped char or an error pub fn unescape_char(src: &str) -> Result { let mut chars = src.chars(); - unescape_char_or_byte(&mut chars, Mode::Char) - .map_err(|err| (src.len() - chars.as_str().len(), err)) + unescape_char_or_byte(&mut chars, false).map_err(|err| (src.len() - chars.as_str().len(), err)) } /// Takes a contents of a byte literal (without quotes), and returns an /// unescaped byte or an error. pub fn unescape_byte(src: &str) -> Result { let mut chars = src.chars(); - unescape_char_or_byte(&mut chars, Mode::Byte) + unescape_char_or_byte(&mut chars, true) .map(byte_from_char) .map_err(|err| (src.len() - chars.as_str().len(), err)) } @@ -145,7 +146,7 @@ impl Mode { } } - pub fn is_bytes(self) -> bool { + pub fn is_byte(self) -> bool { match self { Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, Mode::Char | Mode::Str | Mode::RawStr => false, @@ -153,7 +154,7 @@ impl Mode { } } -fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { +fn scan_escape(chars: &mut Chars<'_>, is_byte: bool) -> Result { // Previous character was '\\', unescape what follows. let res = match chars.next().ok_or(EscapeError::LoneSlash)? { '"' => '"', @@ -176,7 +177,7 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { let value = hi * 16 + lo; // For a non-byte literal verify that it is within ASCII range. - if !mode.is_bytes() && !is_ascii(value) { + if !is_byte && !is_ascii(value) { return Err(EscapeError::OutOfRangeHexEscape); } let value = value as u8; @@ -212,7 +213,7 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { // Incorrect syntax has higher priority for error reporting // than unallowed value for a literal. - if mode.is_bytes() { + if is_byte { return Err(EscapeError::UnicodeEscapeInByte); } @@ -244,8 +245,8 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { } #[inline] -fn ascii_check(c: char, mode: Mode) -> Result { - if mode.is_bytes() && !c.is_ascii() { +fn ascii_check(c: char, is_byte: bool) -> Result { + if is_byte && !c.is_ascii() { // Byte literal can't be a non-ascii character. Err(EscapeError::NonAsciiCharInByte) } else { @@ -253,14 +254,13 @@ fn ascii_check(c: char, mode: Mode) -> Result { } } -fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result { - debug_assert!(mode == Mode::Char || mode == Mode::Byte); +fn unescape_char_or_byte(chars: &mut Chars<'_>, is_byte: bool) -> Result { let c = chars.next().ok_or(EscapeError::ZeroChars)?; let res = match c { - '\\' => scan_escape(chars, mode), + '\\' => scan_escape(chars, is_byte), '\n' | '\t' | '\'' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), - _ => ascii_check(c, mode), + _ => ascii_check(c, is_byte), }?; if chars.next().is_some() { return Err(EscapeError::MoreThanOneChar); @@ -270,11 +270,10 @@ fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result(src: &str, mode: Mode, callback: &mut F) +fn unescape_str_or_byte_str(src: &str, is_byte: bool, callback: &mut F) where F: FnMut(Range, Result), { - debug_assert!(mode == Mode::Str || mode == Mode::ByteStr); let mut chars = src.chars(); // The `start` and `end` computation here is complicated because @@ -293,14 +292,14 @@ where skip_ascii_whitespace(&mut chars, start, callback); continue; } - _ => scan_escape(&mut chars, mode), + _ => scan_escape(&mut chars, is_byte), } } '\n' => Ok('\n'), '\t' => Ok('\t'), '"' => Err(EscapeError::EscapeOnlyChar), '\r' => Err(EscapeError::BareCarriageReturn), - _ => ascii_check(c, mode), + _ => ascii_check(c, is_byte), }; let end = src.len() - chars.as_str().len(); callback(start..end, result); @@ -337,11 +336,10 @@ where /// sequence of characters or errors. /// NOTE: Raw strings do not perform any explicit character escaping, here we /// only translate CRLF to LF and produce errors on bare CR. -fn unescape_raw_str_or_raw_byte_str(src: &str, mode: Mode, callback: &mut F) +fn unescape_raw_str_or_raw_byte_str(src: &str, is_byte: bool, callback: &mut F) where F: FnMut(Range, Result), { - debug_assert!(mode == Mode::RawStr || mode == Mode::RawByteStr); let mut chars = src.chars(); // The `start` and `end` computation here matches the one in @@ -351,7 +349,7 @@ where let start = src.len() - chars.as_str().len() - c.len_utf8(); let result = match c { '\r' => Err(EscapeError::BareCarriageReturnInRawString), - c if mode.is_bytes() && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), + c if is_byte && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), c => Ok(c), }; let end = src.len() - chars.as_str().len(); diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index f075de7142676..055ee98a00aa3 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -108,7 +108,7 @@ pub(crate) fn emit_unescape_error( } if !has_help { - let (prefix, msg) = if mode.is_bytes() { + let (prefix, msg) = if mode.is_byte() { ("b", "if you meant to write a byte string literal, use double quotes") } else { ("", "if you meant to write a `str` literal, use double quotes") @@ -142,7 +142,7 @@ pub(crate) fn emit_unescape_error( EscapeError::EscapeOnlyChar => { let (c, char_span) = last_char(); - let msg = if mode.is_bytes() { + let msg = if mode.is_byte() { "byte constant must be escaped" } else { "character constant must be escaped" @@ -182,11 +182,11 @@ pub(crate) fn emit_unescape_error( let (c, span) = last_char(); let label = - if mode.is_bytes() { "unknown byte escape" } else { "unknown character escape" }; + if mode.is_byte() { "unknown byte escape" } else { "unknown character escape" }; let ec = escaped_char(c); let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); diag.span_label(span, label); - if c == '{' || c == '}' && !mode.is_bytes() { + if c == '{' || c == '}' && !mode.is_byte() { diag.help( "if used in a formatting string, curly braces are escaped with `{{` and `}}`", ); @@ -196,7 +196,7 @@ pub(crate) fn emit_unescape_error( version control settings", ); } else { - if !mode.is_bytes() { + if !mode.is_byte() { diag.span_suggestion( span_with_quotes, "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal", @@ -231,7 +231,7 @@ pub(crate) fn emit_unescape_error( .emit(); } EscapeError::NonAsciiCharInByte => { - assert!(mode.is_bytes()); + assert!(mode.is_byte()); let (c, span) = last_char(); let mut err = handler.struct_span_err(span, "non-ASCII character in byte constant"); let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 { @@ -271,7 +271,7 @@ pub(crate) fn emit_unescape_error( err.emit(); } EscapeError::NonAsciiCharInByteString => { - assert!(mode.is_bytes()); + assert!(mode.is_byte()); let (c, span) = last_char(); let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 { format!(" but is {:?}", c) From a430927e69e190aae1be1586920b4c6daa0eac65 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 15:17:37 +1100 Subject: [PATCH 280/482] Make non-ASCII errors more consistent. There are three kinds of "byte" literals: byte literals, byte string literals, and raw byte string literals. None are allowed to have non-ASCII chars in them. Two `EscapeError` variants exist for when that constraint is violated. - `NonAsciiCharInByte`: used for byte literals and byte string literals. - `NonAsciiCharInByteString`: used for raw byte string literals. As a result, the messages for raw byte string literals use different wording, without good reason. Also, byte string literals are incorrectly described as "byte constants" in some error messages. This commit eliminates `NonAsciiCharInByteString` so the three cases are handled similarly, and described correctly. The `mode` is enough to distinguish them. Note: Some existing error messages mention "byte constants" and some mention "byte literals". I went with the latter here, because it's a more correct name, as used by the Reference. --- compiler/rustc_lexer/src/unescape.rs | 7 ++-- compiler/rustc_lexer/src/unescape/tests.rs | 7 ++-- .../src/lexer/unescape_error_reporting.rs | 32 ++++++++----------- src/test/ui/attributes/key-value-non-ascii.rs | 2 +- .../ui/attributes/key-value-non-ascii.stderr | 4 +-- src/test/ui/parser/byte-literals.rs | 2 +- src/test/ui/parser/byte-literals.stderr | 4 +-- src/test/ui/parser/byte-string-literals.rs | 4 +-- .../ui/parser/byte-string-literals.stderr | 6 ++-- .../ui/parser/raw/raw-byte-string-literals.rs | 2 +- .../raw/raw-byte-string-literals.stderr | 2 +- .../ui/parser/unicode-control-codepoints.rs | 16 +++++----- .../parser/unicode-control-codepoints.stderr | 24 +++++++------- src/test/ui/suggestions/multibyte-escapes.rs | 12 +++---- .../ui/suggestions/multibyte-escapes.stderr | 12 +++---- 15 files changed, 62 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index f0042a397c2c5..9c9cce7cbd48e 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -52,10 +52,8 @@ pub enum EscapeError { /// Unicode escape code in byte literal. UnicodeEscapeInByte, - /// Non-ascii character in byte literal. + /// Non-ascii character in byte literal, byte string literal, or raw byte string literal. NonAsciiCharInByte, - /// Non-ascii character in byte string literal. - NonAsciiCharInByteString, /// After a line ending with '\', the next line contains whitespace /// characters that are not skipped. @@ -349,8 +347,7 @@ where let start = src.len() - chars.as_str().len() - c.len_utf8(); let result = match c { '\r' => Err(EscapeError::BareCarriageReturnInRawString), - c if is_byte && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), - c => Ok(c), + _ => ascii_check(c, is_byte), }; let end = src.len() - chars.as_str().len(); callback(start..end, result); diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index fa61554afde6c..008edef5a6385 100644 --- a/compiler/rustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs @@ -289,9 +289,6 @@ fn test_unescape_raw_byte_str() { } check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]); - check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByteString))]); - check( - "🦀a", - &[(0..4, Err(EscapeError::NonAsciiCharInByteString)), (4..5, Ok(byte_from_char('a')))], - ); + check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByte))]); + check("🦀a", &[(0..4, Err(EscapeError::NonAsciiCharInByte)), (4..5, Ok(byte_from_char('a')))]); } diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 055ee98a00aa3..6373f5b4fd6ff 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -231,16 +231,23 @@ pub(crate) fn emit_unescape_error( .emit(); } EscapeError::NonAsciiCharInByte => { - assert!(mode.is_byte()); let (c, span) = last_char(); - let mut err = handler.struct_span_err(span, "non-ASCII character in byte constant"); + let desc = match mode { + Mode::Byte => "byte literal", + Mode::ByteStr => "byte string literal", + Mode::RawByteStr => "raw byte string literal", + _ => panic!("non-is_byte literal paired with NonAsciiCharInByte"), + }; + let mut err = handler.struct_span_err(span, format!("non-ASCII character in {}", desc)); let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 { format!(" but is {:?}", c) } else { String::new() }; - err.span_label(span, &format!("byte constant must be ASCII{}", postfix)); - if (c as u32) <= 0xFF { + err.span_label(span, &format!("must be ASCII{}", postfix)); + // Note: the \\xHH suggestions are not given for raw byte string + // literals, because they are araw and so cannot use any escapes. + if (c as u32) <= 0xFF && mode != Mode::RawByteStr { err.span_suggestion( span, &format!( @@ -250,9 +257,9 @@ pub(crate) fn emit_unescape_error( format!("\\x{:X}", c as u32), Applicability::MaybeIncorrect, ); - } else if matches!(mode, Mode::Byte) { + } else if mode == Mode::Byte { err.span_label(span, "this multibyte character does not fit into a single byte"); - } else if matches!(mode, Mode::ByteStr) { + } else if mode != Mode::RawByteStr { let mut utf8 = String::new(); utf8.push(c); err.span_suggestion( @@ -270,19 +277,6 @@ pub(crate) fn emit_unescape_error( } err.emit(); } - EscapeError::NonAsciiCharInByteString => { - assert!(mode.is_byte()); - let (c, span) = last_char(); - let postfix = if unicode_width::UnicodeWidthChar::width(c).unwrap_or(1) == 0 { - format!(" but is {:?}", c) - } else { - String::new() - }; - handler - .struct_span_err(span, "raw byte string must be ASCII") - .span_label(span, &format!("must be ASCII{}", postfix)) - .emit(); - } EscapeError::OutOfRangeHexEscape => { handler .struct_span_err(span, "out of range hex escape") diff --git a/src/test/ui/attributes/key-value-non-ascii.rs b/src/test/ui/attributes/key-value-non-ascii.rs index 12942eabdf7b5..e14e2fc05ad39 100644 --- a/src/test/ui/attributes/key-value-non-ascii.rs +++ b/src/test/ui/attributes/key-value-non-ascii.rs @@ -1,4 +1,4 @@ #![feature(rustc_attrs)] -#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte constant +#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte string literal fn main() {} diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr index 422107867f7f9..23d482de6a868 100644 --- a/src/test/ui/attributes/key-value-non-ascii.stderr +++ b/src/test/ui/attributes/key-value-non-ascii.stderr @@ -1,8 +1,8 @@ -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/key-value-non-ascii.rs:3:19 | LL | #[rustc_dummy = b"ffi.rs"] - | ^ byte constant must be ASCII + | ^ must be ASCII | help: if you meant to use the UTF-8 encoding of 'ffi', use \xHH escapes | diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs index 05a510b24a7ab..896dc1a1a5fba 100644 --- a/src/test/ui/parser/byte-literals.rs +++ b/src/test/ui/parser/byte-literals.rs @@ -7,6 +7,6 @@ pub fn main() { b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z` b' '; //~ ERROR byte constant must be escaped b'''; //~ ERROR byte constant must be escaped - b'é'; //~ ERROR non-ASCII character in byte constant + b'é'; //~ ERROR non-ASCII character in byte literal b'a //~ ERROR unterminated byte constant [E0763] } diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr index c3d0006163005..efa55ae05bd37 100644 --- a/src/test/ui/parser/byte-literals.stderr +++ b/src/test/ui/parser/byte-literals.stderr @@ -32,11 +32,11 @@ error: byte constant must be escaped: `'` LL | b'''; | ^ help: escape the character: `\'` -error: non-ASCII character in byte constant +error: non-ASCII character in byte literal --> $DIR/byte-literals.rs:10:7 | LL | b'é'; - | ^ byte constant must be ASCII + | ^ must be ASCII | help: if you meant to use the unicode code point for 'é', use a \xHH escape | diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs index b1f11024a7bb6..30a4f50c4e40b 100644 --- a/src/test/ui/parser/byte-string-literals.rs +++ b/src/test/ui/parser/byte-string-literals.rs @@ -3,7 +3,7 @@ static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape pub fn main() { b"\f"; //~ ERROR unknown byte escape b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z` - b"é"; //~ ERROR non-ASCII character in byte constant - br##"é"##; //~ ERROR raw byte string must be ASCII + b"é"; //~ ERROR non-ASCII character in byte string literal + br##"é"##; //~ ERROR non-ASCII character in raw byte string literal b"a //~ ERROR unterminated double quote byte string } diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr index 3b8b3692e053f..5b96cc3d18abc 100644 --- a/src/test/ui/parser/byte-string-literals.stderr +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -20,18 +20,18 @@ error: invalid character in numeric character escape: `Z` LL | b"\x0Z"; | ^ invalid character in numeric character escape -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/byte-string-literals.rs:6:7 | LL | b"é"; - | ^ byte constant must be ASCII + | ^ must be ASCII | help: if you meant to use the unicode code point for 'é', use a \xHH escape | LL | b"\xE9"; | ~~~~ -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/byte-string-literals.rs:7:10 | LL | br##"é"##; diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs index 163c8ac66b022..1b859fee596ad 100644 --- a/src/test/ui/parser/raw/raw-byte-string-literals.rs +++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs @@ -2,6 +2,6 @@ pub fn main() { br"a "; //~ ERROR bare CR not allowed in raw string - br"é"; //~ ERROR raw byte string must be ASCII + br"é"; //~ ERROR non-ASCII character in raw byte string literal br##~"a"~##; //~ ERROR only `#` is allowed in raw string delimitation } diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr index cfc877104bd9f..a2f27d1ed70ae 100644 --- a/src/test/ui/parser/raw/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr @@ -4,7 +4,7 @@ error: bare CR not allowed in raw string LL | br"a "; | ^ -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/raw-byte-string-literals.rs:5:8 | LL | br"é"; diff --git a/src/test/ui/parser/unicode-control-codepoints.rs b/src/test/ui/parser/unicode-control-codepoints.rs index 5af0b585a1275..df099bb62ad1e 100644 --- a/src/test/ui/parser/unicode-control-codepoints.rs +++ b/src/test/ui/parser/unicode-control-codepoints.rs @@ -14,15 +14,15 @@ fn main() { println!("{:?}", r##"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only "##); //~^ ERROR unicode codepoint changing visible direction of text present in literal println!("{:?}", b"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only "); - //~^ ERROR non-ASCII character in byte constant - //~| ERROR non-ASCII character in byte constant - //~| ERROR non-ASCII character in byte constant - //~| ERROR non-ASCII character in byte constant + //~^ ERROR non-ASCII character in byte string literal + //~| ERROR non-ASCII character in byte string literal + //~| ERROR non-ASCII character in byte string literal + //~| ERROR non-ASCII character in byte string literal println!("{:?}", br##"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only "##); - //~^ ERROR raw byte string must be ASCII - //~| ERROR raw byte string must be ASCII - //~| ERROR raw byte string must be ASCII - //~| ERROR raw byte string must be ASCII + //~^ ERROR non-ASCII character in raw byte string literal + //~| ERROR non-ASCII character in raw byte string literal + //~| ERROR non-ASCII character in raw byte string literal + //~| ERROR non-ASCII character in raw byte string literal println!("{:?}", '‮'); //~^ ERROR unicode codepoint changing visible direction of text present in literal } diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr index 44548c72ff5d0..fc071a9419142 100644 --- a/src/test/ui/parser/unicode-control-codepoints.stderr +++ b/src/test/ui/parser/unicode-control-codepoints.stderr @@ -14,69 +14,69 @@ LL | println!("{:?}", b"us\u{202B}e\u{202A}r"); | = help: unicode escape sequences cannot be used as a byte or in a byte string -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/unicode-control-codepoints.rs:16:26 | LL | println!("{:?}", b"/* } if isAdmin begin admins only "); - | ^ byte constant must be ASCII but is '\u{202e}' + | ^ must be ASCII but is '\u{202e}' | help: if you meant to use the UTF-8 encoding of '\u{202e}', use \xHH escapes | LL | println!("{:?}", b"/*\xE2\x80\xAE } if isAdmin begin admins only "); | ~~~~~~~~~~~~ -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/unicode-control-codepoints.rs:16:30 | LL | println!("{:?}", b"/* } if isAdmin begin admins only "); - | ^ byte constant must be ASCII but is '\u{2066}' + | ^ must be ASCII but is '\u{2066}' | help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes | LL | println!("{:?}", b"/* } \xE2\x81\xA6if isAdmin begin admins only "); | ~~~~~~~~~~~~ -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/unicode-control-codepoints.rs:16:41 | LL | println!("{:?}", b"/* } if isAdmin begin admins only "); - | ^ byte constant must be ASCII but is '\u{2069}' + | ^ must be ASCII but is '\u{2069}' | help: if you meant to use the UTF-8 encoding of '\u{2069}', use \xHH escapes | LL | println!("{:?}", b"/* } if isAdmin\xE2\x81\xA9 begin admins only "); | ~~~~~~~~~~~~ -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/unicode-control-codepoints.rs:16:43 | LL | println!("{:?}", b"/* } if isAdmin begin admins only "); - | ^ byte constant must be ASCII but is '\u{2066}' + | ^ must be ASCII but is '\u{2066}' | help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes | LL | println!("{:?}", b"/* } if isAdmin \xE2\x81\xA6 begin admins only "); | ~~~~~~~~~~~~ -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/unicode-control-codepoints.rs:21:29 | LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); | ^ must be ASCII but is '\u{202e}' -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/unicode-control-codepoints.rs:21:33 | LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); | ^ must be ASCII but is '\u{2066}' -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/unicode-control-codepoints.rs:21:44 | LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); | ^ must be ASCII but is '\u{2069}' -error: raw byte string must be ASCII +error: non-ASCII character in raw byte string literal --> $DIR/unicode-control-codepoints.rs:21:46 | LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##); diff --git a/src/test/ui/suggestions/multibyte-escapes.rs b/src/test/ui/suggestions/multibyte-escapes.rs index fd5d46a4e923e..c4105186244db 100644 --- a/src/test/ui/suggestions/multibyte-escapes.rs +++ b/src/test/ui/suggestions/multibyte-escapes.rs @@ -2,17 +2,17 @@ fn main() { b'µ'; - //~^ ERROR: non-ASCII character in byte constant + //~^ ERROR: non-ASCII character in byte literal //~| HELP: if you meant to use the unicode code point for 'µ', use a \xHH escape - //~| NOTE: byte constant must be ASCII + //~| NOTE: must be ASCII b'字'; - //~^ ERROR: non-ASCII character in byte constant + //~^ ERROR: non-ASCII character in byte literal //~| NOTE: this multibyte character does not fit into a single byte - //~| NOTE: byte constant must be ASCII + //~| NOTE: must be ASCII b"字"; - //~^ ERROR: non-ASCII character in byte constant + //~^ ERROR: non-ASCII character in byte string literal //~| HELP: if you meant to use the UTF-8 encoding of '字', use \xHH escapes - //~| NOTE: byte constant must be ASCII + //~| NOTE: must be ASCII } diff --git a/src/test/ui/suggestions/multibyte-escapes.stderr b/src/test/ui/suggestions/multibyte-escapes.stderr index 6e26bc1f01cef..1e7c43e6538f6 100644 --- a/src/test/ui/suggestions/multibyte-escapes.stderr +++ b/src/test/ui/suggestions/multibyte-escapes.stderr @@ -1,28 +1,28 @@ -error: non-ASCII character in byte constant +error: non-ASCII character in byte literal --> $DIR/multibyte-escapes.rs:4:7 | LL | b'µ'; - | ^ byte constant must be ASCII + | ^ must be ASCII | help: if you meant to use the unicode code point for 'µ', use a \xHH escape | LL | b'\xB5'; | ~~~~ -error: non-ASCII character in byte constant +error: non-ASCII character in byte literal --> $DIR/multibyte-escapes.rs:9:7 | LL | b'字'; | ^^ | | - | byte constant must be ASCII + | must be ASCII | this multibyte character does not fit into a single byte -error: non-ASCII character in byte constant +error: non-ASCII character in byte string literal --> $DIR/multibyte-escapes.rs:14:7 | LL | b"字"; - | ^^ byte constant must be ASCII + | ^^ must be ASCII | help: if you meant to use the UTF-8 encoding of '字', use \xHH escapes | From b9b3b8ce45e398d326a124e9afe720ab84790bf8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2022 16:26:27 +1100 Subject: [PATCH 281/482] Improve comments. Remove a low-value comment, remove a duplicate comment, and correct a third comment. --- compiler/rustc_lexer/src/unescape.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 9c9cce7cbd48e..db7bf02e71adc 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -84,12 +84,9 @@ where Mode::Char | Mode::Byte => { let mut chars = src.chars(); let result = unescape_char_or_byte(&mut chars, mode == Mode::Byte); - // The Chars iterator moved forward. callback(0..(src.len() - chars.as_str().len()), result); } Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode == Mode::ByteStr, callback), - // NOTE: Raw strings do not perform any explicit character escaping, here we - // only translate CRLF to LF and produce errors on bare CR. Mode::RawStr | Mode::RawByteStr => { unescape_raw_str_or_raw_byte_str(src, mode == Mode::RawByteStr, callback) } @@ -333,7 +330,7 @@ where /// Takes a contents of a string literal (without quotes) and produces a /// sequence of characters or errors. /// NOTE: Raw strings do not perform any explicit character escaping, here we -/// only translate CRLF to LF and produce errors on bare CR. +/// only produce errors on bare CR. fn unescape_raw_str_or_raw_byte_str(src: &str, is_byte: bool, callback: &mut F) where F: FnMut(Range, Result), From 00a6465cf72b99a699b2f3e7c70465204ebb7aa0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Nov 2022 09:19:34 +1100 Subject: [PATCH 282/482] Refactor `cook_lexer_literal`. It deals with eight cases: ints, floats, and the six quoted types (char/byte/strings). For ints and floats we have an early return, and the other six types fall through to the code at the end, which makes the function hard to read. This commit rearranges things to avoid the early returns. --- compiler/rustc_parse/src/lexer/mod.rs | 78 +++++++++++++-------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index de8f1c00c1295..3b3a4f2d9ae5e 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -353,55 +353,55 @@ impl<'a> StringReader<'a> { fn cook_lexer_literal( &self, start: BytePos, - suffix_start: BytePos, + end: BytePos, kind: rustc_lexer::LiteralKind, ) -> (token::LitKind, Symbol) { - // prefix means `"` or `br"` or `r###"`, ... - let (lit_kind, mode, prefix_len, postfix_len) = match kind { + match kind { rustc_lexer::LiteralKind::Char { terminated } => { if !terminated { self.sess.span_diagnostic.span_fatal_with_code( - self.mk_sp(start, suffix_start), + self.mk_sp(start, end), "unterminated character literal", error_code!(E0762), ) } - (token::Char, Mode::Char, 1, 1) // ' ' + self.cook_quoted(token::Char, Mode::Char, start, end, 1, 1) // ' ' } rustc_lexer::LiteralKind::Byte { terminated } => { if !terminated { self.sess.span_diagnostic.span_fatal_with_code( - self.mk_sp(start + BytePos(1), suffix_start), + self.mk_sp(start + BytePos(1), end), "unterminated byte constant", error_code!(E0763), ) } - (token::Byte, Mode::Byte, 2, 1) // b' ' + self.cook_quoted(token::Byte, Mode::Byte, start, end, 2, 1) // b' ' } rustc_lexer::LiteralKind::Str { terminated } => { if !terminated { self.sess.span_diagnostic.span_fatal_with_code( - self.mk_sp(start, suffix_start), + self.mk_sp(start, end), "unterminated double quote string", error_code!(E0765), ) } - (token::Str, Mode::Str, 1, 1) // " " + self.cook_quoted(token::Str, Mode::Str, start, end, 1, 1) // " " } rustc_lexer::LiteralKind::ByteStr { terminated } => { if !terminated { self.sess.span_diagnostic.span_fatal_with_code( - self.mk_sp(start + BytePos(1), suffix_start), + self.mk_sp(start + BytePos(1), end), "unterminated double quote byte string", error_code!(E0766), ) } - (token::ByteStr, Mode::ByteStr, 2, 1) // b" " + self.cook_quoted(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" " } rustc_lexer::LiteralKind::RawStr { n_hashes } => { if let Some(n_hashes) = n_hashes { let n = u32::from(n_hashes); - (token::StrRaw(n_hashes), Mode::RawStr, 2 + n, 1 + n) // r##" "## + let kind = token::StrRaw(n_hashes); + self.cook_quoted(kind, Mode::RawStr, start, end, 2 + n, 1 + n) // r##" "## } else { self.report_raw_str_error(start, 1); } @@ -409,56 +409,47 @@ impl<'a> StringReader<'a> { rustc_lexer::LiteralKind::RawByteStr { n_hashes } => { if let Some(n_hashes) = n_hashes { let n = u32::from(n_hashes); - (token::ByteStrRaw(n_hashes), Mode::RawByteStr, 3 + n, 1 + n) // br##" "## + let kind = token::ByteStrRaw(n_hashes); + self.cook_quoted(kind, Mode::RawByteStr, start, end, 3 + n, 1 + n) // br##" "## } else { self.report_raw_str_error(start, 2); } } rustc_lexer::LiteralKind::Int { base, empty_int } => { - return if empty_int { + if empty_int { self.sess .span_diagnostic .struct_span_err_with_code( - self.mk_sp(start, suffix_start), + self.mk_sp(start, end), "no valid digits found for number", error_code!(E0768), ) .emit(); (token::Integer, sym::integer(0)) } else { - self.validate_int_literal(base, start, suffix_start); - (token::Integer, self.symbol_from_to(start, suffix_start)) - }; + self.validate_int_literal(base, start, end); + (token::Integer, self.symbol_from_to(start, end)) + } } rustc_lexer::LiteralKind::Float { base, empty_exponent } => { if empty_exponent { self.err_span_(start, self.pos, "expected at least one digit in exponent"); } - match base { - Base::Hexadecimal => self.err_span_( - start, - suffix_start, - "hexadecimal float literal is not supported", - ), + Base::Hexadecimal => { + self.err_span_(start, end, "hexadecimal float literal is not supported") + } Base::Octal => { - self.err_span_(start, suffix_start, "octal float literal is not supported") + self.err_span_(start, end, "octal float literal is not supported") } Base::Binary => { - self.err_span_(start, suffix_start, "binary float literal is not supported") + self.err_span_(start, end, "binary float literal is not supported") } - _ => (), + _ => {} } - - let id = self.symbol_from_to(start, suffix_start); - return (token::Float, id); + (token::Float, self.symbol_from_to(start, end)) } - }; - let content_start = start + BytePos(prefix_len); - let content_end = suffix_start - BytePos(postfix_len); - let id = self.symbol_from_to(content_start, content_end); - self.validate_literal_escape(mode, content_start, content_end, prefix_len, postfix_len); - (lit_kind, id) + } } #[inline] @@ -649,20 +640,22 @@ impl<'a> StringReader<'a> { ) } - fn validate_literal_escape( + fn cook_quoted( &self, + kind: token::LitKind, mode: Mode, - content_start: BytePos, - content_end: BytePos, + start: BytePos, + end: BytePos, prefix_len: u32, postfix_len: u32, - ) { + ) -> (token::LitKind, Symbol) { + let content_start = start + BytePos(prefix_len); + let content_end = end - BytePos(postfix_len); let lit_content = self.str_from_to(content_start, content_end); unescape::unescape_literal(lit_content, mode, &mut |range, result| { // Here we only check for errors. The actual unescaping is done later. if let Err(err) = result { - let span_with_quotes = self - .mk_sp(content_start - BytePos(prefix_len), content_end + BytePos(postfix_len)); + let span_with_quotes = self.mk_sp(start, end); let (start, end) = (range.start as u32, range.end as u32); let lo = content_start + BytePos(start); let hi = lo + BytePos(end - start); @@ -678,6 +671,7 @@ impl<'a> StringReader<'a> { ); } }); + (kind, Symbol::intern(lit_content)) } fn validate_int_literal(&self, base: Base, content_start: BytePos, content_end: BytePos) { From 8b69a2c00f423806801367fd08af96cf66747a1a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Nov 2022 10:02:29 +1100 Subject: [PATCH 283/482] Inline and remove `validate_int_literal`. It has a single callsite, and is fairly small. The `Float` match arm already has base-specific checking inline, so this makes things more consistent. --- compiler/rustc_lexer/src/lib.rs | 10 ++++----- compiler/rustc_parse/src/lexer/mod.rs | 31 +++++++++++---------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index dd2c09cae02fd..d4140cb295f32 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -205,13 +205,13 @@ pub enum RawStrError { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Base { /// Literal starts with "0b". - Binary, + Binary = 2, /// Literal starts with "0o". - Octal, - /// Literal starts with "0x". - Hexadecimal, + Octal = 8, /// Literal doesn't contain a prefix. - Decimal, + Decimal = 10, + /// Literal starts with "0x". + Hexadecimal = 16, } /// `rustc` allows files to have a shebang, e.g. "#!/usr/bin/rustrun", diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 3b3a4f2d9ae5e..645262bd2f1d3 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -427,7 +427,19 @@ impl<'a> StringReader<'a> { .emit(); (token::Integer, sym::integer(0)) } else { - self.validate_int_literal(base, start, end); + if matches!(base, Base::Binary | Base::Octal) { + let base = base as u32; + let s = self.str_from_to(start + BytePos(2), end); + for (idx, c) in s.char_indices() { + if c != '_' && c.to_digit(base).is_none() { + self.err_span_( + start + BytePos::from_usize(2 + idx), + start + BytePos::from_usize(2 + idx + c.len_utf8()), + &format!("invalid digit for a base {} literal", base), + ); + } + } + } (token::Integer, self.symbol_from_to(start, end)) } } @@ -673,23 +685,6 @@ impl<'a> StringReader<'a> { }); (kind, Symbol::intern(lit_content)) } - - fn validate_int_literal(&self, base: Base, content_start: BytePos, content_end: BytePos) { - let base = match base { - Base::Binary => 2, - Base::Octal => 8, - _ => return, - }; - let s = self.str_from_to(content_start + BytePos(2), content_end); - for (idx, c) in s.char_indices() { - let idx = idx as u32; - if c != '_' && c.to_digit(base).is_none() { - let lo = content_start + BytePos(2 + idx); - let hi = content_start + BytePos(2 + idx + c.len_utf8() as u32); - self.err_span_(lo, hi, &format!("invalid digit for a base {} literal", base)); - } - } - } } pub fn nfc_normalize(string: &str) -> Symbol { From c1a8bbe663a4872584c8d6457adc270be978db37 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Nov 2022 11:09:23 +1100 Subject: [PATCH 284/482] Remove `unescape_byte_literal`. It's easy to just use `unescape_literal` + `byte_from_char`. --- compiler/rustc_ast/src/util/literal.rs | 29 +++++++------------ compiler/rustc_lexer/src/unescape.rs | 16 ++-------- compiler/rustc_lexer/src/unescape/tests.rs | 12 ++++---- .../crates/syntax/src/validation.rs | 6 ++-- 4 files changed, 20 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 536b385606c69..8f342175f7d37 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -2,12 +2,9 @@ use crate::ast::{self, Lit, LitKind}; use crate::token::{self, Token}; - -use rustc_lexer::unescape::{unescape_byte, unescape_char}; -use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode}; +use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; - use std::ascii; pub enum LitError { @@ -109,13 +106,11 @@ impl LitKind { let s = symbol.as_str(); let mut buf = Vec::with_capacity(s.len()); let mut error = Ok(()); - unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(err) => { - if err.is_fatal() { - error = Err(LitError::LexerError); - } + unescape_literal(&s, Mode::ByteStr, &mut |_, c| match c { + Ok(c) => buf.push(byte_from_char(c)), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); } } }); @@ -127,13 +122,11 @@ impl LitKind { let bytes = if s.contains('\r') { let mut buf = Vec::with_capacity(s.len()); let mut error = Ok(()); - unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(err) => { - if err.is_fatal() { - error = Err(LitError::LexerError); - } + unescape_literal(&s, Mode::RawByteStr, &mut |_, c| match c { + Ok(c) => buf.push(byte_from_char(c)), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); } } }); diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index db7bf02e71adc..8d5eac29452e7 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -93,19 +93,6 @@ where } } -/// Takes a contents of a byte, byte string or raw byte string (without quotes) -/// and produces a sequence of bytes or errors. -/// Values are returned through invoking of the provided callback. -pub fn unescape_byte_literal(src: &str, mode: Mode, callback: &mut F) -where - F: FnMut(Range, Result), -{ - debug_assert!(mode.is_byte()); - unescape_literal(src, mode, &mut |range, result| { - callback(range, result.map(byte_from_char)); - }) -} - /// Takes a contents of a char literal (without quotes), and returns an /// unescaped char or an error pub fn unescape_char(src: &str) -> Result { @@ -351,7 +338,8 @@ where } } -fn byte_from_char(c: char) -> u8 { +#[inline] +pub fn byte_from_char(c: char) -> u8 { let res = c as u32; debug_assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr"); res as u8 diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index 008edef5a6385..00c8401efdfe4 100644 --- a/compiler/rustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs @@ -246,10 +246,10 @@ fn test_unescape_byte_good() { fn test_unescape_byte_str_good() { fn check(literal_text: &str, expected: &[u8]) { let mut buf = Ok(Vec::with_capacity(literal_text.len())); - unescape_byte_literal(literal_text, Mode::ByteStr, &mut |range, c| { + unescape_literal(literal_text, Mode::ByteStr, &mut |range, c| { if let Ok(b) = &mut buf { match c { - Ok(c) => b.push(c), + Ok(c) => b.push(byte_from_char(c)), Err(e) => buf = Err((range, e)), } } @@ -280,15 +280,13 @@ fn test_unescape_raw_str() { #[test] fn test_unescape_raw_byte_str() { - fn check(literal: &str, expected: &[(Range, Result)]) { + fn check(literal: &str, expected: &[(Range, Result)]) { let mut unescaped = Vec::with_capacity(literal.len()); - unescape_byte_literal(literal, Mode::RawByteStr, &mut |range, res| { - unescaped.push((range, res)) - }); + unescape_literal(literal, Mode::RawByteStr, &mut |range, res| unescaped.push((range, res))); assert_eq!(unescaped, expected); } check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]); check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByte))]); - check("🦀a", &[(0..4, Err(EscapeError::NonAsciiCharInByte)), (4..5, Ok(byte_from_char('a')))]); + check("🦀a", &[(0..4, Err(EscapeError::NonAsciiCharInByte)), (4..5, Ok('a'))]); } diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs index b9f2b5132353c..1eea2346451dd 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs @@ -5,9 +5,7 @@ mod block; use rowan::Direction; -use rustc_lexer::unescape::{ - self, unescape_byte, unescape_byte_literal, unescape_char, unescape_literal, Mode, -}; +use rustc_lexer::unescape::{self, unescape_byte, unescape_char, unescape_literal, Mode}; use crate::{ algo, @@ -143,7 +141,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec) { ast::LiteralKind::ByteString(s) => { if !s.is_raw() { if let Some(without_quotes) = unquote(text, 2, '"') { - unescape_byte_literal(without_quotes, Mode::ByteStr, &mut |range, char| { + unescape_literal(without_quotes, Mode::ByteStr, &mut |range, char| { if let Err(err) = char { push_err(2, (range.start, err)); } From 69a2c205bd69668d1f926b75d36a98aafd94f69d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Nov 2022 13:52:44 +1100 Subject: [PATCH 285/482] Rename some `result` variables as `res`, for consistency. --- compiler/rustc_lexer/src/unescape.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 8d5eac29452e7..674bbff0878ce 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -83,8 +83,8 @@ where match mode { Mode::Char | Mode::Byte => { let mut chars = src.chars(); - let result = unescape_char_or_byte(&mut chars, mode == Mode::Byte); - callback(0..(src.len() - chars.as_str().len()), result); + let res = unescape_char_or_byte(&mut chars, mode == Mode::Byte); + callback(0..(src.len() - chars.as_str().len()), res); } Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(src, mode == Mode::ByteStr, callback), Mode::RawStr | Mode::RawByteStr => { @@ -263,7 +263,7 @@ where // them in the range computation. while let Some(c) = chars.next() { let start = src.len() - chars.as_str().len() - c.len_utf8(); - let result = match c { + let res = match c { '\\' => { match chars.clone().next() { Some('\n') => { @@ -284,7 +284,7 @@ where _ => ascii_check(c, is_byte), }; let end = src.len() - chars.as_str().len(); - callback(start..end, result); + callback(start..end, res); } fn skip_ascii_whitespace(chars: &mut Chars<'_>, start: usize, callback: &mut F) @@ -329,12 +329,12 @@ where // doesn't have to worry about skipping any chars. while let Some(c) = chars.next() { let start = src.len() - chars.as_str().len() - c.len_utf8(); - let result = match c { + let res = match c { '\r' => Err(EscapeError::BareCarriageReturnInRawString), _ => ascii_check(c, is_byte), }; let end = src.len() - chars.as_str().len(); - callback(start..end, result); + callback(start..end, res); } } From 9e01a0b9372e3b39656c62057e90f9d0e7695058 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Nov 2022 15:59:19 +1100 Subject: [PATCH 286/482] Simplify `unescape_{char,byte}`. The `usize` isn't needed in the error case. --- compiler/rustc_lexer/src/unescape.rs | 14 +++++--------- compiler/rustc_lexer/src/unescape/tests.rs | 12 ++++-------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 674bbff0878ce..e405013dcabf8 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -94,19 +94,15 @@ where } /// Takes a contents of a char literal (without quotes), and returns an -/// unescaped char or an error -pub fn unescape_char(src: &str) -> Result { - let mut chars = src.chars(); - unescape_char_or_byte(&mut chars, false).map_err(|err| (src.len() - chars.as_str().len(), err)) +/// unescaped char or an error. +pub fn unescape_char(src: &str) -> Result { + unescape_char_or_byte(&mut src.chars(), false) } /// Takes a contents of a byte literal (without quotes), and returns an /// unescaped byte or an error. -pub fn unescape_byte(src: &str) -> Result { - let mut chars = src.chars(); - unescape_char_or_byte(&mut chars, true) - .map(byte_from_char) - .map_err(|err| (src.len() - chars.as_str().len(), err)) +pub fn unescape_byte(src: &str) -> Result { + unescape_char_or_byte(&mut src.chars(), true).map(byte_from_char) } /// What kind of literal do we parse. diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index 00c8401efdfe4..c7ca8fd16ae47 100644 --- a/compiler/rustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs @@ -3,8 +3,7 @@ use super::*; #[test] fn test_unescape_char_bad() { fn check(literal_text: &str, expected_error: EscapeError) { - let actual_result = unescape_char(literal_text).map_err(|(_offset, err)| err); - assert_eq!(actual_result, Err(expected_error)); + assert_eq!(unescape_char(literal_text), Err(expected_error)); } check("", EscapeError::ZeroChars); @@ -68,8 +67,7 @@ fn test_unescape_char_bad() { #[test] fn test_unescape_char_good() { fn check(literal_text: &str, expected_char: char) { - let actual_result = unescape_char(literal_text); - assert_eq!(actual_result, Ok(expected_char)); + assert_eq!(unescape_char(literal_text), Ok(expected_char)); } check("a", 'a'); @@ -149,8 +147,7 @@ fn test_unescape_str_good() { #[test] fn test_unescape_byte_bad() { fn check(literal_text: &str, expected_error: EscapeError) { - let actual_result = unescape_byte(literal_text).map_err(|(_offset, err)| err); - assert_eq!(actual_result, Err(expected_error)); + assert_eq!(unescape_byte(literal_text), Err(expected_error)); } check("", EscapeError::ZeroChars); @@ -219,8 +216,7 @@ fn test_unescape_byte_bad() { #[test] fn test_unescape_byte_good() { fn check(literal_text: &str, expected_byte: u8) { - let actual_result = unescape_byte(literal_text); - assert_eq!(actual_result, Ok(expected_byte)); + assert_eq!(unescape_byte(literal_text), Ok(expected_byte)); } check("a", b'a'); From 7950a2281e451d0ec7ae9a734c183c98e6dfd551 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 3 Nov 2022 12:49:49 -0400 Subject: [PATCH 287/482] Promote {aarch64,i686,x86_64}-unknown-uefi to Tier 2 MCP: https://github.com/rust-lang/compiler-team/issues/555 --- .../host-x86_64/dist-various-2/Dockerfile | 3 ++ src/doc/rustc/src/platform-support.md | 6 +-- .../src/platform-support/unknown-uefi.md | 38 ++++--------------- src/tools/build-manifest/src/main.rs | 3 ++ 4 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 126c292b38ea1..e1adabaac9b56 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -118,6 +118,9 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none +ENV TARGETS=$TARGETS,aarch64-unknown-uefi +ENV TARGETS=$TARGETS,i686-unknown-uefi +ENV TARGETS=$TARGETS,x86_64-unknown-uefi # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211 # we need asm in the search path for gcc-8 (for gnux32) but not in the search path of the diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 3ae9872cf62d4..5b4e436da7d57 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -128,6 +128,7 @@ target | std | notes [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat +[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv7 Android `arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with MUSL `arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with MUSL, hardfloat @@ -149,6 +150,7 @@ target | std | notes [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD `i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL +[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI `mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL @@ -181,6 +183,7 @@ target | std | notes `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat `x86_64-unknown-redox` | ✓ | Redox OS +[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI [Fortanix ABI]: https://edp.fortanix.com/ @@ -213,7 +216,6 @@ target | std | host | notes [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore -[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | ARM64 UEFI `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) `aarch64-unknown-netbsd` | ✓ | ✓ | [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD @@ -252,7 +254,6 @@ target | std | host | notes `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku `i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2 [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD -[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 32-bit UEFI `i686-uwp-windows-gnu` | ? | | `i686-uwp-windows-msvc` | ? | | `i686-wrs-vxworks` | ? | | @@ -311,7 +312,6 @@ target | std | host | notes `x86_64-unknown-l4re-uclibc` | ? | | `x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD -[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 64-bit UEFI `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index 295dec0f0e488..e2bdf73a92990 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -1,6 +1,6 @@ # `*-unknown-uefi` -**Tier: 3** +**Tier: 2** Unified Extensible Firmware Interface (UEFI) targets for application, driver, and core UEFI binaries. @@ -72,28 +72,14 @@ target = ["x86_64-unknown-uefi"] ## Building Rust programs -Rust does not yet ship pre-compiled artifacts for this target. To compile for -this target, you will either need to build Rust with the target enabled (see -"Building rust for UEFI targets" above), or build your own copy of `core` by -using `build-std`, `cargo-buildx`, or similar. - -A native build with the unstable `build-std`-feature can be achieved via: - -```sh -cargo +nightly build \ - -Zbuild-std=core,compiler_builtins \ - -Zbuild-std-features=compiler-builtins-mem \ - --target x86_64-unknown-uefi -``` - -Alternatively, you can install `cargo-xbuild` via -`cargo install --force cargo-xbuild` and build for the UEFI targets via: +Starting with Rust 1.67, precompiled artifacts are provided via +`rustup`. For example, to use `x86_64-unknown-uefi`: ```sh -cargo \ - +nightly \ - xbuild \ - --target x86_64-unknown-uefi +# install cross-compile toolchain +rustup target add x86_64-unknown-uefi +# target flag may be used with any cargo or rustc command +cargo build --target x86_64-unknown-uefi ``` ## Testing @@ -167,18 +153,10 @@ The following code is a valid UEFI application returning immediately upon execution with an exit code of 0. A panic handler is provided. This is executed by rust on panic. For simplicity, we simply end up in an infinite loop. -Note that as of rust-1.31.0, all features used here are stabilized. No unstable -features are required, nor do we rely on nightly compilers. However, if you do -not compile rustc for the UEFI targets, you need a nightly compiler to support -the `-Z build-std` flag. - This example can be compiled as binary crate via `cargo`: ```sh -cargo +nightly build \ - -Zbuild-std=core,compiler_builtins \ - -Zbuild-std-features=compiler-builtins-mem \ - --target x86_64-unknown-uefi +cargo build --target x86_64-unknown-uefi ``` ```rust,ignore (platform-specific,eh-personality-is-unstable) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 371e60f969e58..0551e835bb0e7 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -60,6 +60,7 @@ static TARGETS: &[&str] = &[ "aarch64-unknown-none", "aarch64-unknown-none-softfloat", "aarch64-unknown-redox", + "aarch64-unknown-uefi", "arm-linux-androideabi", "arm-unknown-linux-gnueabi", "arm-unknown-linux-gnueabihf", @@ -95,6 +96,7 @@ static TARGETS: &[&str] = &[ "i686-unknown-freebsd", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", + "i686-unknown-uefi", "m68k-unknown-linux-gnu", "mips-unknown-linux-gnu", "mips-unknown-linux-musl", @@ -151,6 +153,7 @@ static TARGETS: &[&str] = &[ "x86_64-unknown-none", "x86_64-unknown-redox", "x86_64-unknown-hermit", + "x86_64-unknown-uefi", ]; /// This allows the manifest to contain rust-docs for hosts that don't build From 3497dfa43a08cbcaab28d5364900b7a4aa5907e8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 3 Nov 2022 22:01:58 -0700 Subject: [PATCH 288/482] Move intra-doc link checks to a separate function. --- src/tools/linkchecker/main.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 7842611bd4ffa..4092722501d0e 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -365,6 +365,23 @@ impl Checker { } }); + self.check_intra_doc_links(file, &pretty_path, &source, report); + + // we don't need the source anymore, + // so drop to reduce memory-usage + match self.cache.get_mut(&pretty_path).unwrap() { + FileEntry::HtmlFile { source, .. } => *source = Rc::new(String::new()), + _ => unreachable!("must be html file"), + } + } + + fn check_intra_doc_links( + &mut self, + file: &Path, + pretty_path: &str, + source: &str, + report: &mut Report, + ) { // Search for intra-doc links that rustdoc didn't warn about // FIXME(#77199, 77200) Rustdoc should just warn about these directly. // NOTE: only looks at one line at a time; in practice this should find most links @@ -379,12 +396,6 @@ impl Checker { } } } - // we don't need the source anymore, - // so drop to reduce memory-usage - match self.cache.get_mut(&pretty_path).unwrap() { - FileEntry::HtmlFile { source, .. } => *source = Rc::new(String::new()), - _ => unreachable!("must be html file"), - } } /// Load a file from disk, or from the cache if available. From bf01330c0acf35b3afdfbccb9695c14e6d26bdcb Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 3 Nov 2022 22:02:39 -0700 Subject: [PATCH 289/482] Remove reference from the intra-doc link checker. --- src/tools/linkchecker/main.rs | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 4092722501d0e..4170c32f1fe25 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -55,30 +55,6 @@ const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[ #[rustfmt::skip] const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[ - // This will never have links that are not in other pages. - // To avoid repeating the exceptions twice, an empty list means all broken links are allowed. - ("reference/print.html", &[]), - // All the reference 'links' are actually ENBF highlighted as code - ("reference/comments.html", &[ - "/ !", - "* !", - ]), - ("reference/identifiers.html", &[ - "a-z A-Z", - "a-z A-Z 0-9 _", - "a-z A-Z] [a-z A-Z 0-9 _", - ]), - ("reference/tokens.html", &[ - "0-1", - "0-7", - "0-9", - "0-9", - "0-9 a-f A-F", - ]), - ("reference/notation.html", &[ - "b B", - "a-z", - ]), // This is being used in the sense of 'inclusive range', not a markdown link ("core/ops/struct.RangeInclusive.html", &["begin, end"]), ("std/ops/struct.RangeInclusive.html", &["begin, end"]), @@ -382,6 +358,16 @@ impl Checker { source: &str, report: &mut Report, ) { + let relative = file.strip_prefix(&self.root).expect("should always be relative to root"); + // Don't check the reference. It has several legitimate things that + // look like []. The reference has its own broken link + // checker in its CI which handles this using pulldown_cmark. + // + // This checks both the end of the root (when checking just the + // reference directory) or the beginning (when checking all docs). + if self.root.ends_with("reference") || relative.starts_with("reference") { + return; + } // Search for intra-doc links that rustdoc didn't warn about // FIXME(#77199, 77200) Rustdoc should just warn about these directly. // NOTE: only looks at one line at a time; in practice this should find most links From 0bb60a5a5ddb8050460667934d5a1547b03223ad Mon Sep 17 00:00:00 2001 From: yancy Date: Mon, 7 Nov 2022 17:02:48 +0100 Subject: [PATCH 290/482] rustdoc: Add mutable to the description --- library/core/src/slice/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0fde931140fbe..0f58bc643d965 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3667,7 +3667,8 @@ impl [T] { unsafe { self.align_to() } } - /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. + /// Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, + /// and a mutable suffix. /// /// This is a safe wrapper around [`slice::align_to_mut`], so has the same weak /// postconditions as that method. You're only assured that From 949b636d7b943784f2ac8a9185b3d74466ab2dc8 Mon Sep 17 00:00:00 2001 From: onestacked Date: Mon, 7 Nov 2022 21:47:46 +0100 Subject: [PATCH 291/482] const Compare Tuples --- library/core/src/tuple.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index fc91fe468cc29..28275798f751e 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -22,7 +22,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:PartialEq),+> PartialEq for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl<$($T: ~const PartialEq),+> const PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -40,7 +41,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:Eq),+> Eq for ($($T,)+) + impl<$($T: Eq),+> Eq for ($($T,)+) where last_type!($($T,)+): ?Sized {} @@ -49,7 +50,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl<$($T: ~const PartialOrd + ~const PartialEq),+> const PartialOrd for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -79,7 +81,8 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:Ord),+> Ord for ($($T,)+) + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl<$($T: ~const Ord),+> const Ord for ($($T,)+) where last_type!($($T,)+): ?Sized { From c6dd869a34971081744cf5b07600f57f89a26feb Mon Sep 17 00:00:00 2001 From: onestacked Date: Wed, 9 Nov 2022 11:35:28 +0100 Subject: [PATCH 292/482] Cleanup fn trait ref test --- src/test/ui/consts/fn_trait_refs.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/test/ui/consts/fn_trait_refs.rs b/src/test/ui/consts/fn_trait_refs.rs index bc8766c74c60f..b507492970ab3 100644 --- a/src/test/ui/consts/fn_trait_refs.rs +++ b/src/test/ui/consts/fn_trait_refs.rs @@ -1,4 +1,4 @@ -// build-pass +// check-pass #![feature(const_fn_trait_ref_impls)] #![feature(fn_traits)] @@ -60,21 +60,18 @@ const fn test(i: i32) -> i32 { i + 1 } -const fn main() { +fn main() { const fn one() -> i32 { 1 }; const fn two() -> i32 { 2 }; + const _: () = { + let test_one = test_fn(one); + assert!(test_one == (1, 1, 1)); - // FIXME(const_cmp_tuple) - let test_one = test_fn(one); - assert!(test_one.0 == 1); - assert!(test_one.1 == 1); - assert!(test_one.2 == 1); - - let test_two = test_fn_mut(two); - assert!(test_two.0 == 1); - assert!(test_two.1 == 1); + let test_two = test_fn_mut(two); + assert!(test_two == (2, 2)); + }; } From b39002dc9b059397e5b134d0f26de1ed46882f70 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 7 Nov 2022 17:13:20 -0700 Subject: [PATCH 293/482] Update to latest version of flate2 --- Cargo.lock | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 544cb4faef222..ddacf9cf02463 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,12 +14,6 @@ dependencies = [ "rustc-std-workspace-core", ] -[[package]] -name = "adler" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" - [[package]] name = "adler" version = "1.0.2" @@ -180,7 +174,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide 0.5.3", + "miniz_oxide", "object", "rustc-demangle", ] @@ -1286,15 +1280,15 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.16" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "crc32fast", "libc", "libz-sys", - "miniz_oxide 0.4.0", + "miniz_oxide", ] [[package]] @@ -2209,22 +2203,13 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" -dependencies = [ - "adler 0.2.3", -] - [[package]] name = "miniz_oxide" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ - "adler 1.0.2", + "adler", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -4682,7 +4667,7 @@ dependencies = [ "hashbrown", "hermit-abi 0.2.6", "libc", - "miniz_oxide 0.5.3", + "miniz_oxide", "object", "panic_abort", "panic_unwind", From 41113b2c00afa28754375fde2a5d54fabfad2465 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 15:34:30 +0200 Subject: [PATCH 294/482] Port unknown feature diagnostic to the new framework --- compiler/rustc_codegen_llvm/src/errors.rs | 33 +++++++++++++++++++ compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/llvm_util.rs | 20 ++--------- .../locales/en-US/codegen_llvm.ftl | 14 ++++++++ compiler/rustc_error_messages/src/lib.rs | 1 + 5 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 compiler/rustc_codegen_llvm/src/errors.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs new file mode 100644 index 0000000000000..b1f85e656b821 --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -0,0 +1,33 @@ +use rustc_errors::DiagnosticBuilder; +use rustc_session::SessionDiagnostic; +use rustc_errors::fluent; + +pub(crate) enum UnknownCTargetFeature { + UnknownFeaturePrefix { feature: String }, + UnknownFeature { feature: String, rust_feature: Option }, +} + +impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature { + fn into_diagnostic(self, sess: &'_ rustc_session::parse::ParseSess) -> DiagnosticBuilder<'_, ()> { + match self { + UnknownCTargetFeature::UnknownFeaturePrefix { feature } => { + let mut diag = sess.struct_warn(fluent::codegen_llvm::unknown_ctarget_feature); + diag.set_arg("feature", feature); + diag.note(fluent::codegen_llvm::unknown_feature_prefix); + diag + } + UnknownCTargetFeature::UnknownFeature { feature, rust_feature } => { + let mut diag = sess.struct_warn(fluent::codegen_llvm::unknown_ctarget_feature); + diag.set_arg("feature", feature); + diag.note(fluent::codegen_llvm::unknown_feature); + if let Some(rust_feature) = rust_feature { + diag.help(fluent::codegen_llvm::rust_feature); + diag.set_arg("rust_feature", rust_feature); + } else { + diag.note(fluent::codegen_llvm::unknown_feature_fill_request); + } + diag + } + } + } +} \ No newline at end of file diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index d51aced85df43..af632b2ff54b9 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -62,6 +62,7 @@ mod context; mod coverageinfo; mod debuginfo; mod declare; +mod errors; mod intrinsic; // The following is a work around that replaces `pub mod llvm;` and that fixes issue 53912. diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 2fd58567c4874..f8f174692c06c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -1,5 +1,6 @@ use crate::back::write::create_informational_target_machine; use crate::llvm; +use crate::errors::UnknownCTargetFeature; use libc::c_int; use rustc_codegen_ssa::target_features::{ supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES, @@ -434,12 +435,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec c, Some(_) => { if diagnostics { - let mut diag = sess.struct_warn(&format!( - "unknown feature specified for `-Ctarget-feature`: `{}`", - s - )); - diag.note("features must begin with a `+` to enable or `-` to disable it"); - diag.emit(); + sess.emit_warning(UnknownCTargetFeature::UnknownFeaturePrefix { feature: s.to_string() }); } return None; } @@ -456,17 +452,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", codegen_gcc => "../locales/en-US/codegen_gcc.ftl", + codegen_llvm => "../locales/en-US/codegen_llvm.ftl", codegen_ssa => "../locales/en-US/codegen_ssa.ftl", compiletest => "../locales/en-US/compiletest.ftl", const_eval => "../locales/en-US/const_eval.ftl", From 5a598b7d9e64bc59f7fee1bfe7a3ee2afe7598de Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 15:42:20 +0200 Subject: [PATCH 295/482] Formatting --- compiler/rustc_codegen_llvm/src/errors.rs | 9 ++++++--- compiler/rustc_codegen_llvm/src/llvm_util.rs | 11 ++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index b1f85e656b821..c9af545a81823 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -1,6 +1,6 @@ +use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; use rustc_session::SessionDiagnostic; -use rustc_errors::fluent; pub(crate) enum UnknownCTargetFeature { UnknownFeaturePrefix { feature: String }, @@ -8,7 +8,10 @@ pub(crate) enum UnknownCTargetFeature { } impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature { - fn into_diagnostic(self, sess: &'_ rustc_session::parse::ParseSess) -> DiagnosticBuilder<'_, ()> { + fn into_diagnostic( + self, + sess: &'_ rustc_session::parse::ParseSess, + ) -> DiagnosticBuilder<'_, ()> { match self { UnknownCTargetFeature::UnknownFeaturePrefix { feature } => { let mut diag = sess.struct_warn(fluent::codegen_llvm::unknown_ctarget_feature); @@ -30,4 +33,4 @@ impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature { } } } -} \ No newline at end of file +} diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f8f174692c06c..81b325fee2d73 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -1,6 +1,6 @@ use crate::back::write::create_informational_target_machine; -use crate::llvm; use crate::errors::UnknownCTargetFeature; +use crate::llvm; use libc::c_int; use rustc_codegen_ssa::target_features::{ supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES, @@ -435,7 +435,9 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec c, Some(_) => { if diagnostics { - sess.emit_warning(UnknownCTargetFeature::UnknownFeaturePrefix { feature: s.to_string() }); + sess.emit_warning(UnknownCTargetFeature::UnknownFeaturePrefix { + feature: s.to_string(), + }); } return None; } @@ -452,7 +454,10 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Date: Thu, 25 Aug 2022 16:15:03 +0200 Subject: [PATCH 296/482] locales formatting --- compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 3c644d77bb7a8..c946aacf3859e 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -11,4 +11,4 @@ codegen_llvm_rust_feature = you might have meant: `{$rust_feature}` codegen_llvm_unknown_feature_fill_request = - consider filing a feature request \ No newline at end of file + consider filing a feature request From 68c6b7d22d666752e4c0cb20a3e52052336743ec Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 16:18:06 +0200 Subject: [PATCH 297/482] Trailing whitespaces --- .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index c946aacf3859e..33abf6ce5cfc8 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -1,10 +1,10 @@ -codegen_llvm_unknown_ctarget_feature = +codegen_llvm_unknown_ctarget_feature = unknown feature specified for `-Ctarget-feature`: `{$feature}` -codegen_llvm_unknown_feature_prefix = +codegen_llvm_unknown_feature_prefix = features must begin with a `+` to enable or `-` to disable it -codegen_llvm_unknown_feature = +codegen_llvm_unknown_feature = it is still passed through to the codegen backend codegen_llvm_rust_feature = From a93efbff77ed72f2192c83d7946ae6fbec3e531d Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 18:36:15 +0200 Subject: [PATCH 298/482] Change String in structs to &'a str --- compiler/rustc_codegen_llvm/src/errors.rs | 6 +++--- compiler/rustc_codegen_llvm/src/llvm_util.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index c9af545a81823..cf896f38c8c21 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -2,9 +2,9 @@ use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; use rustc_session::SessionDiagnostic; -pub(crate) enum UnknownCTargetFeature { - UnknownFeaturePrefix { feature: String }, - UnknownFeature { feature: String, rust_feature: Option }, +pub(crate) enum UnknownCTargetFeature<'a> { + UnknownFeaturePrefix { feature: &'a str }, + UnknownFeature { feature: &'a str, rust_feature: Option<&'a str> }, } impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature { diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 81b325fee2d73..f0122d5824f2a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -436,7 +436,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec { if diagnostics { sess.emit_warning(UnknownCTargetFeature::UnknownFeaturePrefix { - feature: s.to_string(), + feature: s, }); } return None; @@ -455,8 +455,8 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Date: Thu, 25 Aug 2022 19:23:55 +0200 Subject: [PATCH 299/482] Missing lifetime parameter and formatting --- compiler/rustc_codegen_llvm/src/errors.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm_util.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index cf896f38c8c21..a2b88c4af11ce 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -7,7 +7,7 @@ pub(crate) enum UnknownCTargetFeature<'a> { UnknownFeature { feature: &'a str, rust_feature: Option<&'a str> }, } -impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature { +impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { fn into_diagnostic( self, sess: &'_ rustc_session::parse::ParseSess, diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f0122d5824f2a..8f67913f91f0b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -454,10 +454,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Date: Thu, 25 Aug 2022 21:01:36 +0200 Subject: [PATCH 300/482] Import `error creating import library` --- compiler/rustc_codegen_llvm/src/back/archive.rs | 8 ++++---- compiler/rustc_codegen_llvm/src/errors.rs | 8 ++++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 082665bba3802..4fd8b0ef4bb70 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -12,6 +12,7 @@ use std::str; use object::read::macho::FatArch; use crate::common; +use crate::errors::ErrorCreatingImportLibrary; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; @@ -293,11 +294,10 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { }; if result == crate::llvm::LLVMRustResult::Failure { - sess.fatal(&format!( - "Error creating import library for {}: {}", + sess.emit_fatal(ErrorCreatingImportLibrary { lib_name, - llvm::last_error().unwrap_or("unknown LLVM error".to_string()) - )); + error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()), + }); } }; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index a2b88c4af11ce..03e55c72e222e 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -1,5 +1,6 @@ use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; +use rustc_macros::SessionDiagnostic; use rustc_session::SessionDiagnostic; pub(crate) enum UnknownCTargetFeature<'a> { @@ -34,3 +35,10 @@ impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { } } } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::error_creating_import_library)] +pub(crate) struct ErrorCreatingImportLibrary<'a> { + pub lib_name: &'a str, + pub error: String, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 33abf6ce5cfc8..bfd3d5f033a86 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -12,3 +12,6 @@ codegen_llvm_rust_feature = codegen_llvm_unknown_feature_fill_request = consider filing a feature request + +codegen_llvm_error_creating_import_library = + Error creating import library for {$lib_name}: {$error} From 7c9ae0974fe54d441700324d84c1158a898135ce Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 23:08:18 +0200 Subject: [PATCH 301/482] Port Instrument coverage requires llvm 12 to the new struct --- compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 4 ++++ compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 433f043209e53..8a8d889a29865 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -1,5 +1,6 @@ use crate::common::CodegenCx; use crate::coverageinfo; +use crate::errors::InstrumentCoverageRequiresLLVM12; use crate::llvm; use llvm::coverageinfo::CounterMappingRegion; @@ -37,7 +38,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { // LLVM 12. let version = coverageinfo::mapping_version(); if version < 4 { - tcx.sess.fatal("rustc option `-C instrument-coverage` requires LLVM 12 or higher."); + tcx.sess.emit_fatal(InstrumentCoverageRequiresLLVM12); } debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name()); diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 03e55c72e222e..b06ad78cf7b96 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -42,3 +42,7 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> { pub lib_name: &'a str, pub error: String, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::instrument_coverage_requires_llvm_12)] +pub(crate) struct InstrumentCoverageRequiresLLVM12; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index bfd3d5f033a86..9f75d5a0e4752 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -15,3 +15,6 @@ codegen_llvm_unknown_feature_fill_request = codegen_llvm_error_creating_import_library = Error creating import library for {$lib_name}: {$error} + +codegen_llvm_instrument_coverage_requires_llvm_12 = + rustc option `-C instrument-coverage` requires LLVM 12 or higher. From 8c7822a73da9a52021c049c559d322313f1fef03 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 23:30:17 +0200 Subject: [PATCH 302/482] Port `symbol_already_defined` error --- compiler/rustc_codegen_llvm/src/errors.rs | 9 +++++++++ compiler/rustc_codegen_llvm/src/mono_item.rs | 5 +---- .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index b06ad78cf7b96..34b2c844f5032 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -2,6 +2,7 @@ use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; use rustc_macros::SessionDiagnostic; use rustc_session::SessionDiagnostic; +use rustc_span::Span; pub(crate) enum UnknownCTargetFeature<'a> { UnknownFeaturePrefix { feature: &'a str }, @@ -46,3 +47,11 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> { #[derive(SessionDiagnostic)] #[diag(codegen_llvm::instrument_coverage_requires_llvm_12)] pub(crate) struct InstrumentCoverageRequiresLLVM12; + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::SymbolAlreadyDefined)] +pub(crate) struct SymbolAlreadyDefined<'a> { + #[primary_span] + pub span: Span, + pub symbol_name: &'a str, +} diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 1eceb7f5c87be..d5096873c4378 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -25,10 +25,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> { let llty = self.layout_of(ty).llvm_type(self); let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { - self.sess().span_fatal( - self.tcx.def_span(def_id), - &format!("symbol `{}` is already defined", symbol_name), - ) + self.sess().emit_fatal(SymbolAlreadyDefined { span: self.tcx.def_span(def_id), symbol_name }) }); unsafe { diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 9f75d5a0e4752..c1222d3db5f76 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -18,3 +18,6 @@ codegen_llvm_error_creating_import_library = codegen_llvm_instrument_coverage_requires_llvm_12 = rustc option `-C instrument-coverage` requires LLVM 12 or higher. + +codegen_llvm_symbol_already_defined = + symbol `{$symbol_name}` is already defined From 7e81e3696938f350cb85770deceb5e5aa95324cb Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 25 Aug 2022 23:47:11 +0200 Subject: [PATCH 303/482] Fix diag() and formatting --- compiler/rustc_codegen_llvm/src/errors.rs | 2 +- compiler/rustc_codegen_llvm/src/mono_item.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 34b2c844f5032..ed435e555d7e7 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -49,7 +49,7 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> { pub(crate) struct InstrumentCoverageRequiresLLVM12; #[derive(SessionDiagnostic)] -#[diag(codegen_llvm::SymbolAlreadyDefined)] +#[diag(codegen_llvm::symbol_already_defined)] pub(crate) struct SymbolAlreadyDefined<'a> { #[primary_span] pub span: Span, diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index d5096873c4378..76f692b2016fd 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -1,6 +1,7 @@ use crate::attributes; use crate::base; use crate::context::CodegenCx; +use crate::errors::SymbolAlreadyDefined; use crate::llvm; use crate::type_of::LayoutLlvmExt; use rustc_codegen_ssa::traits::*; @@ -25,7 +26,8 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> { let llty = self.layout_of(ty).llvm_type(self); let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { - self.sess().emit_fatal(SymbolAlreadyDefined { span: self.tcx.def_span(def_id), symbol_name }) + self.sess() + .emit_fatal(SymbolAlreadyDefined { span: self.tcx.def_span(def_id), symbol_name }) }); unsafe { From b86d7695992f1e99d861140bb1432edffc4da8fe Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 00:03:53 +0200 Subject: [PATCH 304/482] Port branch protection on aarch64 --- compiler/rustc_codegen_llvm/src/context.rs | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 4 ++++ compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c22ec128dacb0..3ac0778e3bd4e 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -3,6 +3,7 @@ use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; +use crate::errors::BranchProtectionRequiresAArch64; use crate::llvm; use crate::llvm_util; use crate::type_::Type; @@ -275,7 +276,7 @@ pub unsafe fn create_module<'ll>( if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection { if sess.target.arch != "aarch64" { - sess.err("-Zbranch-protection is only supported on aarch64"); + sess.emit_err(BranchProtectionRequiresAArch64); } else { llvm::LLVMRustAddModuleFlag( llmod, diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index ed435e555d7e7..e740e02dd1c28 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -55,3 +55,7 @@ pub(crate) struct SymbolAlreadyDefined<'a> { pub span: Span, pub symbol_name: &'a str, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::branch_protection_requires_aarch64)] +pub(crate) struct BranchProtectionRequiresAArch64; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index c1222d3db5f76..4fd3d364b4799 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -21,3 +21,6 @@ codegen_llvm_instrument_coverage_requires_llvm_12 = codegen_llvm_symbol_already_defined = symbol `{$symbol_name}` is already defined + +codegen_llvm_branch_protection_requires_aarch64 = + -Zbranch-protection is only supported on aarch64 From cfce73e878f93eb062d3db3a402daeac51e1d14a Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 00:08:05 +0200 Subject: [PATCH 305/482] Formatting --- compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 4fd3d364b4799..d713183f57296 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -19,7 +19,7 @@ codegen_llvm_error_creating_import_library = codegen_llvm_instrument_coverage_requires_llvm_12 = rustc option `-C instrument-coverage` requires LLVM 12 or higher. -codegen_llvm_symbol_already_defined = +codegen_llvm_symbol_already_defined = symbol `{$symbol_name}` is already defined codegen_llvm_branch_protection_requires_aarch64 = From 835d250abbd3ef5aacada3e50a50dc65c7104593 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 10:14:15 +0200 Subject: [PATCH 306/482] Port layout size overflow --- compiler/rustc_codegen_llvm/src/context.rs | 5 +++-- compiler/rustc_codegen_llvm/src/errors.rs | 8 ++++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 3ac0778e3bd4e..7ed4df16ea99f 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -4,6 +4,7 @@ use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; use crate::errors::BranchProtectionRequiresAArch64; +use crate::errors::LayoutSizeOverflow; use crate::llvm; use crate::llvm_util; use crate::type_::Type; @@ -952,7 +953,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let LayoutError::SizeOverflow(_) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(LayoutSizeOverflow { span, error: err.to_string() }) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) } @@ -970,7 +971,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(LayoutSizeOverflow { span, error: err.to_string() }) } else { match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index e740e02dd1c28..95a12d98d5cf5 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -59,3 +59,11 @@ pub(crate) struct SymbolAlreadyDefined<'a> { #[derive(SessionDiagnostic)] #[diag(codegen_llvm::branch_protection_requires_aarch64)] pub(crate) struct BranchProtectionRequiresAArch64; + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::layout_size_overflow)] +pub(crate) struct LayoutSizeOverflow { + #[primary_span] + pub span: Span, + pub error: String, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index d713183f57296..75c6547a44482 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -24,3 +24,6 @@ codegen_llvm_symbol_already_defined = codegen_llvm_branch_protection_requires_aarch64 = -Zbranch-protection is only supported on aarch64 + +codegen_llvm_layout_size_overflow = + {$error} From ea57ea805b45aa61b27735d55f3f3b718a6dc55a Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 10:30:43 +0200 Subject: [PATCH 307/482] Port InvalidMinimumAlignment --- compiler/rustc_codegen_llvm/src/consts.rs | 5 ++++- compiler/rustc_codegen_llvm/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index bf5ac4e503e3f..05fa87c80946f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -1,6 +1,7 @@ use crate::base; use crate::common::{self, CodegenCx}; use crate::debuginfo; +use crate::errors::InvalidMinimumAlignment; use crate::llvm::{self, True}; use crate::llvm_util; use crate::type_::Type; @@ -146,7 +147,9 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: match Align::from_bits(min) { Ok(min) => align = align.max(min), Err(err) => { - cx.sess().err(&format!("invalid minimum global alignment: {}", err)); + cx.sess().emit_err(InvalidMinimumAlignment { + err, + }); } } } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 95a12d98d5cf5..8c87d9eb1fbca 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -67,3 +67,9 @@ pub(crate) struct LayoutSizeOverflow { pub span: Span, pub error: String, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::invalid_minimum_alignment)] +pub(crate) struct InvalidMinimumAlignment { + pub err: String +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 75c6547a44482..1c38bbdce16ca 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -27,3 +27,6 @@ codegen_llvm_branch_protection_requires_aarch64 = codegen_llvm_layout_size_overflow = {$error} + +codegen_llvm_invalid_minimum_alignment = + invalid minimum global alignment: {$err} From 4a6c9e4190b86063ffc894dd136d1a6db3d33bcd Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 10:40:48 +0200 Subject: [PATCH 308/482] Port LinkageConstOrMutType error --- compiler/rustc_codegen_llvm/src/consts.rs | 11 +++-------- compiler/rustc_codegen_llvm/src/errors.rs | 9 ++++++++- .../locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 05fa87c80946f..07c46e9363214 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -1,7 +1,7 @@ use crate::base; use crate::common::{self, CodegenCx}; use crate::debuginfo; -use crate::errors::InvalidMinimumAlignment; +use crate::errors::{InvalidMinimumAlignment, LinkageConstOrMutType}; use crate::llvm::{self, True}; use crate::llvm_util; use crate::type_::Type; @@ -147,9 +147,7 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: match Align::from_bits(min) { Ok(min) => align = align.max(min), Err(err) => { - cx.sess().emit_err(InvalidMinimumAlignment { - err, - }); + cx.sess().emit_err(InvalidMinimumAlignment { err }); } } } @@ -177,10 +175,7 @@ fn check_and_apply_linkage<'ll, 'tcx>( let llty2 = if let ty::RawPtr(ref mt) = ty.kind() { cx.layout_of(mt.ty).llvm_type(cx) } else { - cx.sess().span_fatal( - cx.tcx.def_span(def_id), - "must have type `*const T` or `*mut T` due to `#[linkage]` attribute", - ) + cx.sess().emit_fatal(LinkageConstOrMutType { span: cx.tcx.def_span(def_id) }) }; unsafe { // Declare a symbol `foo` with the desired linkage. diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 8c87d9eb1fbca..2661bd3cb9979 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -71,5 +71,12 @@ pub(crate) struct LayoutSizeOverflow { #[derive(SessionDiagnostic)] #[diag(codegen_llvm::invalid_minimum_alignment)] pub(crate) struct InvalidMinimumAlignment { - pub err: String + pub err: String, +} + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::linkage_const_or_mut_type)] +pub(crate) struct LinkageConstOrMutType { + #[primary_span] + pub span: Span, } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 1c38bbdce16ca..3804f0dbbfabc 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -30,3 +30,6 @@ codegen_llvm_layout_size_overflow = codegen_llvm_invalid_minimum_alignment = invalid minimum global alignment: {$err} + +codegen_llvm_linkage_const_or_mut_type = + must have type `*const T` or `*mut T` due to `#[linkage]` attribute From 5fbe72eed86f381dd7a3d447ac9a1aa3e211d3b9 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 11:48:35 +0200 Subject: [PATCH 309/482] Reuse SymbolAlreadyDefined --- compiler/rustc_codegen_llvm/src/consts.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 07c46e9363214..3b504d3a7df75 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -1,7 +1,7 @@ use crate::base; use crate::common::{self, CodegenCx}; use crate::debuginfo; -use crate::errors::{InvalidMinimumAlignment, LinkageConstOrMutType}; +use crate::errors::{InvalidMinimumAlignment, LinkageConstOrMutType, SymbolAlreadyDefined}; use crate::llvm::{self, True}; use crate::llvm_util; use crate::type_::Type; @@ -191,10 +191,10 @@ fn check_and_apply_linkage<'ll, 'tcx>( let mut real_name = "_rust_extern_with_linkage_".to_string(); real_name.push_str(sym); let g2 = cx.define_global(&real_name, llty).unwrap_or_else(|| { - cx.sess().span_fatal( - cx.tcx.def_span(def_id), - &format!("symbol `{}` is already defined", &sym), - ) + cx.sess().emit_fatal(SymbolAlreadyDefined { + span: cx.tcx.def_span(def_id), + symbol_name: sym, + }) }); llvm::LLVMRustSetLinkage(g2, llvm::Linkage::InternalLinkage); llvm::LLVMSetInitializer(g2, g1); From d8dfd3e5f00963b3d61982702486ffdbe9e8c1b3 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 12:19:10 +0200 Subject: [PATCH 310/482] Port SanitizerMemtagRequiresMte --- compiler/rustc_codegen_llvm/src/attributes.rs | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 4 ++++ compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index d96da5cc11d1f..02eef10407730 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -12,6 +12,7 @@ use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtec use smallvec::SmallVec; use crate::attributes; +use crate::errors::SanitizerMemtagRequiresMte; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; use crate::llvm_util; @@ -82,7 +83,7 @@ pub fn sanitize_attrs<'ll>( let mte_feature = features.iter().map(|s| &s[..]).rfind(|n| ["+mte", "-mte"].contains(&&n[..])); if let None | Some("-mte") = mte_feature { - cx.tcx.sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`"); + cx.tcx.sess.emit_err(SanitizerMemtagRequiresMte); } attrs.push(llvm::AttributeKind::SanitizeMemTag.create_attr(cx.llcx)); diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 2661bd3cb9979..a652fb4c2a085 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -80,3 +80,7 @@ pub(crate) struct LinkageConstOrMutType { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::sanitizer_memtag_requires_mte)] +pub(crate) struct SanitizerMemtagRequiresMte; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 3804f0dbbfabc..e4e1abfe21971 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -33,3 +33,6 @@ codegen_llvm_invalid_minimum_alignment = codegen_llvm_linkage_const_or_mut_type = must have type `*const T` or `*mut T` due to `#[linkage]` attribute + +codegen_llvm_sanitizer_memtag_requires_mte = + `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte` From 7c00af0bfcb352feabad96aa87b148741c001e9f Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 14:11:47 +0200 Subject: [PATCH 311/482] Port ArchiveBuildFailure --- compiler/rustc_codegen_llvm/src/back/archive.rs | 4 ++-- compiler/rustc_codegen_llvm/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 4fd8b0ef4bb70..e6ab0e74b7d0d 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -12,7 +12,7 @@ use std::str; use object::read::macho::FatArch; use crate::common; -use crate::errors::ErrorCreatingImportLibrary; +use crate::errors::{ErrorCreatingImportLibrary, ArchiveBuildFailure}; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; @@ -148,7 +148,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { fn build(mut self: Box, output: &Path) -> bool { match self.build_with_llvm(output) { Ok(any_members) => any_members, - Err(e) => self.sess.fatal(&format!("failed to build archive: {}", e)), + Err(e) => self.sess.emit_fatal(ArchiveBuildFailure { error: e }), } } } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index a652fb4c2a085..12ea4166cf46d 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -84,3 +84,9 @@ pub(crate) struct LinkageConstOrMutType { #[derive(SessionDiagnostic)] #[diag(codegen_llvm::sanitizer_memtag_requires_mte)] pub(crate) struct SanitizerMemtagRequiresMte; + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::archive_build_failure)] +pub(crate) struct ArchiveBuildFailure { + pub error: std::io::Error, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index e4e1abfe21971..7ce1bb18d62fb 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -36,3 +36,6 @@ codegen_llvm_linkage_const_or_mut_type = codegen_llvm_sanitizer_memtag_requires_mte = `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte` + +codegen_llvm_archive_build_failure = + failed to build archive: {$error} From 1d74ef5368c20f5a798cbc93f909cd3d35f60a1c Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 14:17:15 +0200 Subject: [PATCH 312/482] Import ErrorWritingDEFFile --- compiler/rustc_codegen_llvm/src/back/archive.rs | 4 ++-- compiler/rustc_codegen_llvm/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index e6ab0e74b7d0d..01d4cda18d470 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -12,7 +12,7 @@ use std::str; use object::read::macho::FatArch; use crate::common; -use crate::errors::{ErrorCreatingImportLibrary, ArchiveBuildFailure}; +use crate::errors::{ArchiveBuildFailure, ErrorCreatingImportLibrary, ErrorWritingDEFFile}; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; @@ -218,7 +218,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { match std::fs::write(&def_file_path, def_file_content) { Ok(_) => {} Err(e) => { - sess.fatal(&format!("Error writing .DEF file: {}", e)); + sess.emit_fatal(ErrorWritingDEFFile { error: e }); } }; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 12ea4166cf46d..b7962fd0bae7a 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -90,3 +90,9 @@ pub(crate) struct SanitizerMemtagRequiresMte; pub(crate) struct ArchiveBuildFailure { pub error: std::io::Error, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::error_writing_def_file)] +pub(crate) struct ErrorWritingDEFFile { + pub error: std::io::Error, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 7ce1bb18d62fb..c26c11612cda9 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -39,3 +39,6 @@ codegen_llvm_sanitizer_memtag_requires_mte = codegen_llvm_archive_build_failure = failed to build archive: {$error} + +codegen_llvm_error_writing_def_file = + Error writing .DEF file: {$error} From 9d4a3e5a81c7ef8e2913850e7c616d8bfaa36d9e Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 14:29:33 +0200 Subject: [PATCH 313/482] Port ErrorCallingDllTool --- compiler/rustc_codegen_llvm/src/back/archive.rs | 6 ++++-- compiler/rustc_codegen_llvm/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 01d4cda18d470..e73e122ee68d1 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -12,7 +12,9 @@ use std::str; use object::read::macho::FatArch; use crate::common; -use crate::errors::{ArchiveBuildFailure, ErrorCreatingImportLibrary, ErrorWritingDEFFile}; +use crate::errors::{ + ArchiveBuildFailure, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, +}; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; @@ -240,7 +242,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { match result { Err(e) => { - sess.fatal(&format!("Error calling dlltool: {}", e)); + sess.emit_fatal(ErrorCallingDllTool { error: e }); } Ok(output) if !output.status.success() => sess.fatal(&format!( "Dlltool could not create import library: {}\n{}", diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index b7962fd0bae7a..4856cead1521b 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -96,3 +96,9 @@ pub(crate) struct ArchiveBuildFailure { pub(crate) struct ErrorWritingDEFFile { pub error: std::io::Error, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::error_calling_dlltool)] +pub(crate) struct ErrorCallingDllTool { + pub error: std::io::Error, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index c26c11612cda9..3c8a893b4a5a1 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -42,3 +42,6 @@ codegen_llvm_archive_build_failure = codegen_llvm_error_writing_def_file = Error writing .DEF file: {$error} + +codegen_llvm_error_calling_dlltool = + Error calling dlltool: {$error} From d0c94bb3467901b1cb11588e947c489a5e0bc1e4 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 19:01:22 +0200 Subject: [PATCH 314/482] Port `DlltoolFailImportLibrary` and implement `IntoDiagnosticArg` for `Cow<'a, str>` --- compiler/rustc_codegen_llvm/src/back/archive.rs | 14 ++++++++------ compiler/rustc_codegen_llvm/src/errors.rs | 9 +++++++++ .../locales/en-US/codegen_llvm.ftl | 3 +++ compiler/rustc_errors/src/diagnostic_impls.rs | 6 ++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index e73e122ee68d1..9be104fde6c4c 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -13,7 +13,8 @@ use object::read::macho::FatArch; use crate::common; use crate::errors::{ - ArchiveBuildFailure, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, + ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, + ErrorWritingDEFFile, }; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; @@ -244,11 +245,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { Err(e) => { sess.emit_fatal(ErrorCallingDllTool { error: e }); } - Ok(output) if !output.status.success() => sess.fatal(&format!( - "Dlltool could not create import library: {}\n{}", - String::from_utf8_lossy(&output.stdout), - String::from_utf8_lossy(&output.stderr) - )), + Ok(output) if !output.status.success() => { + sess.emit_fatal(DlltoolFailImportLibrary { + stdout: String::from_utf8_lossy(&output.stdout), + stderr: String::from_utf8_lossy(&output.stderr), + }) + } _ => {} } } else { diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 4856cead1521b..68c2e69283041 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; use rustc_macros::SessionDiagnostic; @@ -102,3 +104,10 @@ pub(crate) struct ErrorWritingDEFFile { pub(crate) struct ErrorCallingDllTool { pub error: std::io::Error, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::dlltool_fail_import_library)] +pub(crate) struct DlltoolFailImportLibrary<'a> { + pub stdout: Cow<'a, str>, + pub stderr: Cow<'a, str>, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 3c8a893b4a5a1..f9266b54d137a 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -45,3 +45,6 @@ codegen_llvm_error_writing_def_file = codegen_llvm_error_calling_dlltool = Error calling dlltool: {$error} + +codegen_llvm_dlltool_fail_import_library = + Dlltool could not create import library: {$stdout}\n{$stderr} diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 22f6fc700fad3..c6035705e39fa 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -107,6 +107,12 @@ impl IntoDiagnosticArg for String { } } +impl<'a> IntoDiagnosticArg for Cow<'a, str> { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.into_owned())) + } +} + impl<'a> IntoDiagnosticArg for &'a Path { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Owned(self.display().to_string())) From 8c33f4f15461a7500eb4cbbaf5e53648ba1235bb Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 19:42:29 +0200 Subject: [PATCH 315/482] Port `UnknownArchiveKind` --- compiler/rustc_codegen_llvm/src/back/archive.rs | 9 +++++---- compiler/rustc_codegen_llvm/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 +++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 9be104fde6c4c..99c9b51a9cdaa 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -14,7 +14,7 @@ use object::read::macho::FatArch; use crate::common; use crate::errors::{ ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, - ErrorWritingDEFFile, + ErrorWritingDEFFile, UnknownArchiveKind, }; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; @@ -312,9 +312,10 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { impl<'a> LlvmArchiveBuilder<'a> { fn build_with_llvm(&mut self, output: &Path) -> io::Result { let kind = &*self.sess.target.archive_format; - let kind = kind.parse::().map_err(|_| kind).unwrap_or_else(|kind| { - self.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)) - }); + let kind = kind + .parse::() + .map_err(|_| kind) + .unwrap_or_else(|kind| self.sess.emit_fatal(UnknownArchiveKind { kind: kind })); let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 68c2e69283041..1fe88cc248246 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -111,3 +111,9 @@ pub(crate) struct DlltoolFailImportLibrary<'a> { pub stdout: Cow<'a, str>, pub stderr: Cow<'a, str>, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_llvm::unknown_archive_kind)] +pub(crate) struct UnknownArchiveKind<'a> { + pub kind: &'a str, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index f9266b54d137a..67160ca28820b 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -48,3 +48,6 @@ codegen_llvm_error_calling_dlltool = codegen_llvm_dlltool_fail_import_library = Dlltool could not create import library: {$stdout}\n{$stderr} + +codegen_llvm_unknown_archive_kind = + Don't know how to build archive of type: {$kind} From 297a52c39eabcf0ca5ee26deec9626ccb76d760a Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 26 Aug 2022 21:27:17 +0200 Subject: [PATCH 316/482] Port `MissingFeatures` and `TargetFeatureDisableOrEnable` --- compiler/rustc_codegen_llvm/src/attributes.rs | 14 ++++----- compiler/rustc_codegen_llvm/src/errors.rs | 29 ++++++++++++++++++- compiler/rustc_codegen_llvm/src/llvm_util.rs | 10 +++---- .../locales/en-US/codegen_llvm.ftl | 6 ++++ 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 02eef10407730..ce54c28138432 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -12,7 +12,7 @@ use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtec use smallvec::SmallVec; use crate::attributes; -use crate::errors::SanitizerMemtagRequiresMte; +use crate::errors::{MissingFeatures, SanitizerMemtagRequiresMte, TargetFeatureDisableOrEnable}; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; use crate::llvm_util; @@ -394,13 +394,11 @@ pub fn from_fn_attrs<'ll, 'tcx>( .get_attrs(instance.def_id(), sym::target_feature) .next() .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span); - let msg = format!( - "the target features {} must all be either enabled or disabled together", - f.join(", ") - ); - let mut err = cx.tcx.sess.struct_span_err(span, &msg); - err.help("add the missing features in a `target_feature` attribute"); - err.emit(); + cx.tcx + .sess + .create_err(TargetFeatureDisableOrEnable { features: f, span: Some(span) }) + .subdiagnostic(MissingFeatures) + .emit(); return; } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 1fe88cc248246..cd53ac4532ae6 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -2,7 +2,8 @@ use std::borrow::Cow; use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; -use rustc_macros::SessionDiagnostic; +use rustc_errors::ErrorGuaranteed; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_session::SessionDiagnostic; use rustc_span::Span; @@ -117,3 +118,29 @@ pub(crate) struct DlltoolFailImportLibrary<'a> { pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } + +pub(crate) struct TargetFeatureDisableOrEnable<'a> { + pub features: &'a [&'a str], + pub span: Option, +} + +#[derive(SessionSubdiagnostic)] +#[help(codegen_llvm::missing_features)] +pub(crate) struct MissingFeatures; + +impl SessionDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { + fn into_diagnostic( + self, + sess: &'_ rustc_session::parse::ParseSess, + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = if let Some(span) = self.span { + let mut diag = sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable); + diag.set_span(span); + diag + } else { + sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable) + }; + diag.set_arg("features", self.features.join(", ")); + diag + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 8f67913f91f0b..8c2db38d84d8c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -1,5 +1,5 @@ use crate::back::write::create_informational_target_machine; -use crate::errors::UnknownCTargetFeature; +use crate::errors::{TargetFeatureDisableOrEnable, UnknownCTargetFeature}; use crate::llvm; use libc::c_int; use rustc_codegen_ssa::target_features::{ @@ -480,10 +480,10 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Date: Sat, 27 Aug 2022 10:05:50 +0200 Subject: [PATCH 317/482] Fix CI Add missing 'the' to the error en-US translation --- compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 4113e6640d6e3..940f727b21ddf 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -53,7 +53,7 @@ codegen_llvm_unknown_archive_kind = Don't know how to build archive of type: {$kind} codegen_llvm_target_feature_disable_or_enable = - target features {$features} must all be enabled or disabled together + the target features {$features} must all be enabled or disabled together codegen_llvm_missing_features = add the missing features in a `target_feature` attribute From 5600845303ad6ae03b68b8b0f6b3c065d7e95a91 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Tue, 30 Aug 2022 12:22:08 +0200 Subject: [PATCH 318/482] Correct tests to match errors --- compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl | 2 +- src/test/ui/target-feature/tied-features-cli.one.stderr | 2 +- src/test/ui/target-feature/tied-features-cli.three.stderr | 2 +- src/test/ui/target-feature/tied-features-cli.two.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 940f727b21ddf..9d80b98f56c65 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -53,7 +53,7 @@ codegen_llvm_unknown_archive_kind = Don't know how to build archive of type: {$kind} codegen_llvm_target_feature_disable_or_enable = - the target features {$features} must all be enabled or disabled together + the target features {$features} must all be either enabled or disabled together codegen_llvm_missing_features = add the missing features in a `target_feature` attribute diff --git a/src/test/ui/target-feature/tied-features-cli.one.stderr b/src/test/ui/target-feature/tied-features-cli.one.stderr index 0cc901eecaa2c..b4b50d98192b1 100644 --- a/src/test/ui/target-feature/tied-features-cli.one.stderr +++ b/src/test/ui/target-feature/tied-features-cli.one.stderr @@ -1,4 +1,4 @@ -error: target features paca, pacg must all be enabled or disabled together +error: the target features paca, pacg must all be either enabled or disabled together error: aborting due to previous error diff --git a/src/test/ui/target-feature/tied-features-cli.three.stderr b/src/test/ui/target-feature/tied-features-cli.three.stderr index 0cc901eecaa2c..b4b50d98192b1 100644 --- a/src/test/ui/target-feature/tied-features-cli.three.stderr +++ b/src/test/ui/target-feature/tied-features-cli.three.stderr @@ -1,4 +1,4 @@ -error: target features paca, pacg must all be enabled or disabled together +error: the target features paca, pacg must all be either enabled or disabled together error: aborting due to previous error diff --git a/src/test/ui/target-feature/tied-features-cli.two.stderr b/src/test/ui/target-feature/tied-features-cli.two.stderr index 0cc901eecaa2c..b4b50d98192b1 100644 --- a/src/test/ui/target-feature/tied-features-cli.two.stderr +++ b/src/test/ui/target-feature/tied-features-cli.two.stderr @@ -1,4 +1,4 @@ -error: target features paca, pacg must all be enabled or disabled together +error: the target features paca, pacg must all be either enabled or disabled together error: aborting due to previous error From 23ff4a9b42b409dc817eb03ed6e4ace193e97638 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Sun, 30 Oct 2022 14:33:27 +0100 Subject: [PATCH 319/482] Flatten diagnostic structs --- compiler/rustc_codegen_llvm/src/errors.rs | 91 +++++++++++------------ 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index cd53ac4532ae6..db3ca6a7783e1 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -3,8 +3,9 @@ use std::borrow::Cow; use rustc_errors::fluent; use rustc_errors::DiagnosticBuilder; use rustc_errors::ErrorGuaranteed; -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use rustc_session::SessionDiagnostic; +use rustc_errors::Handler; +use rustc_errors::IntoDiagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; pub(crate) enum UnknownCTargetFeature<'a> { @@ -12,27 +13,24 @@ pub(crate) enum UnknownCTargetFeature<'a> { UnknownFeature { feature: &'a str, rust_feature: Option<&'a str> }, } -impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { - fn into_diagnostic( - self, - sess: &'_ rustc_session::parse::ParseSess, - ) -> DiagnosticBuilder<'_, ()> { +impl IntoDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { + fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ()> { match self { UnknownCTargetFeature::UnknownFeaturePrefix { feature } => { - let mut diag = sess.struct_warn(fluent::codegen_llvm::unknown_ctarget_feature); + let mut diag = sess.struct_warn(fluent::codegen_llvm_unknown_ctarget_feature); diag.set_arg("feature", feature); - diag.note(fluent::codegen_llvm::unknown_feature_prefix); + diag.note(fluent::codegen_llvm_unknown_feature_prefix); diag } UnknownCTargetFeature::UnknownFeature { feature, rust_feature } => { - let mut diag = sess.struct_warn(fluent::codegen_llvm::unknown_ctarget_feature); + let mut diag = sess.struct_warn(fluent::codegen_llvm_unknown_ctarget_feature); diag.set_arg("feature", feature); - diag.note(fluent::codegen_llvm::unknown_feature); + diag.note(fluent::codegen_llvm_unknown_feature); if let Some(rust_feature) = rust_feature { - diag.help(fluent::codegen_llvm::rust_feature); + diag.help(fluent::codegen_llvm_rust_feature); diag.set_arg("rust_feature", rust_feature); } else { - diag.note(fluent::codegen_llvm::unknown_feature_fill_request); + diag.note(fluent::codegen_llvm_unknown_feature_fill_request); } diag } @@ -40,81 +38,81 @@ impl SessionDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { } } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::error_creating_import_library)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_error_creating_import_library)] pub(crate) struct ErrorCreatingImportLibrary<'a> { pub lib_name: &'a str, pub error: String, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::instrument_coverage_requires_llvm_12)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_instrument_coverage_requires_llvm_12)] pub(crate) struct InstrumentCoverageRequiresLLVM12; -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::symbol_already_defined)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_symbol_already_defined)] pub(crate) struct SymbolAlreadyDefined<'a> { #[primary_span] pub span: Span, pub symbol_name: &'a str, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::branch_protection_requires_aarch64)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_branch_protection_requires_aarch64)] pub(crate) struct BranchProtectionRequiresAArch64; -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::layout_size_overflow)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_layout_size_overflow)] pub(crate) struct LayoutSizeOverflow { #[primary_span] pub span: Span, pub error: String, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::invalid_minimum_alignment)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_invalid_minimum_alignment)] pub(crate) struct InvalidMinimumAlignment { pub err: String, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::linkage_const_or_mut_type)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_linkage_const_or_mut_type)] pub(crate) struct LinkageConstOrMutType { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::sanitizer_memtag_requires_mte)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_sanitizer_memtag_requires_mte)] pub(crate) struct SanitizerMemtagRequiresMte; -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::archive_build_failure)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_archive_build_failure)] pub(crate) struct ArchiveBuildFailure { pub error: std::io::Error, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::error_writing_def_file)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_error_writing_def_file)] pub(crate) struct ErrorWritingDEFFile { pub error: std::io::Error, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::error_calling_dlltool)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_error_calling_dlltool)] pub(crate) struct ErrorCallingDllTool { pub error: std::io::Error, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::dlltool_fail_import_library)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_dlltool_fail_import_library)] pub(crate) struct DlltoolFailImportLibrary<'a> { pub stdout: Cow<'a, str>, pub stderr: Cow<'a, str>, } -#[derive(SessionDiagnostic)] -#[diag(codegen_llvm::unknown_archive_kind)] +#[derive(Diagnostic)] +#[diag(codegen_llvm_unknown_archive_kind)] pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } @@ -124,21 +122,18 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub span: Option, } -#[derive(SessionSubdiagnostic)] -#[help(codegen_llvm::missing_features)] +#[derive(Subdiagnostic)] +#[help(codegen_llvm_missing_features)] pub(crate) struct MissingFeatures; -impl SessionDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic( - self, - sess: &'_ rustc_session::parse::ParseSess, - ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { +impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { + fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = if let Some(span) = self.span { - let mut diag = sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable); + let mut diag = sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); diag.set_span(span); diag } else { - sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable) + sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable) }; diag.set_arg("features", self.features.join(", ")); diag From b72e356cdd838e5a86252a58bac74349b045d07c Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Sun, 30 Oct 2022 16:07:04 +0100 Subject: [PATCH 320/482] Port diagnostics created by `Handler` --- compiler/rustc_codegen_llvm/src/back/lto.rs | 9 ++------- compiler/rustc_codegen_llvm/src/errors.rs | 11 +++++++++++ compiler/rustc_codegen_llvm/src/lib.rs | 5 ++++- .../locales/en-US/codegen_llvm.ftl | 7 +++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index a49cc7f8d662d..3fa21355b7f4c 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -1,4 +1,5 @@ use crate::back::write::{self, save_temp_bitcode, DiagnosticHandlers}; +use crate::errors::DynamicLinkingWithLTO; use crate::llvm::{self, build_string}; use crate::{LlvmCodegenBackend, ModuleLlvm}; use object::read::archive::ArchiveFile; @@ -90,13 +91,7 @@ fn prepare_lto( } if cgcx.opts.cg.prefer_dynamic && !cgcx.opts.unstable_opts.dylib_lto { - diag_handler - .struct_err("cannot prefer dynamic linking when performing LTO") - .note( - "only 'staticlib', 'bin', and 'cdylib' outputs are \ - supported with LTO", - ) - .emit(); + diag_handler.emit_err(DynamicLinkingWithLTO); return Err(FatalError); } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index db3ca6a7783e1..c08827b952191 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -117,6 +117,17 @@ pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } +#[derive(Diagnostic)] +#[diag(codegen_llvm_dynamic_linking_with_lto)] +#[note] +pub(crate) struct DynamicLinkingWithLTO; + +#[derive(Diagnostic)] +#[diag(codegen_llvm_fail_parsing_target_machine_config_to_target_machine)] +pub(crate) struct FailParsingTargetMachineConfigToTargetMachine { + pub error: String, +} + pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub features: &'a [&'a str], pub span: Option, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index af632b2ff54b9..246e82545c874 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -12,6 +12,8 @@ #![feature(iter_intersperse)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; @@ -20,6 +22,7 @@ extern crate tracing; use back::write::{create_informational_target_machine, create_target_machine}; +use errors::FailParsingTargetMachineConfigToTargetMachine; pub use llvm_util::target_features; use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; @@ -413,7 +416,7 @@ impl ModuleLlvm { let tm = match (cgcx.tm_factory)(tm_factory_config) { Ok(m) => m, Err(e) => { - handler.struct_err(&e).emit(); + handler.emit_err(FailParsingTargetMachineConfigToTargetMachine { error: e }); return Err(FatalError); } }; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index 9d80b98f56c65..ad4d6a676e66c 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -57,3 +57,10 @@ codegen_llvm_target_feature_disable_or_enable = codegen_llvm_missing_features = add the missing features in a `target_feature` attribute + +codegen_llvm_dynamic_linking_with_lto = + cannot prefer dynamic linking when performing LTO + .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO + +codegen_llvm_fail_parsing_target_machine_config_to_target_machine = + failed to parse target machine config to target machine: {$error} From 677e0333af821ba67c5561c569f597f2439f78e4 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Sun, 30 Oct 2022 19:26:12 +0100 Subject: [PATCH 321/482] Simplify existing Diagnostic implementations --- compiler/rustc_codegen_llvm/src/attributes.rs | 7 ++- compiler/rustc_codegen_llvm/src/errors.rs | 61 +++++++++---------- compiler/rustc_codegen_llvm/src/llvm_util.rs | 22 +++++-- .../locales/en-US/codegen_llvm.ftl | 17 ++---- 4 files changed, 55 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index ce54c28138432..a8b47633519aa 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -396,8 +396,11 @@ pub fn from_fn_attrs<'ll, 'tcx>( .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span); cx.tcx .sess - .create_err(TargetFeatureDisableOrEnable { features: f, span: Some(span) }) - .subdiagnostic(MissingFeatures) + .create_err(TargetFeatureDisableOrEnable { + features: f, + span: Some(span), + missing_features: Some(MissingFeatures), + }) .emit(); return; } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index c08827b952191..44896a8e8febf 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -8,34 +8,28 @@ use rustc_errors::IntoDiagnostic; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; -pub(crate) enum UnknownCTargetFeature<'a> { - UnknownFeaturePrefix { feature: &'a str }, - UnknownFeature { feature: &'a str, rust_feature: Option<&'a str> }, -} - -impl IntoDiagnostic<'_, ()> for UnknownCTargetFeature<'_> { - fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ()> { - match self { - UnknownCTargetFeature::UnknownFeaturePrefix { feature } => { - let mut diag = sess.struct_warn(fluent::codegen_llvm_unknown_ctarget_feature); - diag.set_arg("feature", feature); - diag.note(fluent::codegen_llvm_unknown_feature_prefix); - diag - } - UnknownCTargetFeature::UnknownFeature { feature, rust_feature } => { - let mut diag = sess.struct_warn(fluent::codegen_llvm_unknown_ctarget_feature); - diag.set_arg("feature", feature); - diag.note(fluent::codegen_llvm_unknown_feature); - if let Some(rust_feature) = rust_feature { - diag.help(fluent::codegen_llvm_rust_feature); - diag.set_arg("rust_feature", rust_feature); - } else { - diag.note(fluent::codegen_llvm_unknown_feature_fill_request); - } - diag - } - } - } +#[derive(Diagnostic)] +#[diag(codegen_llvm_unknown_ctarget_feature_prefix)] +#[note] +pub(crate) struct UnknownCTargetFeaturePrefix<'a> { + pub feature: &'a str, +} + +#[derive(Diagnostic)] +#[diag(codegen_llvm_unknown_ctarget_feature)] +#[note] +pub(crate) struct UnknownCTargetFeature<'a> { + pub feature: &'a str, + #[subdiagnostic] + pub rust_feature: PossibleFeature<'a>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum PossibleFeature<'a> { + #[help(possible_feature)] + Some { rust_feature: &'a str }, + #[help(consider_filing_feature_request)] + None, } #[derive(Diagnostic)] @@ -131,6 +125,7 @@ pub(crate) struct FailParsingTargetMachineConfigToTargetMachine { pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub features: &'a [&'a str], pub span: Option, + pub missing_features: Option, } #[derive(Subdiagnostic)] @@ -139,13 +134,13 @@ pub(crate) struct MissingFeatures; impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = if let Some(span) = self.span { - let mut diag = sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); + let mut diag = sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); + if let Some(span) = self.span { diag.set_span(span); - diag - } else { - sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable) }; + if let Some(missing_features) = self.missing_features { + diag.subdiagnostic(missing_features); + } diag.set_arg("features", self.features.join(", ")); diag } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 8c2db38d84d8c..e1f54356228d3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -1,5 +1,8 @@ use crate::back::write::create_informational_target_machine; -use crate::errors::{TargetFeatureDisableOrEnable, UnknownCTargetFeature}; +use crate::errors::{ + PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, + UnknownCTargetFeaturePrefix, +}; use crate::llvm; use libc::c_int; use rustc_codegen_ssa::target_features::{ @@ -435,9 +438,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec c, Some(_) => { if diagnostics { - sess.emit_warning(UnknownCTargetFeature::UnknownFeaturePrefix { - feature: s, - }); + sess.emit_warning(UnknownCTargetFeaturePrefix { feature: s }); } return None; } @@ -454,7 +455,15 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec Vec Date: Wed, 2 Nov 2022 19:23:05 +0100 Subject: [PATCH 322/482] Delay diagnostic translation in `rustc_codegen_ssa` --- compiler/rustc_codegen_ssa/src/back/write.rs | 27 +++++++++++++------- compiler/rustc_errors/src/diagnostic.rs | 9 +++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d0ac016b02e15..6e1a87ae9ebbf 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -15,10 +15,8 @@ use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::profiling::VerboseTimingGuard; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::Emitter; -use rustc_errors::{ - translation::{to_fluent_args, Translate}, - DiagnosticId, FatalError, Handler, Level, -}; +use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level}; +use rustc_errors::{DiagnosticMessage, Style}; use rustc_fs_util::link_or_copy; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_incremental::{ @@ -38,6 +36,7 @@ use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span}; use rustc_target::spec::{MergeFunctions, SanitizerSet}; use std::any::Any; +use std::borrow::Cow; use std::fs; use std::io; use std::marker::PhantomData; @@ -969,8 +968,11 @@ pub enum Message { CodegenAborted, } +type DiagnosticArgName<'source> = Cow<'source, str>; + struct Diagnostic { - msg: String, + msg: Vec<(DiagnosticMessage, Style)>, + args: FxHashMap, rustc_errors::DiagnosticArgValue<'static>>, code: Option, lvl: Level, } @@ -1743,15 +1745,18 @@ impl Translate for SharedEmitter { impl Emitter for SharedEmitter { fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) { - let fluent_args = to_fluent_args(diag.args()); + let args: FxHashMap, rustc_errors::DiagnosticArgValue<'_>> = + diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect(); drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { - msg: self.translate_messages(&diag.message, &fluent_args).to_string(), + msg: diag.message.clone(), + args: args.clone(), code: diag.code.clone(), lvl: diag.level(), }))); for child in &diag.children { drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { - msg: self.translate_messages(&child.message, &fluent_args).to_string(), + msg: child.message.clone(), + args: args.clone(), code: None, lvl: child.level, }))); @@ -1782,10 +1787,14 @@ impl SharedEmitterMain { match message { Ok(SharedEmitterMessage::Diagnostic(diag)) => { let handler = sess.diagnostic(); - let mut d = rustc_errors::Diagnostic::new(diag.lvl, &diag.msg); + let mut d = rustc_errors::Diagnostic::new(diag.lvl, String::new()); + d.message = diag.msg; if let Some(code) = diag.code { d.code(code); } + for (name, arg) in diag.args { + d.set_arg(name, arg); + } handler.emit_diagnostic(&mut d); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 45c017df918e8..b6370354b2481 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -44,6 +44,15 @@ pub trait IntoDiagnosticArg { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>; } +impl<'source> IntoDiagnosticArg for DiagnosticArgValue<'source> { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + match self { + DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())), + DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n), + } + } +} + impl<'source> Into> for DiagnosticArgValue<'source> { fn into(self) -> FluentValue<'source> { match self { From f267a9f2ec0087b9a650fa2ed0b7484b88061d1d Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 3 Nov 2022 13:09:25 +0100 Subject: [PATCH 323/482] Add `replace_args` method for `rustc_errors::diagnostic::Diagnostic` --- compiler/rustc_codegen_ssa/src/back/write.rs | 4 +--- compiler/rustc_errors/src/diagnostic.rs | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 6e1a87ae9ebbf..f0e2e43509f9d 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1792,9 +1792,7 @@ impl SharedEmitterMain { if let Some(code) = diag.code { d.code(code); } - for (name, arg) in diag.args { - d.set_arg(name, arg); - } + d.replace_args(diag.args); handler.emit_diagnostic(&mut d); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b6370354b2481..8c76db84392e9 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -940,6 +940,10 @@ impl Diagnostic { self } + pub fn replace_args(&mut self, args: FxHashMap, DiagnosticArgValue<'static>>) { + self.args = args; + } + pub fn styled_message(&self) -> &[(DiagnosticMessage, Style)] { &self.message } From 931d9298dfa54a7fb2948ad5ec114baa30e3e604 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Thu, 3 Nov 2022 13:41:54 +0100 Subject: [PATCH 324/482] Formatting --- compiler/rustc_errors/src/diagnostic.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 8c76db84392e9..b24814bfa3870 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -940,7 +940,10 @@ impl Diagnostic { self } - pub fn replace_args(&mut self, args: FxHashMap, DiagnosticArgValue<'static>>) { + pub fn replace_args( + &mut self, + args: FxHashMap, DiagnosticArgValue<'static>>, + ) { self.args = args; } From 7a2bb1a83c09b90d50eaa815fcf982f445e15460 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Fri, 4 Nov 2022 20:08:01 +0100 Subject: [PATCH 325/482] Use `LayoutError`'s implementation of `IntoDiagnostic` --- compiler/rustc_codegen_llvm/src/context.rs | 6 +++--- compiler/rustc_codegen_llvm/src/errors.rs | 8 -------- .../rustc_error_messages/locales/en-US/codegen_llvm.ftl | 3 --- compiler/rustc_middle/src/ty/layout.rs | 8 ++++---- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 7ed4df16ea99f..eaa2ccfc835c5 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -4,7 +4,6 @@ use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; use crate::errors::BranchProtectionRequiresAArch64; -use crate::errors::LayoutSizeOverflow; use crate::llvm; use crate::llvm_util; use crate::type_::Type; @@ -28,6 +27,7 @@ use rustc_session::config::{BranchProtection, CFGuard, CFProtection}; use rustc_session::config::{CrateType, DebugInfo, PAuthKey, PacRet}; use rustc_session::Session; use rustc_span::source_map::Span; +use rustc_span::source_map::Spanned; use rustc_target::abi::{ call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx, }; @@ -953,7 +953,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let LayoutError::SizeOverflow(_) = err { - self.sess().emit_fatal(LayoutSizeOverflow { span, error: err.to_string() }) + self.sess().emit_fatal(Spanned { span, node: err }) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) } @@ -971,7 +971,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.sess().emit_fatal(LayoutSizeOverflow { span, error: err.to_string() }) + self.sess().emit_fatal(Spanned { span, node: err }) } else { match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 44896a8e8febf..0fafc214f2f5e 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -55,14 +55,6 @@ pub(crate) struct SymbolAlreadyDefined<'a> { #[diag(codegen_llvm_branch_protection_requires_aarch64)] pub(crate) struct BranchProtectionRequiresAArch64; -#[derive(Diagnostic)] -#[diag(codegen_llvm_layout_size_overflow)] -pub(crate) struct LayoutSizeOverflow { - #[primary_span] - pub span: Span, - pub error: String, -} - #[derive(Diagnostic)] #[diag(codegen_llvm_invalid_minimum_alignment)] pub(crate) struct InvalidMinimumAlignment { diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl index a105b4a64e99e..68a205df6c7ad 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl @@ -20,9 +20,6 @@ codegen_llvm_symbol_already_defined = codegen_llvm_branch_protection_requires_aarch64 = -Zbranch-protection is only supported on aarch64 -codegen_llvm_layout_size_overflow = - {$error} - codegen_llvm_invalid_minimum_alignment = invalid minimum global alignment: {$err} diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3312f44c67b2a..c74d6bc3774a2 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -189,8 +189,8 @@ pub enum LayoutError<'tcx> { NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), } -impl<'a> IntoDiagnostic<'a, !> for LayoutError<'a> { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> { +impl IntoDiagnostic<'_, !> for LayoutError<'_> { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { let mut diag = handler.struct_fatal(""); match self { @@ -1126,8 +1126,8 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> { } } -impl<'tcx> IntoDiagnostic<'tcx, !> for FnAbiError<'tcx> { - fn into_diagnostic(self, handler: &'tcx Handler) -> DiagnosticBuilder<'tcx, !> { +impl IntoDiagnostic<'_, !> for FnAbiError<'_> { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { handler.struct_fatal(self.to_string()) } } From cac3896c6ccda31a8c8cdcfda07bf7769e34767d Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Tue, 8 Nov 2022 20:32:09 +0100 Subject: [PATCH 326/482] Update compiler/rustc_codegen_llvm/src/back/archive.rs Co-authored-by: David Wood --- compiler/rustc_codegen_llvm/src/back/archive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 99c9b51a9cdaa..5c68abeb08baf 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -315,7 +315,7 @@ impl<'a> LlvmArchiveBuilder<'a> { let kind = kind .parse::() .map_err(|_| kind) - .unwrap_or_else(|kind| self.sess.emit_fatal(UnknownArchiveKind { kind: kind })); + .unwrap_or_else(|kind| self.sess.emit_fatal(UnknownArchiveKind { kind })); let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); From afc708c3fec10f723eb714578d4482de16236c40 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Wed, 9 Nov 2022 13:47:46 +0100 Subject: [PATCH 327/482] Add constructor for `Diagnostic` that takes `Vec<(DiagnosticMessage, Style)>` --- compiler/rustc_codegen_ssa/src/back/write.rs | 3 +-- compiler/rustc_errors/src/diagnostic.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index f0e2e43509f9d..e3d28a1aca20e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1787,8 +1787,7 @@ impl SharedEmitterMain { match message { Ok(SharedEmitterMessage::Diagnostic(diag)) => { let handler = sess.diagnostic(); - let mut d = rustc_errors::Diagnostic::new(diag.lvl, String::new()); - d.message = diag.msg; + let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msg); if let Some(code) = diag.code { d.code(code); } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b24814bfa3870..0ee4c6e722fc2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -213,6 +213,21 @@ impl Diagnostic { Diagnostic::new_with_code(level, None, message) } + #[track_caller] + pub fn new_with_messages(level: Level, messages: Vec<(DiagnosticMessage, Style)>) -> Self { + Diagnostic { + level, + message: messages, + code: None, + span: MultiSpan::new(), + children: vec![], + suggestions: Ok(vec![]), + args: Default::default(), + sort_span: DUMMY_SP, + is_lint: false, + } + } + #[track_caller] pub fn new_with_code>( level: Level, From 2c278c9fd8fd5b799f32ba0dcb28d73d0da66304 Mon Sep 17 00:00:00 2001 From: SLASHLogin Date: Wed, 9 Nov 2022 15:14:58 +0100 Subject: [PATCH 328/482] Add missing `emitted_at` to the `Diagnostic` --- compiler/rustc_errors/src/diagnostic.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 0ee4c6e722fc2..43101bbb9d31c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -225,6 +225,7 @@ impl Diagnostic { args: Default::default(), sort_span: DUMMY_SP, is_lint: false, + emitted_at: DiagnosticLocation::caller(), } } From b52967c2ab662ae00bd25994338de768b0adcf2b Mon Sep 17 00:00:00 2001 From: b4den Date: Thu, 20 Oct 2022 15:44:25 +0100 Subject: [PATCH 329/482] Add context to compiler error message Changed `creates a temporary which is freed while still in use` to `creates a temporary value which is freed while still in use` --- compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7f26e970e3094..86cae5d09b5aa 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1557,7 +1557,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let mut err = self.temporary_value_borrowed_for_too_long(proper_span); - err.span_label(proper_span, "creates a temporary which is freed while still in use"); + err.span_label(proper_span, "creates a temporary value which is freed while still in use"); err.span_label(drop_span, "temporary value is freed at the end of this statement"); match explanation { From e15968e18ed4622875d574b73dbd8ffbbb939c9b Mon Sep 17 00:00:00 2001 From: b4den Date: Thu, 20 Oct 2022 16:43:27 +0100 Subject: [PATCH 330/482] Update tests to match error message changes --- library/core/src/pin.rs | 2 +- .../borrowck-borrowed-uniq-rvalue-2.stderr | 2 +- .../borrowck-borrowed-uniq-rvalue.stderr | 2 +- src/test/ui/borrowck/issue-11493.stderr | 2 +- src/test/ui/borrowck/issue-17545.stderr | 2 +- src/test/ui/borrowck/issue-36082.fixed | 2 +- src/test/ui/borrowck/issue-36082.rs | 2 +- src/test/ui/borrowck/issue-36082.stderr | 2 +- src/test/ui/cleanup-rvalue-scopes-cf.stderr | 14 +++---- .../const-eval-intrinsic-promotion.stderr | 2 +- .../dont_promote_unstable_const_fn.stderr | 6 +-- ...omote_unstable_const_fn_cross_crate.stderr | 4 +- .../const-eval/promoted_const_fn_fail.stderr | 2 +- ...omoted_const_fn_fail_deny_const_err.stderr | 2 +- .../const-eval/promoted_raw_ptr_ops.stderr | 8 ++-- .../transmute-const-promotion.stderr | 2 +- .../consts/const-eval/union_promotion.stderr | 2 +- .../ui/consts/const-int-conversion.stderr | 14 +++---- .../ui/consts/const-int-overflowing.stderr | 6 +-- src/test/ui/consts/const-int-rotate.stderr | 4 +- src/test/ui/consts/const-int-sign.stderr | 4 +- src/test/ui/consts/const-int-wrapping.stderr | 10 ++--- .../const-mut-refs/mut_ref_in_final.stderr | 10 ++--- src/test/ui/consts/const-ptr-nonnull.stderr | 4 +- src/test/ui/consts/const-ptr-unique.stderr | 2 +- .../control-flow/interior-mutability.stderr | 6 +-- src/test/ui/consts/issue-54224.stderr | 4 +- .../ui/consts/min_const_fn/promotion.stderr | 12 +++--- src/test/ui/consts/promote-not.stderr | 40 +++++++++---------- src/test/ui/consts/promote_const_let.stderr | 2 +- src/test/ui/consts/promoted-const-drop.stderr | 4 +- src/test/ui/consts/qualif-union.stderr | 10 ++--- .../ui/generator/auto-trait-regions.stderr | 4 +- .../bugs/hrtb-implied-1.stderr | 2 +- src/test/ui/issues/issue-47184.stderr | 2 +- src/test/ui/issues/issue-52049.stderr | 2 +- .../lifetimes/borrowck-let-suggestion.stderr | 2 +- .../ui/nll/borrowed-temporary-error.stderr | 2 +- .../issue-57265-return-type-wf-check.stderr | 2 +- .../ui/nll/user-annotations/patterns.stderr | 6 +-- ...fetime_errors_on_promotion_misusage.stderr | 4 +- ...egions-free-region-ordering-caller1.stderr | 2 +- .../regions-var-type-out-of-scope.stderr | 2 +- .../span/borrowck-let-suggestion-suffixes.rs | 6 +-- .../borrowck-let-suggestion-suffixes.stderr | 6 +-- .../ui/span/borrowck-ref-into-rvalue.stderr | 2 +- src/test/ui/span/issue-15480.stderr | 2 +- ...ions-close-over-borrowed-ref-in-obj.stderr | 2 +- src/test/ui/span/slice-borrow.stderr | 2 +- src/test/ui/static/static-drop-scope.stderr | 4 +- .../ui/static/static-reference-to-fn-2.stderr | 6 +-- src/test/ui/static/static-region-bound.stderr | 2 +- src/test/ui/statics/issue-44373.stderr | 2 +- 53 files changed, 127 insertions(+), 127 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index ccef35b45325a..f0258640e2aec 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1059,7 +1059,7 @@ impl DispatchFromDyn> for Pin

where P: DispatchFromDyn {} /// 8 | let x: Pin<&mut Foo> = { /// | - borrow later stored here /// 9 | let x: Pin<&mut Foo> = pin!(Foo { /* … */ }); -/// | ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use +/// | ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use /// 10 | x /// 11 | }; // <- Foo is dropped /// | - temporary value is freed at the end of this statement diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr index a6af129bf39f1..4eeec09b91040 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x = defer(&vec!["Goodbye", "world!"]); | ^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | x.x[0]; | ------ borrow later used here | diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr index dea8ac90bec2e..c62d5f903c8d8 100644 --- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr +++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | buggy_map.insert(42, &*Box::new(1)); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | buggy_map.insert(43, &*tmp); | --------------------------- borrow later used here diff --git a/src/test/ui/borrowck/issue-11493.stderr b/src/test/ui/borrowck/issue-11493.stderr index a5d1f2816f1ca..2720b09b0fc5f 100644 --- a/src/test/ui/borrowck/issue-11493.stderr +++ b/src/test/ui/borrowck/issue-11493.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let y = x.as_ref().unwrap_or(&id(5)); | ^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | let _ = &y; | -- borrow later used here | diff --git a/src/test/ui/borrowck/issue-17545.stderr b/src/test/ui/borrowck/issue-17545.stderr index 79a1e09bd7cc6..3ae7e64d202b6 100644 --- a/src/test/ui/borrowck/issue-17545.stderr +++ b/src/test/ui/borrowck/issue-17545.stderr @@ -5,7 +5,7 @@ LL | pub fn foo<'a, F: Fn(&'a ())>(bar: F) { | -- lifetime `'a` defined here LL | / bar.call(( LL | | &id(()), - | | ^^^^^^ creates a temporary which is freed while still in use + | | ^^^^^^ creates a temporary value which is freed while still in use LL | | )); | | -- temporary value is freed at the end of this statement | |______| diff --git a/src/test/ui/borrowck/issue-36082.fixed b/src/test/ui/borrowck/issue-36082.fixed index 8640ca7a50964..8fc963a85664e 100644 --- a/src/test/ui/borrowck/issue-36082.fixed +++ b/src/test/ui/borrowck/issue-36082.fixed @@ -10,7 +10,7 @@ fn main() { let val: &_ = binding.0; //~^ ERROR temporary value dropped while borrowed [E0716] //~| NOTE temporary value is freed at the end of this statement - //~| NOTE creates a temporary which is freed while still in use + //~| NOTE creates a temporary value which is freed while still in use //~| HELP consider using a `let` binding to create a longer lived value println!("{}", val); //~^ borrow later used here diff --git a/src/test/ui/borrowck/issue-36082.rs b/src/test/ui/borrowck/issue-36082.rs index 877d372fb8484..20f66b4d45de4 100644 --- a/src/test/ui/borrowck/issue-36082.rs +++ b/src/test/ui/borrowck/issue-36082.rs @@ -9,7 +9,7 @@ fn main() { let val: &_ = x.borrow().0; //~^ ERROR temporary value dropped while borrowed [E0716] //~| NOTE temporary value is freed at the end of this statement - //~| NOTE creates a temporary which is freed while still in use + //~| NOTE creates a temporary value which is freed while still in use //~| HELP consider using a `let` binding to create a longer lived value println!("{}", val); //~^ borrow later used here diff --git a/src/test/ui/borrowck/issue-36082.stderr b/src/test/ui/borrowck/issue-36082.stderr index 4bd586db1cdce..a6357f8182fc2 100644 --- a/src/test/ui/borrowck/issue-36082.stderr +++ b/src/test/ui/borrowck/issue-36082.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let val: &_ = x.borrow().0; | ^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | println!("{}", val); | --- borrow later used here diff --git a/src/test/ui/cleanup-rvalue-scopes-cf.stderr b/src/test/ui/cleanup-rvalue-scopes-cf.stderr index 40f14c389842e..425cd75141cec 100644 --- a/src/test/ui/cleanup-rvalue-scopes-cf.stderr +++ b/src/test/ui/cleanup-rvalue-scopes-cf.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x1 = arg(&AddFlags(1)); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -21,7 +21,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x2 = AddFlags(1).get(); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -38,7 +38,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x3 = &*arg(&AddFlags(1)); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -55,7 +55,7 @@ error[E0716]: temporary value dropped while borrowed LL | let ref x4 = *arg(&AddFlags(1)); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -72,7 +72,7 @@ error[E0716]: temporary value dropped while borrowed LL | let &ref x5 = arg(&AddFlags(1)); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -89,7 +89,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x6 = AddFlags(1).get(); | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here @@ -106,7 +106,7 @@ error[E0716]: temporary value dropped while borrowed LL | let StackBox { f: x7 } = StackBox { f: AddFlags(1).get() }; | ^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | LL | (x1, x2, x3, x4, x5, x6, x7); | -- borrow later used here diff --git a/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr b/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr index 78143042ece7b..ed6a6ee6e0fd9 100644 --- a/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr +++ b/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let x: &'static usize = | -------------- type annotation requires that borrow lasts for `'static` LL | &std::intrinsics::size_of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr index 69e3ca716a909..2e697b219c5a4 100644 --- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr +++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr @@ -10,7 +10,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/dont_promote_unstable_const_fn.rs:17:28 | LL | let _: &'static u32 = &foo(); - | ------------ ^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } @@ -20,7 +20,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/dont_promote_unstable_const_fn.rs:21:28 | LL | let _: &'static u32 = &meh(); - | ------------ ^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -31,7 +31,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/dont_promote_unstable_const_fn.rs:22:26 | LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis(); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr index 129f06151074f..aa742d784e035 100644 --- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr +++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:8:28 | LL | let _: &'static u32 = &foo(); - | ------------ ^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | let _x: &'static u32 = &foo(); @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:9:29 | LL | let _x: &'static u32 = &foo(); - | ------------ ^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr index 596fa090d976f..2d4e7c83d3e4e 100644 --- a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr +++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_fn_fail.rs:17:27 | LL | let x: &'static u8 = &(bar() + 1); - | ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use + | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr index 63dc43a41a8fc..9ebae3a18a32f 100644 --- a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr +++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_fn_fail_deny_const_err.rs:18:27 | LL | let x: &'static u8 = &(bar() + 1); - | ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use + | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr index 8ac60da38634b..01fcf2ec21342 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:2:29 | LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:4:30 | LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); - | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:6:28 | LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_raw_ptr_ops.rs:8:29 | LL | let a: &'static bool = &(main as fn() == main as fn()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-eval/transmute-const-promotion.stderr b/src/test/ui/consts/const-eval/transmute-const-promotion.stderr index 15b9b56ea6606..434a957f64840 100644 --- a/src/test/ui/consts/const-eval/transmute-const-promotion.stderr +++ b/src/test/ui/consts/const-eval/transmute-const-promotion.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/transmute-const-promotion.rs:4:37 | LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-eval/union_promotion.stderr b/src/test/ui/consts/const-eval/union_promotion.stderr index 70808c520d3f9..42f17de200344 100644 --- a/src/test/ui/consts/const-eval/union_promotion.stderr +++ b/src/test/ui/consts/const-eval/union_promotion.stderr @@ -7,7 +7,7 @@ LL | let x: &'static bool = &unsafe { | | type annotation requires that borrow lasts for `'static` LL | | Foo { a: &1 }.b == Foo { a: &2 }.b LL | | }; - | |_____^ creates a temporary which is freed while still in use + | |_____^ creates a temporary value which is freed while still in use LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/consts/const-int-conversion.stderr b/src/test/ui/consts/const-int-conversion.stderr index 61162a792262b..5dd757e3f5ee1 100644 --- a/src/test/ui/consts/const-int-conversion.stderr +++ b/src/test/ui/consts/const-int-conversion.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:2:28 | LL | let x: &'static i32 = &(5_i32.reverse_bits()); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:4:28 | LL | let y: &'static i32 = &(i32::from_be_bytes([0x12, 0x34, 0x56, 0x78])); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:6:28 | LL | let z: &'static i32 = &(i32::from_le_bytes([0x12, 0x34, 0x56, 0x78])); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:8:28 | LL | let a: &'static i32 = &(i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0]))); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:10:29 | LL | let b: &'static [u8] = &(0x12_34_56_78_i32.to_be_bytes()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -57,7 +57,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:12:29 | LL | let c: &'static [u8] = &(0x12_34_56_78_i32.to_le_bytes()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -68,7 +68,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-conversion.rs:14:29 | LL | let d: &'static [u8] = &(i32::MIN.to_be().to_ne_bytes()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-int-overflowing.stderr b/src/test/ui/consts/const-int-overflowing.stderr index 56c7f7f092d66..7d3689e6ec7d7 100644 --- a/src/test/ui/consts/const-int-overflowing.stderr +++ b/src/test/ui/consts/const-int-overflowing.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-overflowing.rs:2:36 | LL | let x: &'static (i32, bool) = &(5_i32.overflowing_add(3)); - | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-overflowing.rs:4:36 | LL | let y: &'static (i32, bool) = &(5_i32.overflowing_sub(3)); - | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-overflowing.rs:6:36 | LL | let z: &'static (i32, bool) = &(5_i32.overflowing_mul(3)); - | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-int-rotate.stderr b/src/test/ui/consts/const-int-rotate.stderr index ed265804bbc6c..039da1c31c575 100644 --- a/src/test/ui/consts/const-int-rotate.stderr +++ b/src/test/ui/consts/const-int-rotate.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-rotate.rs:2:28 | LL | let x: &'static i32 = &(5_i32.rotate_left(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-rotate.rs:4:28 | LL | let y: &'static i32 = &(5_i32.rotate_right(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-int-sign.stderr b/src/test/ui/consts/const-int-sign.stderr index 5f8fd4141804c..fc23d9d2b2942 100644 --- a/src/test/ui/consts/const-int-sign.stderr +++ b/src/test/ui/consts/const-int-sign.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-sign.rs:2:29 | LL | let x: &'static bool = &(5_i32.is_negative()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-sign.rs:4:29 | LL | let y: &'static bool = &(5_i32.is_positive()); - | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-int-wrapping.stderr b/src/test/ui/consts/const-int-wrapping.stderr index 5174b72659cd7..1342fadc4055b 100644 --- a/src/test/ui/consts/const-int-wrapping.stderr +++ b/src/test/ui/consts/const-int-wrapping.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-wrapping.rs:2:28 | LL | let x: &'static i32 = &(5_i32.wrapping_add(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-wrapping.rs:4:28 | LL | let y: &'static i32 = &(5_i32.wrapping_sub(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-wrapping.rs:6:28 | LL | let z: &'static i32 = &(5_i32.wrapping_mul(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-wrapping.rs:8:28 | LL | let a: &'static i32 = &(5_i32.wrapping_shl(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-int-wrapping.rs:10:28 | LL | let b: &'static i32 = &(5_i32.wrapping_shr(3)); - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 3a9ce79f10ef2..78c58b5ab092b 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -11,7 +11,7 @@ LL | const B3: Option<&mut i32> = Some(&mut 42); | ----------^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -21,7 +21,7 @@ LL | const B4: Option<&mut i32> = helper(&mut 42); | ------------^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -31,7 +31,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -41,7 +41,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a static requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -51,7 +51,7 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a static requires that borrow lasts for `'static` error: aborting due to 6 previous errors diff --git a/src/test/ui/consts/const-ptr-nonnull.stderr b/src/test/ui/consts/const-ptr-nonnull.stderr index 26946fb99024c..dbcb0c86052ee 100644 --- a/src/test/ui/consts/const-ptr-nonnull.stderr +++ b/src/test/ui/consts/const-ptr-nonnull.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-ptr-nonnull.rs:4:37 | LL | let x: &'static NonNull = &(NonNull::dangling()); - | --------------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | --------------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-ptr-nonnull.rs:9:37 | LL | let x: &'static NonNull = &(non_null.cast()); - | --------------------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | --------------------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/const-ptr-unique.stderr b/src/test/ui/consts/const-ptr-unique.stderr index 3644cf4cec7d3..83448c3e8d876 100644 --- a/src/test/ui/consts/const-ptr-unique.stderr +++ b/src/test/ui/consts/const-ptr-unique.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/const-ptr-unique.rs:8:33 | LL | let x: &'static *mut u32 = &(unique.as_ptr()); - | ----------------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ----------------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | diff --git a/src/test/ui/consts/control-flow/interior-mutability.stderr b/src/test/ui/consts/control-flow/interior-mutability.stderr index 4f9c7d34c35f4..db2ffb91b988b 100644 --- a/src/test/ui/consts/control-flow/interior-mutability.stderr +++ b/src/test/ui/consts/control-flow/interior-mutability.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/interior-mutability.rs:40:26 | LL | let x: &'static _ = &X; - | ---------- ^ creates a temporary which is freed while still in use + | ---------- ^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/interior-mutability.rs:41:26 | LL | let y: &'static _ = &Y; - | ---------- ^ creates a temporary which is freed while still in use + | ---------- ^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | let z: &'static _ = &Z; @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/interior-mutability.rs:42:26 | LL | let z: &'static _ = &Z; - | ---------- ^ creates a temporary which is freed while still in use + | ---------- ^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr index 8dcb4daca3b70..55fe55759df54 100644 --- a/src/test/ui/consts/issue-54224.stderr +++ b/src/test/ui/consts/issue-54224.stderr @@ -5,7 +5,7 @@ LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); | ------^^^^^^^^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -15,7 +15,7 @@ LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); | ---------------^^^^^^^^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/min_const_fn/promotion.stderr b/src/test/ui/consts/min_const_fn/promotion.stderr index 550423c2d933c..0b8dc0ce0e903 100644 --- a/src/test/ui/consts/min_const_fn/promotion.stderr +++ b/src/test/ui/consts/min_const_fn/promotion.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:11:27 | LL | let x: &'static () = &foo1(); - | ----------- ^^^^^^ creates a temporary which is freed while still in use + | ----------- ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:12:28 | LL | let y: &'static i32 = &foo2(42); - | ------------ ^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:13:28 | LL | let z: &'static i32 = &foo3(); - | ------------ ^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:14:34 | LL | let a: &'static Cell = &foo4(); - | ------------------ ^^^^^^ creates a temporary which is freed while still in use + | ------------------ ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:15:42 | LL | let a: &'static Option> = &foo5(); - | -------------------------- ^^^^^^ creates a temporary which is freed while still in use + | -------------------------- ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | let a: &'static Option> = &foo6(); @@ -57,7 +57,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promotion.rs:16:42 | LL | let a: &'static Option> = &foo6(); - | -------------------------- ^^^^^^ creates a temporary which is freed while still in use + | -------------------------- ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/consts/promote-not.stderr b/src/test/ui/consts/promote-not.stderr index 0d0b0f9c689b5..b93358e8dccea 100644 --- a/src/test/ui/consts/promote-not.stderr +++ b/src/test/ui/consts/promote-not.stderr @@ -5,14 +5,14 @@ LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]); | ----------^^^^^^^^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a static requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:11:18 | LL | let x = &mut [1,2,3]; - | ^^^^^^^ creates a temporary which is freed while still in use + | ^^^^^^^ creates a temporary value which is freed while still in use LL | x | - using this value as a static requires that borrow lasts for `'static` LL | }; @@ -22,7 +22,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:20:32 | LL | let _x: &'static () = &foo(); - | ----------- ^^^^^ creates a temporary which is freed while still in use + | ----------- ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } @@ -32,7 +32,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:28:29 | LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } @@ -42,7 +42,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:33:29 | LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | }; @@ -52,7 +52,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:39:29 | LL | let _val: &'static _ = &(Cell::new(1), 2).1; - | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | }; @@ -62,7 +62,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:46:29 | LL | let _val: &'static _ = &(Cell::new(1), 2).0; - | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -73,7 +73,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:47:29 | LL | let _val: &'static _ = &(Cell::new(1), 2).1; - | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -84,7 +84,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:50:29 | LL | let _val: &'static _ = &(1/0); - | ---------- ^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -95,7 +95,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:51:29 | LL | let _val: &'static _ = &(1/(1-1)); - | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -106,7 +106,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:52:29 | LL | let _val: &'static _ = &(1%0); - | ---------- ^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -117,7 +117,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:53:29 | LL | let _val: &'static _ = &(1%(1-1)); - | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -128,7 +128,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:54:29 | LL | let _val: &'static _ = &([1,2,3][4]+1); - | ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -139,7 +139,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:57:29 | LL | let _val: &'static _ = &TEST_DROP; - | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -150,7 +150,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:59:29 | LL | let _val: &'static _ = &&TEST_DROP; - | ---------- ^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -161,7 +161,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:59:30 | LL | let _val: &'static _ = &&TEST_DROP; - | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -172,7 +172,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:62:29 | LL | let _val: &'static _ = &(&TEST_DROP,); - | ---------- ^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -183,7 +183,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:62:31 | LL | let _val: &'static _ = &(&TEST_DROP,); - | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -194,7 +194,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promote-not.rs:65:29 | LL | let _val: &'static _ = &[&TEST_DROP; 1]; - | ---------- ^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ---------- ^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -207,7 +207,7 @@ error[E0716]: temporary value dropped while borrowed LL | let _val: &'static _ = &[&TEST_DROP; 1]; | ---------- ^^^^^^^^^ - temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` error: aborting due to 20 previous errors diff --git a/src/test/ui/consts/promote_const_let.stderr b/src/test/ui/consts/promote_const_let.stderr index c47d297c90409..975a235a6495b 100644 --- a/src/test/ui/consts/promote_const_let.stderr +++ b/src/test/ui/consts/promote_const_let.stderr @@ -19,7 +19,7 @@ LL | let x: &'static u32 = &{ LL | | let y = 42; LL | | y LL | | }; - | |_____^ creates a temporary which is freed while still in use + | |_____^ creates a temporary value which is freed while still in use LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/consts/promoted-const-drop.stderr b/src/test/ui/consts/promoted-const-drop.stderr index 184ba0ea3b377..4802834173fc5 100644 --- a/src/test/ui/consts/promoted-const-drop.stderr +++ b/src/test/ui/consts/promoted-const-drop.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted-const-drop.rs:13:26 | LL | let _: &'static A = &A(); - | ---------- ^^^ creates a temporary which is freed while still in use + | ---------- ^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | let _: &'static [A] = &[C]; @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/promoted-const-drop.rs:14:28 | LL | let _: &'static [A] = &[C]; - | ------------ ^^^ creates a temporary which is freed while still in use + | ------------ ^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/consts/qualif-union.stderr b/src/test/ui/consts/qualif-union.stderr index 8ec68ada048a5..d847cf88f505f 100644 --- a/src/test/ui/consts/qualif-union.stderr +++ b/src/test/ui/consts/qualif-union.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/qualif-union.rs:28:26 | LL | let _: &'static _ = &C1; - | ---------- ^^ creates a temporary which is freed while still in use + | ---------- ^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/qualif-union.rs:29:26 | LL | let _: &'static _ = &C2; - | ---------- ^^ creates a temporary which is freed while still in use + | ---------- ^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/qualif-union.rs:30:26 | LL | let _: &'static _ = &C3; - | ---------- ^^ creates a temporary which is freed while still in use + | ---------- ^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` ... @@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/qualif-union.rs:31:26 | LL | let _: &'static _ = &C4; - | ---------- ^^ creates a temporary which is freed while still in use + | ---------- ^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | let _: &'static _ = &C5; @@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/qualif-union.rs:32:26 | LL | let _: &'static _ = &C5; - | ---------- ^^ creates a temporary which is freed while still in use + | ---------- ^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 23324af6171a9..0b1f34aeb96bd 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | assert_foo(a); | - borrow later used here @@ -17,7 +17,7 @@ error[E0716]: temporary value dropped while borrowed LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | assert_foo(a); | - borrow later used here diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr index 414999881d470..1c9abc4e837c5 100644 --- a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr +++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/hrtb-implied-1.rs:31:22 | LL | let slice = &mut (); - | ^^ creates a temporary which is freed while still in use + | ^^ creates a temporary value which is freed while still in use ... LL | print_items::>(windows); | -------------------------------------- argument requires that borrow lasts for `'static` diff --git a/src/test/ui/issues/issue-47184.stderr b/src/test/ui/issues/issue-47184.stderr index f97713b4ac438..c2c7df7a333a4 100644 --- a/src/test/ui/issues/issue-47184.stderr +++ b/src/test/ui/issues/issue-47184.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let _vec: Vec<&'static String> = vec![&String::new()]; | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-52049.stderr b/src/test/ui/issues/issue-52049.stderr index 55929d85da457..b25dbd1cb8b12 100644 --- a/src/test/ui/issues/issue-52049.stderr +++ b/src/test/ui/issues/issue-52049.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | foo(&unpromotable(5u32)); | -----^^^^^^^^^^^^^^^^^^- | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index bbf04c98436e8..987b051b11106 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let mut x = vec![1].iter(); | ^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | LL | x.use_mut(); | ----------- borrow later used here diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr index 2c6bd92641f60..89781d96fab26 100644 --- a/src/test/ui/nll/borrowed-temporary-error.stderr +++ b/src/test/ui/nll/borrowed-temporary-error.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowed-temporary-error.rs:8:10 | LL | &(v,) - | ^^^^ creates a temporary which is freed while still in use + | ^^^^ creates a temporary value which is freed while still in use LL | LL | }); | - temporary value is freed at the end of this statement diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr index 20add62b91ddf..bb45575fa64c3 100644 --- a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr +++ b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let (_, z) = foo(&"hello".to_string()); | -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr index 60d6e6db36326..de6f8f80fe252 100644 --- a/src/test/ui/nll/user-annotations/patterns.stderr +++ b/src/test/ui/nll/user-annotations/patterns.stderr @@ -76,7 +76,7 @@ error[E0716]: temporary value dropped while borrowed LL | let _: Vec<&'static String> = vec![&String::new()]; | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -85,7 +85,7 @@ error[E0716]: temporary value dropped while borrowed LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); | ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed @@ -94,7 +94,7 @@ error[E0716]: temporary value dropped while borrowed LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); | ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` error[E0597]: `x` does not live long enough diff --git a/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr index 4971263af08ad..fc1be052fb791 100644 --- a/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr +++ b/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | let phantom_pinned = identity(pin!(PhantomPinned)); | ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | LL | stuff(phantom_pinned) | -------------- borrow later used here @@ -18,7 +18,7 @@ error[E0716]: temporary value dropped while borrowed LL | let phantom_pinned = { | -------------- borrow later stored here LL | let phantom_pinned = pin!(PhantomPinned); - | ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use ... LL | }; | - temporary value is freed at the end of this statement diff --git a/src/test/ui/regions/regions-free-region-ordering-caller1.stderr b/src/test/ui/regions/regions-free-region-ordering-caller1.stderr index 8042b1740b141..8ef7e22536bf9 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller1.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-caller1.stderr @@ -5,7 +5,7 @@ LL | fn call1<'a>(x: &'a usize) { | -- lifetime `'a` defined here ... LL | let z: &'a & usize = &(&y); - | ----------- ^^^^ creates a temporary which is freed while still in use + | ----------- ^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'a` ... diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr index 476e82f046f01..c32bbe0ee1fb4 100644 --- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr +++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr @@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed LL | x = &id(3); | ^^^^^- temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use LL | assert_eq!(*x, 3); | ----------------- borrow later used here | diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs index 6240f103c99b0..18abfb5c3fbec 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs @@ -18,7 +18,7 @@ fn f() { v3.push(&id('x')); // statement 6 //~^ ERROR temporary value dropped while borrowed - //~| NOTE creates a temporary which is freed while still in use + //~| NOTE creates a temporary value which is freed while still in use //~| NOTE temporary value is freed at the end of this statement //~| HELP consider using a `let` binding to create a longer lived value @@ -28,7 +28,7 @@ fn f() { v4.push(&id('y')); //~^ ERROR temporary value dropped while borrowed - //~| NOTE creates a temporary which is freed while still in use + //~| NOTE creates a temporary value which is freed while still in use //~| NOTE temporary value is freed at the end of this statement //~| NOTE consider using a `let` binding to create a longer lived value v4.use_ref(); @@ -39,7 +39,7 @@ fn f() { v5.push(&id('z')); //~^ ERROR temporary value dropped while borrowed - //~| NOTE creates a temporary which is freed while still in use + //~| NOTE creates a temporary value which is freed while still in use //~| NOTE temporary value is freed at the end of this statement //~| HELP consider using a `let` binding to create a longer lived value diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr index a236dab3ae562..2dc29a78d204d 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -16,7 +16,7 @@ error[E0716]: temporary value dropped while borrowed LL | v3.push(&id('x')); // statement 6 | ^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref(); | -- borrow later used here @@ -33,7 +33,7 @@ error[E0716]: temporary value dropped while borrowed LL | v4.push(&id('y')); | ^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | v4.use_ref(); | ------------ borrow later used here @@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed LL | v5.push(&id('z')); | ^^^^^^^ - temporary value is freed at the end of this statement | | - | creates a temporary which is freed while still in use + | creates a temporary value which is freed while still in use ... LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref(); | -- borrow later used here diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr index cb5289d24b4fc..25e344fedfb25 100644 --- a/src/test/ui/span/borrowck-ref-into-rvalue.stderr +++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/borrowck-ref-into-rvalue.rs:4:11 | LL | match Some("Hello".to_string()) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use ... LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr index 460ad9ac74445..d9cce2254dd95 100644 --- a/src/test/ui/span/issue-15480.stderr +++ b/src/test/ui/span/issue-15480.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/issue-15480.rs:6:10 | LL | &id(3) - | ^^^^^ creates a temporary which is freed while still in use + | ^^^^^ creates a temporary value which is freed while still in use LL | ]; | - temporary value is freed at the end of this statement ... diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr index ba0c45acf237d..81e858fa0ce01 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/regions-close-over-borrowed-ref-in-obj.rs:12:27 | LL | let ss: &isize = &id(1); - | ^^^^^ creates a temporary which is freed while still in use + | ^^^^^ creates a temporary value which is freed while still in use ... LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index 27df25be3fa03..b70bf69d688a5 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/slice-borrow.rs:6:28 | LL | let x: &[isize] = &vec![1, 2, 3, 4, 5]; - | ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use ... LL | } | - temporary value is freed at the end of this statement diff --git a/src/test/ui/static/static-drop-scope.stderr b/src/test/ui/static/static-drop-scope.stderr index 112bfc003048d..cedcb7367949f 100644 --- a/src/test/ui/static/static-drop-scope.stderr +++ b/src/test/ui/static/static-drop-scope.stderr @@ -13,7 +13,7 @@ LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor); | ------^^^^^^^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a static requires that borrow lasts for `'static` error[E0493]: destructor of `WithDtor` cannot be evaluated at compile-time @@ -31,7 +31,7 @@ LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor); | ------^^^^^^^^- | | | | | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr index ff15884bd445d..133d8ec2e1e51 100644 --- a/src/test/ui/static/static-reference-to-fn-2.stderr +++ b/src/test/ui/static/static-reference-to-fn-2.stderr @@ -6,7 +6,7 @@ LL | fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { LL | self_.statefn = &id(state2 as StateMachineFunc); | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | assignment requires that borrow lasts for `'1` error[E0716]: temporary value dropped while borrowed @@ -17,7 +17,7 @@ LL | fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { LL | self_.statefn = &id(state3 as StateMachineFunc); | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | assignment requires that borrow lasts for `'1` error[E0716]: temporary value dropped while borrowed @@ -28,7 +28,7 @@ LL | fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { LL | self_.statefn = &id(finished as StateMachineFunc); | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement | | | - | | creates a temporary which is freed while still in use + | | creates a temporary value which is freed while still in use | assignment requires that borrow lasts for `'1` error[E0515]: cannot return value referencing temporary value diff --git a/src/test/ui/static/static-region-bound.stderr b/src/test/ui/static/static-region-bound.stderr index 15261259ed412..1a607e3c014a3 100644 --- a/src/test/ui/static/static-region-bound.stderr +++ b/src/test/ui/static/static-region-bound.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/static-region-bound.rs:10:14 | LL | let x = &id(3); - | ^^^^^ creates a temporary which is freed while still in use + | ^^^^^ creates a temporary value which is freed while still in use LL | f(x); | ---- argument requires that borrow lasts for `'static` LL | } diff --git a/src/test/ui/statics/issue-44373.stderr b/src/test/ui/statics/issue-44373.stderr index 6f92fbb1eb689..2d29dec888e8d 100644 --- a/src/test/ui/statics/issue-44373.stderr +++ b/src/test/ui/statics/issue-44373.stderr @@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed --> $DIR/issue-44373.rs:4:42 | LL | let _val: &'static [&'static u32] = &[&FOO]; - | ----------------------- ^^^^^^ creates a temporary which is freed while still in use + | ----------------------- ^^^^^^ creates a temporary value which is freed while still in use | | | type annotation requires that borrow lasts for `'static` LL | } From 072f54fddc8a8579ff6413a9c039105248c90159 Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Wed, 3 Aug 2022 04:30:13 -0700 Subject: [PATCH 331/482] Add support for custom MIR parsing --- compiler/rustc_borrowck/src/lib.rs | 14 + compiler/rustc_feature/src/active.rs | 2 + compiler/rustc_feature/src/builtin_attrs.rs | 4 + compiler/rustc_middle/src/mir/mod.rs | 59 +++++ .../rustc_mir_build/src/build/custom/mod.rs | 155 +++++++++++ .../rustc_mir_build/src/build/custom/parse.rs | 245 ++++++++++++++++++ .../src/build/custom/parse/instruction.rs | 72 +++++ compiler/rustc_mir_build/src/build/mod.rs | 17 ++ compiler/rustc_mir_build/src/thir/cx/expr.rs | 16 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 11 +- .../rustc_mir_transform/src/check_unsafety.rs | 8 + .../rustc_mir_transform/src/pass_manager.rs | 73 +++--- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics.rs | 3 + library/core/src/intrinsics/mir.rs | 123 +++++++++ .../references.immut_ref.built.after.mir | 14 + .../custom/references.mut_ref.built.after.mir | 14 + .../mir-opt/building/custom/references.rs | 43 +++ .../mir-opt/building/custom/simple_assign.rs | 37 +++ .../simple_assign.simple.built.after.mir | 18 ++ .../simple_assign.simple_ref.built.after.mir | 10 + .../feature-gates/feature-gate-custom_mir.rs | 12 + .../feature-gate-custom_mir.stderr | 11 + 23 files changed, 921 insertions(+), 41 deletions(-) create mode 100644 compiler/rustc_mir_build/src/build/custom/mod.rs create mode 100644 compiler/rustc_mir_build/src/build/custom/parse.rs create mode 100644 compiler/rustc_mir_build/src/build/custom/parse/instruction.rs create mode 100644 library/core/src/intrinsics/mir.rs create mode 100644 src/test/mir-opt/building/custom/references.immut_ref.built.after.mir create mode 100644 src/test/mir-opt/building/custom/references.mut_ref.built.after.mir create mode 100644 src/test/mir-opt/building/custom/references.rs create mode 100644 src/test/mir-opt/building/custom/simple_assign.rs create mode 100644 src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir create mode 100644 src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir create mode 100644 src/test/ui/feature-gates/feature-gate-custom_mir.rs create mode 100644 src/test/ui/feature-gates/feature-gate-custom_mir.stderr diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index abfe253d43df7..4a4887f19702f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -18,6 +18,7 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; +use rustc_data_structures::vec_map::VecMap; use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; @@ -129,6 +130,19 @@ fn mir_borrowck<'tcx>( ) -> &'tcx BorrowCheckResult<'tcx> { let (input_body, promoted) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); + + if input_body.borrow().should_skip() { + debug!("Skipping borrowck because of injected body"); + // Let's make up a borrowck result! Fun times! + let result = BorrowCheckResult { + concrete_opaque_types: VecMap::new(), + closure_requirements: None, + used_mut_upvars: SmallVec::new(), + tainted_by_errors: None, + }; + return tcx.arena.alloc(result); + } + let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; let infcx = diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 09a747662e266..e94e038f9283b 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -152,6 +152,8 @@ declare_features! ( (active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None), /// Allows identifying the `compiler_builtins` crate. (active, compiler_builtins, "1.13.0", None, None), + /// Allows writing custom MIR + (active, custom_mir, "1.65.0", None, None), /// Outputs useful `assert!` messages (active, generic_assert, "1.63.0", None, None), /// Allows using the `rust-intrinsic`'s "ABI". diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4ff3b3f2a38b3..dc3a74956843e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -810,6 +810,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(TEST, rustc_polymorphize_error, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_def_path, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ..."), DuplicatesOk), + gated!( + custom_mir, Normal, template!(List: r#"dialect = "...", phase = "...""#), + ErrorFollowing, "the `#[custom_mir]` attribute is just used for the Rust test suite", + ), rustc_attr!(TEST, rustc_dump_program_clauses, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_dump_env_program_clauses, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0a96d23e3543b..5290d5aae46ca 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -138,6 +138,48 @@ impl MirPhase { } } } + + /// Parses an `MirPhase` from a pair of strings. Panics if this isn't possible for any reason. + pub fn parse(dialect: String, phase: Option) -> Self { + match &*dialect.to_ascii_lowercase() { + "built" => { + assert!(phase.is_none(), "Cannot specify a phase for `Built` MIR"); + MirPhase::Built + } + "analysis" => Self::Analysis(AnalysisPhase::parse(phase)), + "runtime" => Self::Runtime(RuntimePhase::parse(phase)), + _ => panic!("Unknown MIR dialect {}", dialect), + } + } +} + +impl AnalysisPhase { + pub fn parse(phase: Option) -> Self { + let Some(phase) = phase else { + return Self::Initial; + }; + + match &*phase.to_ascii_lowercase() { + "initial" => Self::Initial, + "post_cleanup" | "post-cleanup" | "postcleanup" => Self::PostCleanup, + _ => panic!("Unknown analysis phase {}", phase), + } + } +} + +impl RuntimePhase { + pub fn parse(phase: Option) -> Self { + let Some(phase) = phase else { + return Self::Initial; + }; + + match &*phase.to_ascii_lowercase() { + "initial" => Self::Initial, + "post_cleanup" | "post-cleanup" | "postcleanup" => Self::PostCleanup, + "optimized" => Self::Optimized, + _ => panic!("Unknown runtime phase {}", phase), + } + } } impl Display for MirPhase { @@ -293,6 +335,13 @@ pub struct Body<'tcx> { /// potentially allow things like `[u8; std::mem::size_of::() * 0]` due to this. pub is_polymorphic: bool, + /// The phase at which this MIR should be "injected" into the compilation process. + /// + /// Everything that comes before this `MirPhase` should be skipped. + /// + /// This is only `Some` if the function that this body comes from was annotated with `rustc_custom_mir`. + pub injection_phase: Option, + pub tainted_by_errors: Option, } @@ -339,6 +388,7 @@ impl<'tcx> Body<'tcx> { span, required_consts: Vec::new(), is_polymorphic: false, + injection_phase: None, tainted_by_errors, }; body.is_polymorphic = body.has_non_region_param(); @@ -366,6 +416,7 @@ impl<'tcx> Body<'tcx> { required_consts: Vec::new(), var_debug_info: Vec::new(), is_polymorphic: false, + injection_phase: None, tainted_by_errors: None, }; body.is_polymorphic = body.has_non_region_param(); @@ -508,6 +559,14 @@ impl<'tcx> Body<'tcx> { pub fn generator_kind(&self) -> Option { self.generator.as_ref().map(|generator| generator.generator_kind) } + + #[inline] + pub fn should_skip(&self) -> bool { + let Some(injection_phase) = self.injection_phase else { + return false; + }; + injection_phase > self.phase + } } #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)] diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs new file mode 100644 index 0000000000000..68d8766c90734 --- /dev/null +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -0,0 +1,155 @@ +//! Provides the implementation of the `custom_mir` attribute. +//! +//! Up until MIR building, this attribute has absolutely no effect. The `mir!` macro is a normal +//! decl macro that expands like any other, and the code goes through parsing, name resolution and +//! type checking like all other code. In MIR building we finally detect whether this attribute is +//! present, and if so we branch off into this module, which implements the attribute by +//! implementing a custom lowering from THIR to MIR. +//! +//! The result of this lowering is returned "normally" from the `mir_built` query, with the only +//! notable difference being that the `injected` field in the body is set. Various components of the +//! MIR pipeline, like borrowck and the pass manager will then consult this field (via +//! `body.should_skip()`) to skip the parts of the MIR pipeline that precede the MIR phase the user +//! specified. +//! +//! This file defines the general framework for the custom parsing. The parsing for all the +//! "top-level" constructs can be found in the `parse` submodule, while the parsing for statements, +//! terminators, and everything below can be found in the `parse::instruction` submodule. +//! + +use rustc_ast::Attribute; +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def_id::DefId; +use rustc_index::vec::IndexVec; +use rustc_middle::{ + mir::*, + thir::*, + ty::{Ty, TyCtxt}, +}; +use rustc_span::Span; + +mod parse; + +pub(super) fn build_custom_mir<'tcx>( + tcx: TyCtxt<'tcx>, + did: DefId, + thir: &Thir<'tcx>, + expr: ExprId, + params: &IndexVec>, + return_ty: Ty<'tcx>, + return_ty_span: Span, + span: Span, + attr: &Attribute, +) -> Body<'tcx> { + let mut body = Body { + basic_blocks: BasicBlocks::new(IndexVec::new()), + source: MirSource::item(did), + phase: MirPhase::Built, + source_scopes: IndexVec::new(), + generator: None, + local_decls: LocalDecls::new(), + user_type_annotations: IndexVec::new(), + arg_count: params.len(), + spread_arg: None, + var_debug_info: Vec::new(), + span, + required_consts: Vec::new(), + is_polymorphic: false, + tainted_by_errors: None, + injection_phase: None, + pass_count: 1, + }; + + body.local_decls.push(LocalDecl::new(return_ty, return_ty_span)); + body.basic_blocks_mut().push(BasicBlockData::new(None)); + body.source_scopes.push(SourceScopeData { + span, + parent_scope: None, + inlined: None, + inlined_parent_scope: None, + local_data: ClearCrossCrate::Clear, + }); + body.injection_phase = Some(parse_attribute(attr)); + + let mut pctxt = ParseCtxt { + tcx, + thir, + source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, + body: &mut body, + local_map: FxHashMap::default(), + block_map: FxHashMap::default(), + }; + + let res = (|| { + pctxt.parse_args(¶ms)?; + pctxt.parse_body(expr) + })(); + if let Err(err) = res { + tcx.sess.diagnostic().span_fatal( + err.span, + format!("Could not parse {}, found: {:?}", err.expected, err.item_description), + ) + } + + body +} + +fn parse_attribute(attr: &Attribute) -> MirPhase { + let meta_items = attr.meta_item_list().unwrap(); + let mut dialect: Option = None; + let mut phase: Option = None; + + for nested in meta_items { + let name = nested.name_or_empty(); + let value = nested.value_str().unwrap().as_str().to_string(); + match name.as_str() { + "dialect" => { + assert!(dialect.is_none()); + dialect = Some(value); + } + "phase" => { + assert!(phase.is_none()); + phase = Some(value); + } + other => { + panic!("Unexpected key {}", other); + } + } + } + + let Some(dialect) = dialect else { + assert!(phase.is_none()); + return MirPhase::Built; + }; + + MirPhase::parse(dialect, phase) +} + +struct ParseCtxt<'tcx, 'body> { + tcx: TyCtxt<'tcx>, + thir: &'body Thir<'tcx>, + source_info: SourceInfo, + + body: &'body mut Body<'tcx>, + local_map: FxHashMap, + block_map: FxHashMap, +} + +struct ParseError { + span: Span, + item_description: String, + expected: String, +} + +impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { + fn expr_error(&self, expr: ExprId, expected: &'static str) -> ParseError { + let expr = &self.thir[expr]; + ParseError { + span: expr.span, + item_description: format!("{:?}", expr.kind), + expected: expected.to_string(), + } + } +} + +type PResult = Result; diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs new file mode 100644 index 0000000000000..52cb0a4826d07 --- /dev/null +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -0,0 +1,245 @@ +use rustc_index::vec::IndexVec; +use rustc_middle::{mir::*, thir::*, ty::Ty}; +use rustc_span::Span; + +use super::{PResult, ParseCtxt, ParseError}; + +mod instruction; + +/// Helper macro for parsing custom MIR. +/// +/// Example usage looks something like: +/// ```rust,ignore (incomplete example) +/// parse_by_kind!( +/// self, // : &ParseCtxt +/// expr_id, // what you're matching against +/// "assignment", // the thing you're trying to parse +/// @call("mir_assign", args) => { args[0] }, // match invocations of the `mir_assign` special function +/// ExprKind::Assign { lhs, .. } => { lhs }, // match thir assignment expressions +/// // no need for fallthrough case - reasonable error is automatically generated +/// ) +/// ``` +macro_rules! parse_by_kind { + ( + $self:ident, + $expr_id:expr, + $expected:literal, + $( + @call($name:literal, $args:ident) => $call_expr:expr, + )* + $( + $pat:pat => $expr:expr, + )* + ) => {{ + let expr_id = $self.preparse($expr_id); + let expr = &$self.thir[expr_id]; + match &expr.kind { + $( + ExprKind::Call { ty, fun: _, args: $args, .. } if { + match ty.kind() { + ty::FnDef(did, _) => { + $self.tcx.is_diagnostic_item(rustc_span::Symbol::intern($name), *did) + } + _ => false, + } + } => $call_expr, + )* + $( + $pat => $expr, + )* + #[allow(unreachable_patterns)] + _ => return Err($self.expr_error(expr_id, $expected)) + } + }}; +} +pub(crate) use parse_by_kind; + +impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { + /// Expressions should only ever be matched on after preparsing them. This removes extra scopes + /// we don't care about. + fn preparse(&self, expr_id: ExprId) -> ExprId { + let expr = &self.thir[expr_id]; + match expr.kind { + ExprKind::Scope { value, .. } => self.preparse(value), + _ => expr_id, + } + } + + fn statement_as_expr(&self, stmt_id: StmtId) -> PResult { + match &self.thir[stmt_id].kind { + StmtKind::Expr { expr, .. } => Ok(*expr), + kind @ StmtKind::Let { pattern, .. } => { + return Err(ParseError { + span: pattern.span, + item_description: format!("{:?}", kind), + expected: "expression".to_string(), + }); + } + } + } + + pub fn parse_args(&mut self, params: &IndexVec>) -> PResult<()> { + for param in params.iter() { + let (var, span) = { + let pat = param.pat.as_ref().unwrap(); + match &pat.kind { + PatKind::Binding { var, .. } => (*var, pat.span), + _ => { + return Err(ParseError { + span: pat.span, + item_description: format!("{:?}", pat.kind), + expected: "local".to_string(), + }); + } + } + }; + let decl = LocalDecl::new(param.ty, span); + let local = self.body.local_decls.push(decl); + self.local_map.insert(var, local); + } + + Ok(()) + } + + /// Bodies are of the form: + /// + /// ```text + /// { + /// let bb1: BasicBlock; + /// let bb2: BasicBlock; + /// { + /// let RET: _; + /// let local1; + /// let local2; + /// + /// { + /// { // entry block + /// statement1; + /// terminator1 + /// }; + /// + /// bb1 = { + /// statement2; + /// terminator2 + /// }; + /// + /// bb2 = { + /// statement3; + /// terminator3 + /// } + /// + /// RET + /// } + /// } + /// } + /// ``` + /// + /// This allows us to easily parse the basic blocks declarations, local declarations, and + /// basic block definitions in order. + pub fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { + let body = parse_by_kind!(self, expr_id, "whole body", + ExprKind::Block { block } => self.thir[*block].expr.unwrap(), + ); + let (block_decls, rest) = parse_by_kind!(self, body, "body with block decls", + ExprKind::Block { block } => { + let block = &self.thir[*block]; + (&block.stmts, block.expr.unwrap()) + }, + ); + self.parse_block_decls(block_decls.iter().copied())?; + + let (local_decls, rest) = parse_by_kind!(self, rest, "body with local decls", + ExprKind::Block { block } => { + let block = &self.thir[*block]; + (&block.stmts, block.expr.unwrap()) + }, + ); + self.parse_local_decls(local_decls.iter().copied())?; + + let block_defs = parse_by_kind!(self, rest, "body with block defs", + ExprKind::Block { block } => &self.thir[*block].stmts, + ); + for (i, block_def) in block_defs.iter().enumerate() { + let block = self.parse_block_def(self.statement_as_expr(*block_def)?)?; + self.body.basic_blocks_mut()[BasicBlock::from_usize(i)] = block; + } + + Ok(()) + } + + fn parse_block_decls(&mut self, stmts: impl Iterator) -> PResult<()> { + for stmt in stmts { + let (var, _, _) = self.parse_let_statement(stmt)?; + let data = BasicBlockData::new(None); + let block = self.body.basic_blocks_mut().push(data); + self.block_map.insert(var, block); + } + + Ok(()) + } + + fn parse_local_decls(&mut self, mut stmts: impl Iterator) -> PResult<()> { + let (ret_var, ..) = self.parse_let_statement(stmts.next().unwrap())?; + self.local_map.insert(ret_var, Local::from_u32(0)); + + for stmt in stmts { + let (var, ty, span) = self.parse_let_statement(stmt)?; + let decl = LocalDecl::new(ty, span); + let local = self.body.local_decls.push(decl); + self.local_map.insert(var, local); + } + + Ok(()) + } + + fn parse_let_statement(&mut self, stmt_id: StmtId) -> PResult<(LocalVarId, Ty<'tcx>, Span)> { + let pattern = match &self.thir[stmt_id].kind { + StmtKind::Let { pattern, .. } => pattern, + StmtKind::Expr { expr, .. } => { + return Err(self.expr_error(*expr, "let statement")); + } + }; + + self.parse_var(pattern) + } + + fn parse_var(&mut self, mut pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> { + // Make sure we throw out any `AscribeUserType` we find + loop { + match &pat.kind { + PatKind::Binding { var, ty, .. } => break Ok((*var, *ty, pat.span)), + PatKind::AscribeUserType { subpattern, .. } => { + pat = subpattern; + } + _ => { + break Err(ParseError { + span: pat.span, + item_description: format!("{:?}", pat.kind), + expected: "local".to_string(), + }); + } + } + } + } + + fn parse_block_def(&self, expr_id: ExprId) -> PResult> { + let block = parse_by_kind!(self, expr_id, "basic block", + ExprKind::Block { block } => &self.thir[*block], + ); + + let mut data = BasicBlockData::new(None); + for stmt_id in &*block.stmts { + let stmt = self.statement_as_expr(*stmt_id)?; + let statement = self.parse_statement(stmt)?; + data.statements.push(Statement { source_info: self.source_info, kind: statement }); + } + + let Some(trailing) = block.expr else { + return Err(self.expr_error(expr_id, "terminator")) + }; + let terminator = self.parse_terminator(trailing)?; + data.terminator = Some(Terminator { source_info: self.source_info, kind: terminator }); + + Ok(data) + } +} diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs new file mode 100644 index 0000000000000..6d6176584f5f4 --- /dev/null +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -0,0 +1,72 @@ +use rustc_middle::{mir::*, thir::*, ty}; + +use super::{parse_by_kind, PResult, ParseCtxt}; + +impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { + pub fn parse_statement(&self, expr_id: ExprId) -> PResult> { + parse_by_kind!(self, expr_id, "statement", + @call("mir_retag", args) => { + Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?))) + }, + @call("mir_retag_raw", args) => { + Ok(StatementKind::Retag(RetagKind::Raw, Box::new(self.parse_place(args[0])?))) + }, + ExprKind::Assign { lhs, rhs } => { + let lhs = self.parse_place(*lhs)?; + let rhs = self.parse_rvalue(*rhs)?; + Ok(StatementKind::Assign(Box::new((lhs, rhs)))) + }, + ) + } + + pub fn parse_terminator(&self, expr_id: ExprId) -> PResult> { + parse_by_kind!(self, expr_id, "terminator", + @call("mir_return", _args) => { + Ok(TerminatorKind::Return) + }, + @call("mir_goto", args) => { + Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } ) + }, + ) + } + + fn parse_rvalue(&self, expr_id: ExprId) -> PResult> { + parse_by_kind!(self, expr_id, "rvalue", + ExprKind::Borrow { borrow_kind, arg } => Ok( + Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) + ), + ExprKind::AddressOf { mutability, arg } => Ok( + Rvalue::AddressOf(*mutability, self.parse_place(*arg)?) + ), + _ => self.parse_operand(expr_id).map(Rvalue::Use), + ) + } + + fn parse_operand(&self, expr_id: ExprId) -> PResult> { + parse_by_kind!(self, expr_id, "operand", + @call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move), + _ => self.parse_place(expr_id).map(Operand::Copy), + ) + } + + fn parse_place(&self, expr_id: ExprId) -> PResult> { + parse_by_kind!(self, expr_id, "place", + ExprKind::Deref { arg } => Ok( + self.parse_place(*arg)?.project_deeper(&[PlaceElem::Deref], self.tcx) + ), + _ => self.parse_local(expr_id).map(Place::from), + ) + } + + fn parse_local(&self, expr_id: ExprId) -> PResult { + parse_by_kind!(self, expr_id, "local", + ExprKind::VarRef { id } => Ok(self.local_map[id]), + ) + } + + fn parse_block(&self, expr_id: ExprId) -> PResult { + parse_by_kind!(self, expr_id, "basic block", + ExprKind::VarRef { id } => Ok(self.block_map[id]), + ) + } +} diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index cbcf9cd129f3f..437ac8d82a1a3 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -481,6 +481,22 @@ fn construct_fn<'tcx>( (None, fn_sig.output()) }; + if let Some(custom_mir_attr) = + tcx.hir().attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) + { + return custom::build_custom_mir( + tcx, + fn_def.did.to_def_id(), + thir, + expr, + arguments, + return_ty, + return_ty_span, + span, + custom_mir_attr, + ); + } + let infcx = tcx.infer_ctxt().build(); let mut builder = Builder::new( thir, @@ -1033,6 +1049,7 @@ pub(crate) fn parse_float_into_scalar( mod block; mod cfg; +mod custom; mod expr; mod matches; mod misc; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c7a7c3e3fa8ee..c4639d3a513df 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -51,11 +51,17 @@ impl<'tcx> Cx<'tcx> { trace!(?expr.ty); // Now apply adjustments, if any. - for adjustment in self.typeck_results.expr_adjustments(hir_expr) { - trace!(?expr, ?adjustment); - let span = expr.span; - expr = - self.apply_adjustment(hir_expr, expr, adjustment, adjustment_span.unwrap_or(span)); + if self.apply_adjustments { + for adjustment in self.typeck_results.expr_adjustments(hir_expr) { + trace!(?expr, ?adjustment); + let span = expr.span; + expr = self.apply_adjustment( + hir_expr, + expr, + adjustment, + adjustment_span.unwrap_or(span), + ); + } } trace!(?expr.ty, "after adjustments"); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 1d95d6b53fbec..b5c4b7b137d4c 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -80,6 +80,9 @@ struct Cx<'tcx> { /// for the receiver. adjustment_span: Option<(HirId, Span)>, + /// False to indicate that adjustments should not be applied. Only used for `custom_mir` + apply_adjustments: bool, + /// The `DefId` of the owner of this body. body_owner: DefId, } @@ -87,6 +90,8 @@ struct Cx<'tcx> { impl<'tcx> Cx<'tcx> { fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam) -> Cx<'tcx> { let typeck_results = tcx.typeck_opt_const_arg(def); + let did = def.did; + let hir = tcx.hir(); Cx { tcx, thir: Thir::new(), @@ -94,8 +99,12 @@ impl<'tcx> Cx<'tcx> { region_scope_tree: tcx.region_scope_tree(def.did), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, - body_owner: def.did.to_def_id(), + body_owner: did.to_def_id(), adjustment_span: None, + apply_adjustments: hir + .attrs(hir.local_def_id_to_hir_id(did)) + .iter() + .all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir), } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 269d9f3b102c1..e783d18913774 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -471,6 +471,14 @@ fn unsafety_check_result<'tcx>( // `mir_built` force this. let body = &tcx.mir_built(def).borrow(); + if body.should_skip() { + return tcx.arena.alloc(UnsafetyCheckResult { + violations: Vec::new(), + used_unsafe_blocks: FxHashSet::default(), + unused_unsafes: Some(Vec::new()), + }); + } + let param_env = tcx.param_env(def.did); let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 230c6a7cb4b00..27dbc3e22c97a 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -96,45 +96,48 @@ fn run_passes_inner<'tcx>( phase_change: Option, validate_each: bool, ) { - let validate = validate_each & tcx.sess.opts.unstable_opts.validate_mir; + let validate = validate_each & tcx.sess.opts.unstable_opts.validate_mir & !body.should_skip(); let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes; trace!(?overridden_passes); - for pass in passes { - let name = pass.name(); - - let overridden = - overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(|(_name, polarity)| { - trace!( - pass = %name, - "{} as requested by flag", - if *polarity { "Running" } else { "Not running" }, - ); - *polarity - }); - if !overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess)) { - continue; + if !body.should_skip() { + for pass in passes { + let name = pass.name(); + + let overridden = overridden_passes.iter().rev().find(|(s, _)| s == &*name).map( + |(_name, polarity)| { + trace!( + pass = %name, + "{} as requested by flag", + if *polarity { "Running" } else { "Not running" }, + ); + *polarity + }, + ); + if !overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess)) { + continue; + } + + let dump_enabled = pass.is_mir_dump_enabled(); + + if dump_enabled { + dump_mir_for_pass(tcx, body, &name, false); + } + if validate { + validate_body(tcx, body, format!("before pass {}", name)); + } + + pass.run_pass(tcx, body); + + if dump_enabled { + dump_mir_for_pass(tcx, body, &name, true); + } + if validate { + validate_body(tcx, body, format!("after pass {}", name)); + } + + body.pass_count += 1; } - - let dump_enabled = pass.is_mir_dump_enabled(); - - if dump_enabled { - dump_mir_for_pass(tcx, body, &name, false); - } - if validate { - validate_body(tcx, body, format!("before pass {}", name)); - } - - pass.run_pass(tcx, body); - - if dump_enabled { - dump_mir_for_pass(tcx, body, &name, true); - } - if validate { - validate_body(tcx, body, format!("after pass {}", name)); - } - - body.pass_count += 1; } if let Some(new_phase) = phase_change { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cccc4897ecca6..54a61483a11a3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -584,6 +584,7 @@ symbols! { custom_attribute, custom_derive, custom_inner_attributes, + custom_mir, custom_test_frameworks, d, d32, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index bfbd4301230ae..cec603dcb10ed 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -59,6 +59,9 @@ use crate::marker::DiscriminantKind; use crate::marker::Tuple; use crate::mem; +#[cfg(not(bootstrap))] +pub mod mir; + // These imports are used for simplifying intra-doc links #[allow(unused_imports)] #[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))] diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs new file mode 100644 index 0000000000000..1bacdc39148a1 --- /dev/null +++ b/library/core/src/intrinsics/mir.rs @@ -0,0 +1,123 @@ +//! Rustc internal tooling for hand-writing MIR. +//! +//! If for some reasons you are not writing rustc tests and have found yourself considering using +//! this feature, turn back. This is *exceptionally* unstable. There is no attempt at all to make +//! anything work besides those things which the rustc test suite happened to need. If you make a +//! typo you'll probably ICE. Really, this is not the solution to your problems. Consider instead +//! supporting the [stable MIR project group](https://github.com/rust-lang/project-stable-mir). +//! +//! The documentation for this module describes how to use this feature. If you are interested in +//! hacking on the implementation, most of that documentation lives at +//! `rustc_mir_building/src/build/custom/mod.rs`. +//! +//! Typical usage will look like this: +//! +//! ```rust +//! #![feature(core_intrinsics, custom_mir)] +//! +//! extern crate core; +//! use core::intrinsics::mir::*; +//! +//! #[custom_mir(dialect = "built")] +//! pub fn simple(x: i32) -> i32 { +//! mir!( +//! let temp1: i32; +//! let temp2: _; +//! +//! { +//! temp1 = x; +//! Goto(exit) +//! } +//! +//! exit = { +//! temp2 = Move(temp1); +//! RET = temp2; +//! Return() +//! } +//! ) +//! } +//! ``` +//! +//! Hopefully most of this is fairly self-explanatory. Expanding on some notable details: +//! +//! - The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This +//! attribute only works on functions - there is no way to insert custom MIR into the middle of +//! another function. +//! - The `dialect` and `phase` parameters indicate which version of MIR you are inserting here. +//! This will normally be the phase that corresponds to the thing you are trying to test. The +//! phase can be omitted for dialects that have just one. +//! - You should define your function signature like you normally would. Externally, this function +//! can be called like any other function. +//! - Type inference works - you don't have to spell out the type of all of your locals. +//! +//! For now, all statements and terminators are parsed from nested invocations of the special +//! functions provided in this module. We additionally want to (but do not yet) support more +//! "normal" Rust syntax in places where it makes sense. Also, most kinds of instructions are not +//! supported yet. +//! + +#![unstable( + feature = "custom_mir", + reason = "MIR is an implementation detail and extremely unstable", + issue = "none" +)] +#![allow(unused_variables, non_snake_case, missing_debug_implementations)] + +/// Type representing basic blocks. +/// +/// All terminators will have this type as a return type. It helps achieve some type safety. +pub struct BasicBlock; + +macro_rules! define { + ($name:literal, $($sig:tt)*) => { + #[rustc_diagnostic_item = $name] + pub $($sig)* { panic!() } + } +} + +define!("mir_return", fn Return() -> BasicBlock); +define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock); +define!("mir_retag", fn Retag(place: T)); +define!("mir_retag_raw", fn RetagRaw(place: T)); +define!("mir_move", fn Move(place: T) -> T); + +/// Convenience macro for generating custom MIR. +/// +/// See the module documentation for syntax details. This macro is not magic - it only transforms +/// your MIR into something that is easier to parse in the compiler. +#[rustc_macro_transparency = "transparent"] +pub macro mir { + ( + $(let $local_decl:ident $(: $local_decl_ty:ty)? ;)* + + $entry_block:block + + $( + $block_name:ident = $block:block + )* + ) => {{ + // First, we declare all basic blocks. + $( + let $block_name: ::core::intrinsics::mir::BasicBlock; + )* + + { + // Now all locals + #[allow(non_snake_case)] + let RET; + $( + let $local_decl $(: $local_decl_ty)? ; + )* + + { + // Finally, the contents of the basic blocks + $entry_block; + $( + $block; + )* + + RET + } + } + }} +} diff --git a/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir new file mode 100644 index 0000000000000..4a5ddde4081e2 --- /dev/null +++ b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir @@ -0,0 +1,14 @@ +// MIR for `immut_ref` after built + +fn immut_ref(_1: &i32) -> &i32 { + let mut _0: &i32; // return place in scope 0 at $DIR/references.rs:+0:30: +0:34 + let mut _2: *const i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+0:1: +0:34 + Retag([raw] _2); // scope 0 at $DIR/references.rs:+0:1: +0:34 + _0 = &(*_2); // scope 0 at $DIR/references.rs:+0:1: +0:34 + Retag(_0); // scope 0 at $DIR/references.rs:+0:1: +0:34 + return; // scope 0 at $DIR/references.rs:+0:1: +0:34 + } +} diff --git a/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir new file mode 100644 index 0000000000000..ec8509f69d14e --- /dev/null +++ b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir @@ -0,0 +1,14 @@ +// MIR for `mut_ref` after built + +fn mut_ref(_1: &mut i32) -> &mut i32 { + let mut _0: &mut i32; // return place in scope 0 at $DIR/references.rs:+0:32: +0:40 + let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+0:1: +0:40 + Retag([raw] _2); // scope 0 at $DIR/references.rs:+0:1: +0:40 + _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+0:1: +0:40 + Retag(_0); // scope 0 at $DIR/references.rs:+0:1: +0:40 + return; // scope 0 at $DIR/references.rs:+0:1: +0:40 + } +} diff --git a/src/test/mir-opt/building/custom/references.rs b/src/test/mir-opt/building/custom/references.rs new file mode 100644 index 0000000000000..dee85722e8656 --- /dev/null +++ b/src/test/mir-opt/building/custom/references.rs @@ -0,0 +1,43 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; +use core::ptr::{addr_of, addr_of_mut}; + +// EMIT_MIR references.mut_ref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub fn mut_ref(x: &mut i32) -> &mut i32 { + mir!( + let t: *mut i32; + + { + t = addr_of_mut!(*x); + RetagRaw(t); + RET = &mut *t; + Retag(RET); + Return() + } + ) +} + +// EMIT_MIR references.immut_ref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub fn immut_ref(x: &i32) -> &i32 { + mir!( + let t: *const i32; + + { + t = addr_of!(*x); + RetagRaw(t); + RET = & *t; + Retag(RET); + Return() + } + ) +} + +fn main() { + let mut x = 5; + assert_eq!(*mut_ref(&mut x), 5); + assert_eq!(*immut_ref(&x), 5); +} diff --git a/src/test/mir-opt/building/custom/simple_assign.rs b/src/test/mir-opt/building/custom/simple_assign.rs new file mode 100644 index 0000000000000..ec6dbe1d0526b --- /dev/null +++ b/src/test/mir-opt/building/custom/simple_assign.rs @@ -0,0 +1,37 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR simple_assign.simple.built.after.mir +#[custom_mir(dialect = "built")] +pub fn simple(x: i32) -> i32 { + mir!( + let temp1: i32; + let temp2: _; + + { + temp1 = x; + Goto(exit) + } + + exit = { + temp2 = Move(temp1); + RET = temp2; + Return() + } + ) +} + +// EMIT_MIR simple_assign.simple_ref.built.after.mir +#[custom_mir(dialect = "built")] +pub fn simple_ref(x: &mut i32) -> &mut i32 { + mir!({ + RET = Move(x); + Return() + }) +} + +fn main() { + assert_eq!(5, simple(5)); +} diff --git a/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir new file mode 100644 index 0000000000000..a5a2834c2e1bf --- /dev/null +++ b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir @@ -0,0 +1,18 @@ +// MIR for `simple` after built + +fn simple(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:26: +0:29 + let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = _1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + } + + bb1: { + _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + _0 = _3; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + return; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:29 + } +} diff --git a/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir new file mode 100644 index 0000000000000..6c90f0130a2e6 --- /dev/null +++ b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `simple_ref` after built + +fn simple_ref(_1: &mut i32) -> &mut i32 { + let mut _0: &mut i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:35: +0:43 + + bb0: { + _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:43 + return; // scope 0 at $DIR/simple_assign.rs:+0:1: +0:43 + } +} diff --git a/src/test/ui/feature-gates/feature-gate-custom_mir.rs b/src/test/ui/feature-gates/feature-gate-custom_mir.rs new file mode 100644 index 0000000000000..0126dde2f7d4b --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-custom_mir.rs @@ -0,0 +1,12 @@ +#![feature(core_intrinsics)] + +extern crate core; + +#[custom_mir(dialect = "built")] //~ ERROR the `#[custom_mir]` attribute is just used for the Rust test suite +pub fn foo(_x: i32) -> i32 { + 0 +} + +fn main() { + assert_eq!(2, foo(2)); +} diff --git a/src/test/ui/feature-gates/feature-gate-custom_mir.stderr b/src/test/ui/feature-gates/feature-gate-custom_mir.stderr new file mode 100644 index 0000000000000..3c149d30d82bd --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-custom_mir.stderr @@ -0,0 +1,11 @@ +error[E0658]: the `#[custom_mir]` attribute is just used for the Rust test suite + --> $DIR/feature-gate-custom_mir.rs:5:1 + | +LL | #[custom_mir(dialect = "built")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(custom_mir)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From 9ee9d09a5340dc897bbe6a6cb901f36973439939 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Sun, 23 Oct 2022 16:41:36 -0500 Subject: [PATCH 332/482] Merge apple_base and apple_sdk_base into one module --- .../src/spec/aarch64_apple_darwin.rs | 9 +- .../src/spec/aarch64_apple_ios.rs | 8 +- .../src/spec/aarch64_apple_ios_macabi.rs | 2 +- .../src/spec/aarch64_apple_ios_sim.rs | 8 +- .../src/spec/aarch64_apple_tvos.rs | 2 +- .../src/spec/aarch64_apple_watchos_sim.rs | 8 +- compiler/rustc_target/src/spec/apple_base.rs | 98 ++++++++++++++++--- .../rustc_target/src/spec/apple_sdk_base.rs | 81 --------------- .../src/spec/arm64_32_apple_watchos.rs | 2 +- .../rustc_target/src/spec/armv7_apple_ios.rs | 7 +- .../src/spec/armv7k_apple_watchos.rs | 2 +- .../rustc_target/src/spec/armv7s_apple_ios.rs | 2 +- .../rustc_target/src/spec/i386_apple_ios.rs | 7 +- .../src/spec/i686_apple_darwin.rs | 7 +- compiler/rustc_target/src/spec/mod.rs | 1 - .../src/spec/x86_64_apple_darwin.rs | 11 ++- .../rustc_target/src/spec/x86_64_apple_ios.rs | 7 +- .../src/spec/x86_64_apple_ios_macabi.rs | 2 +- .../src/spec/x86_64_apple_tvos.rs | 2 +- .../src/spec/x86_64_apple_watchos_sim.rs | 4 +- 20 files changed, 134 insertions(+), 136 deletions(-) delete mode 100644 compiler/rustc_target/src/spec/apple_sdk_base.rs diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index 6d919a4c2ad2e..13a13f2f073c8 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -1,20 +1,21 @@ +use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = "arm64"; - let mut base = super::apple_base::opts("macos", arch, ""); + let arch = Arch::Arm64; + let mut base = opts("macos", arch); base.cpu = "apple-a14".into(); base.max_atomic_width = Some(128); // FIXME: The leak sanitizer currently fails the tests, see #88132. base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD; - base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); + base.link_env_remove.to_mut().extend(macos_link_env_remove()); // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work // correctly, we do too. - let llvm_target = super::apple_base::macos_llvm_target(arch); + let llvm_target = macos_llvm_target(arch.target_name()); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index beb9042390b7f..1f9ac7ce59b06 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{ios_llvm_target, opts, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { @@ -6,8 +6,8 @@ pub fn target() -> Target { // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the target to pick the right // MACH-O commands, so we do too. - let arch = "arm64"; - let llvm_target = super::apple_base::ios_llvm_target(arch); + let arch = Arch::Arm64; + let llvm_target = ios_llvm_target(arch); Target { llvm_target: llvm_target.into(), @@ -30,7 +30,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..opts("ios", Arch::Arm64) + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs index 2d2671549cf51..c2106b456becf 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs index b4e135f66e941..097b92f2e8fdb 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs @@ -1,15 +1,15 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("ios", Arch::Arm64_sim); + let arch = Arch::Arm64_sim; + let base = opts("ios", arch); // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the simulator target to pick the right // MACH-O commands, so we do too. - let arch = "arm64"; - let llvm_target = super::apple_base::ios_sim_llvm_target(arch); + let llvm_target = ios_sim_llvm_target(arch); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index 2e31d16dc76ca..8cf24e4bf1f6c 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs index 3059f42140be4..b6c8cd46c050c 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs @@ -1,15 +1,15 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, watchos_sim_llvm_target, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::Arm64_sim); + let arch = Arch::Arm64_sim; + let base = opts("watchos", arch); // Clang automatically chooses a more specific target based on // WATCHOS_DEPLOYMENT_TARGET. // This is required for the simulator target to pick the right // MACH-O commands, so we do too. - let arch = "arm64"; - let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); + let llvm_target = watchos_sim_llvm_target(arch); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 40bc59ca145e5..eb7f457d60bc2 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -3,6 +3,75 @@ use std::{borrow::Cow, env}; use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs}; use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, TargetOptions}; +#[cfg(test)] +#[path = "apple/tests.rs"] +mod tests; + +use Arch::*; +#[allow(non_camel_case_types)] +#[derive(Copy, Clone)] +pub enum Arch { + Armv7, + Armv7k, + Armv7s, + Arm64, + Arm64_32, + I386, + X86_64, + X86_64_sim, + X86_64_macabi, + Arm64_macabi, + Arm64_sim, +} + +impl Arch { + pub fn target_name(self) -> &'static str { + match self { + Armv7 => "armv7", + Armv7k => "armv7k", + Armv7s => "armv7s", + Arm64 | Arm64_macabi | Arm64_sim => "arm64", + Arm64_32 => "arm64_32", + I386 => "i386", + X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + } + } + + fn target_abi(self) -> &'static str { + match self { + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", + X86_64_macabi | Arm64_macabi => "macabi", + // x86_64-apple-ios is a simulator target, even though it isn't + // declared that way in the target like the other ones... + Arm64_sim | X86_64_sim => "sim", + } + } + + fn target_cpu(self) -> &'static str { + match self { + Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher + Armv7k => "cortex-a8", + Armv7s => "cortex-a9", + Arm64 => "apple-a7", + Arm64_32 => "apple-s4", + I386 => "yonah", + X86_64 | X86_64_sim => "core2", + X86_64_macabi => "core2", + Arm64_macabi => "apple-a12", + Arm64_sim => "apple-a12", + } + } + + fn link_env_remove(self) -> StaticCow<[StaticCow]> { + match self { + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | X86_64_sim | Arm64_sim => { + cvs!["MACOSX_DEPLOYMENT_TARGET"] + } + X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], + } + } +} + fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs { let platform_name: StaticCow = match abi { "sim" => format!("{}-simulator", os).into(), @@ -35,30 +104,35 @@ fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> Lin args } -pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOptions { - // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 +pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { + // Static TLS is only available in macOS 10.7+. If you try to compile for 10.6 // either the linker will complain if it is used or the binary will end up // segfaulting at runtime when run on 10.6. Rust by default supports macOS // 10.7+, but there is a standard environment variable, // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older // versions of macOS. For example compiling on 10.10 with // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate - // warnings about the usage of ELF TLS. + // warnings about the usage of static TLS. // - // Here we detect what version is being requested, defaulting to 10.7. ELF + // Here we detect what version is being requested, defaulting to 10.7. Static // TLS is flagged as enabled if it looks to be supported. The architecture // only matters for default deployment target which is 11.0 for ARM64 and // 10.7 for everything else. - let has_thread_local = macos_deployment_target("x86_64") >= (10, 7); + let has_thread_local = os == "macos" && macos_deployment_target("x86_64") >= (10, 7); + + let abi = arch.target_abi(); TargetOptions { + abi: abi.into(), os: os.into(), + cpu: arch.target_cpu().into(), + link_env_remove: arch.link_env_remove(), vendor: "apple".into(), linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No), // macOS has -dead_strip, which doesn't rely on function_sections function_sections: false, dynamic_linking: true, - pre_link_args: pre_link_args(os, arch, abi), + pre_link_args: pre_link_args(os, arch.target_name(), abi), families: cvs!["unix"], is_like_osx: true, default_dwarf_version: 2, @@ -142,7 +216,7 @@ fn ios_deployment_target() -> (u32, u32) { deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0)) } -pub fn ios_llvm_target(arch: &str) -> String { +pub fn ios_llvm_target(arch: Arch) -> String { // Modern iOS tooling extracts information about deployment target // from LC_BUILD_VERSION. This load command will only be emitted when // we build with a version specific `llvm_target`, with the version @@ -150,7 +224,7 @@ pub fn ios_llvm_target(arch: &str) -> String { // to pick it up (since std and core are still built with the fallback // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION). let (major, minor) = ios_deployment_target(); - format!("{}-apple-ios{}.{}.0", arch, major, minor) + format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor) } fn ios_lld_platform_version() -> String { @@ -158,9 +232,9 @@ fn ios_lld_platform_version() -> String { format!("{}.{}", major, minor) } -pub fn ios_sim_llvm_target(arch: &str) -> String { +pub fn ios_sim_llvm_target(arch: Arch) -> String { let (major, minor) = ios_deployment_target(); - format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor) + format!("{}-apple-ios{}.{}.0-simulator", arch.target_name(), major, minor) } fn tvos_deployment_target() -> (u32, u32) { @@ -181,7 +255,7 @@ fn watchos_lld_platform_version() -> String { format!("{}.{}", major, minor) } -pub fn watchos_sim_llvm_target(arch: &str) -> String { +pub fn watchos_sim_llvm_target(arch: Arch) -> String { let (major, minor) = watchos_deployment_target(); - format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor) + format!("{}-apple-watchos{}.{}.0-simulator", arch.target_name(), major, minor) } diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs deleted file mode 100644 index 148031b156976..0000000000000 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::spec::{cvs, TargetOptions}; -use std::borrow::Cow; - -#[cfg(test)] -#[path = "apple/tests.rs"] -mod tests; - -use Arch::*; -#[allow(non_camel_case_types)] -#[derive(Copy, Clone)] -pub enum Arch { - Armv7, - Armv7k, - Armv7s, - Arm64, - Arm64_32, - I386, - #[allow(dead_code)] // Some targets don't use this enum... - X86_64, - X86_64_sim, - X86_64_macabi, - Arm64_macabi, - Arm64_sim, -} - -fn target_arch_name(arch: Arch) -> &'static str { - match arch { - Armv7 => "armv7", - Armv7k => "armv7k", - Armv7s => "armv7s", - Arm64 | Arm64_macabi | Arm64_sim => "arm64", - Arm64_32 => "arm64_32", - I386 => "i386", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", - } -} - -fn target_abi(arch: Arch) -> &'static str { - match arch { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", - X86_64_macabi | Arm64_macabi => "macabi", - // x86_64-apple-ios is a simulator target, even though it isn't - // declared that way in the target like the other ones... - Arm64_sim | X86_64_sim => "sim", - } -} - -fn target_cpu(arch: Arch) -> &'static str { - match arch { - Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher - Armv7k => "cortex-a8", - Armv7s => "cortex-a9", - Arm64 => "apple-a7", - Arm64_32 => "apple-s4", - I386 => "yonah", - X86_64 | X86_64_sim => "core2", - X86_64_macabi => "core2", - Arm64_macabi => "apple-a12", - Arm64_sim => "apple-a12", - } -} - -fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> { - match arch { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | X86_64_sim | Arm64_sim => { - cvs!["MACOSX_DEPLOYMENT_TARGET"] - } - X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], - } -} - -pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { - let abi = target_abi(arch); - TargetOptions { - abi: abi.into(), - cpu: target_cpu(arch).into(), - link_env_remove: link_env_remove(arch), - has_thread_local: false, - ..super::apple_base::opts(os, target_arch_name(arch), abi) - } -} diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs index cb7f5f2a5830b..2cf2cbc751000 100644 --- a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs index 57fd74a36b654..5167af3e7f22c 100644 --- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs @@ -1,8 +1,9 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let llvm_target = super::apple_base::ios_llvm_target("armv7"); + let arch = Arch::Armv7; + let llvm_target = super::apple_base::ios_llvm_target(arch); Target { llvm_target: llvm_target.into(), @@ -12,7 +13,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v7,+vfp3,+neon".into(), max_atomic_width: Some(64), - ..opts("ios", Arch::Armv7) + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs index af5d1c2ff4581..7e9c9b5c26878 100644 --- a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs index cc17265b2b8db..30851564523bc 100644 --- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index b85214a9c6b4a..21635642c18a3 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -1,9 +1,10 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("ios", Arch::I386); - let llvm_target = super::apple_base::ios_sim_llvm_target("i386"); + let arch = Arch::I386; + let base = opts("ios", arch); + let llvm_target = super::apple_base::ios_sim_llvm_target(arch); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 15607c12ea906..84dae68877dfd 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -1,12 +1,13 @@ +use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understand i386 and not i686 - let mut base = super::apple_base::opts("macos", "i386", ""); + let mut base = opts("macos", Arch::I386); base.cpu = "yonah".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); - base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); + base.link_env_remove.to_mut().extend(macos_link_env_remove()); base.stack_probes = StackProbeType::X86; base.frame_pointer = FramePointer::Always; @@ -14,7 +15,7 @@ pub fn target() -> Target { // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work // correctly, we do too. let arch = "i686"; - let llvm_target = super::apple_base::macos_llvm_target(&arch); + let llvm_target = macos_llvm_target(arch); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 72b088d663b1f..9baf7655595bf 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -59,7 +59,6 @@ pub mod crt_objects; mod android_base; mod apple_base; -mod apple_sdk_base; mod avr_gnu_base; mod bpf_base; mod dragonfly_base; diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 087be1b957b14..6112ef7ec1f93 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,14 +1,15 @@ +use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let arch = "x86_64"; - let mut base = super::apple_base::opts("macos", arch, ""); + let arch = Arch::X86_64; + let mut base = opts("macos", arch); base.cpu = "core2".into(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); - base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); + base.link_env_remove.to_mut().extend(macos_link_env_remove()); base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; @@ -16,14 +17,14 @@ pub fn target() -> Target { // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work // correctly, we do too. - let llvm_target = super::apple_base::macos_llvm_target(&arch); + let llvm_target = macos_llvm_target(arch.target_name()); Target { llvm_target: llvm_target.into(), pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), - arch: arch.into(), + arch: "x86_84".into(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index db23f01c23326..032ba0763b4c5 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -1,9 +1,10 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("ios", Arch::X86_64_sim); - let llvm_target = super::apple_base::ios_sim_llvm_target("x86_64"); + let arch = Arch::X86_64_sim; + let base = opts("ios", arch); + let llvm_target = ios_sim_llvm_target(arch); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 13259205ac0f8..6647c1d29217e 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index c1fd8e1c8b90a..cb70717b3c42f 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -1,4 +1,4 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs index 550566b2aa754..03ea66499db1d 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -1,10 +1,10 @@ -use super::apple_sdk_base::{opts, Arch}; +use super::apple_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::X86_64_sim; let base = opts("watchos", Arch::X86_64_sim); - let arch = "x86_64"; let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); Target { From 952875ef1eec41d0261155e3bfdf876753137dfb Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Sun, 23 Oct 2022 17:22:54 -0500 Subject: [PATCH 333/482] Cleanup Apple target specifications --- .../src/spec/aarch64_apple_darwin.rs | 12 +++--- .../src/spec/aarch64_apple_ios.rs | 14 +++---- .../src/spec/aarch64_apple_ios_macabi.rs | 5 ++- .../src/spec/aarch64_apple_ios_sim.rs | 18 ++++----- .../src/spec/aarch64_apple_tvos.rs | 5 ++- .../src/spec/aarch64_apple_watchos_sim.rs | 18 ++++----- compiler/rustc_target/src/spec/apple_base.rs | 39 +++++++++++++------ .../rustc_target/src/spec/armv7_apple_ios.rs | 12 +++--- .../src/spec/armv7k_apple_watchos.rs | 6 +-- .../rustc_target/src/spec/armv7s_apple_ios.rs | 5 ++- .../rustc_target/src/spec/i386_apple_ios.rs | 15 +++---- .../src/spec/i686_apple_darwin.rs | 21 +++++----- .../src/spec/x86_64_apple_darwin.rs | 15 +++---- .../rustc_target/src/spec/x86_64_apple_ios.rs | 9 ++--- .../src/spec/x86_64_apple_ios_macabi.rs | 5 ++- .../src/spec/x86_64_apple_tvos.rs | 6 +-- .../src/spec/x86_64_apple_watchos_sim.rs | 12 ++---- 17 files changed, 108 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index 13a13f2f073c8..0f6bbc323174c 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -12,16 +12,14 @@ pub fn target() -> Target { base.link_env_remove.to_mut().extend(macos_link_env_remove()); - // Clang automatically chooses a more specific target based on - // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work - // correctly, we do too. - let llvm_target = macos_llvm_target(arch.target_name()); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index 1f9ac7ce59b06..b5f9eb1259dac 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -2,18 +2,16 @@ use super::apple_base::{ios_llvm_target, opts, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - // Clang automatically chooses a more specific target based on - // IPHONEOS_DEPLOYMENT_TARGET. - // This is required for the target to pick the right - // MACH-O commands, so we do too. let arch = Arch::Arm64; - let llvm_target = ios_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // IPHONEOS_DEPLOYMENT_TARGET. + // This is required for the target to pick the right + // MACH-O commands, so we do too. + llvm_target: ios_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs index c2106b456becf..0009972cf4256 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs @@ -4,14 +4,15 @@ use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let llvm_target = "arm64-apple-ios14.0-macabi"; - let mut base = opts("ios", Arch::Arm64_macabi); + let arch = Arch::Arm64_macabi; + let mut base = opts("ios", arch); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-target", llvm_target]); Target { llvm_target: llvm_target.into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs index 097b92f2e8fdb..3374755e2dd8b 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs @@ -3,19 +3,15 @@ use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64_sim; - let base = opts("ios", arch); - - // Clang automatically chooses a more specific target based on - // IPHONEOS_DEPLOYMENT_TARGET. - // This is required for the simulator target to pick the right - // MACH-O commands, so we do too. - let llvm_target = ios_sim_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // IPHONEOS_DEPLOYMENT_TARGET. + // This is required for the simulator target to pick the right + // MACH-O commands, so we do too. + llvm_target: ios_sim_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), @@ -32,7 +28,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..base + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index 8cf24e4bf1f6c..bb7c39ff26bdf 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -2,17 +2,18 @@ use super::apple_base::{opts, Arch}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::Arm64; Target { llvm_target: "arm64-apple-tvos".into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), forces_embed_bitcode: true, frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", Arch::Arm64) + ..opts("tvos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs index b6c8cd46c050c..e4af4127c2223 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs @@ -3,19 +3,15 @@ use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64_sim; - let base = opts("watchos", arch); - - // Clang automatically chooses a more specific target based on - // WATCHOS_DEPLOYMENT_TARGET. - // This is required for the simulator target to pick the right - // MACH-O commands, so we do too. - let llvm_target = watchos_sim_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // WATCHOS_DEPLOYMENT_TARGET. + // This is required for the simulator target to pick the right + // MACH-O commands, so we do too. + llvm_target: watchos_sim_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), - arch: "aarch64".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), @@ -32,7 +28,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..base + ..opts("watchos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index eb7f457d60bc2..23c826cb1bda2 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -17,6 +17,7 @@ pub enum Arch { Arm64, Arm64_32, I386, + I686, X86_64, X86_64_sim, X86_64_macabi, @@ -33,13 +34,23 @@ impl Arch { Arm64 | Arm64_macabi | Arm64_sim => "arm64", Arm64_32 => "arm64_32", I386 => "i386", + I686 => "i686", X86_64 | X86_64_sim | X86_64_macabi => "x86_64", } } + pub fn target_arch(self) -> Cow<'static, str> { + Cow::Borrowed(match self { + Armv7 | Armv7k | Armv7s => "arm", + Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", + I386 | I686 => "x86", + X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + }) + } + fn target_abi(self) -> &'static str { match self { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 => "", X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... @@ -54,7 +65,7 @@ impl Arch { Armv7s => "cortex-a9", Arm64 => "apple-a7", Arm64_32 => "apple-s4", - I386 => "yonah", + I386 | I686 => "yonah", X86_64 | X86_64_sim => "core2", X86_64_macabi => "core2", Arm64_macabi => "apple-a12", @@ -64,7 +75,8 @@ impl Arch { fn link_env_remove(self) -> StaticCow<[StaticCow]> { match self { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | X86_64_sim | Arm64_sim => { + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim + | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], @@ -72,7 +84,7 @@ impl Arch { } } -fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs { +fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { let platform_name: StaticCow = match abi { "sim" => format!("{}-simulator", os).into(), "macabi" => "mac-catalyst".into(), @@ -88,6 +100,8 @@ fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> Lin } .into(); + let arch = arch.target_name(); + let mut args = TargetOptions::link_args( LinkerFlavor::Darwin(Cc::No, Lld::No), &["-arch", arch, "-platform_version"], @@ -118,7 +132,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { // TLS is flagged as enabled if it looks to be supported. The architecture // only matters for default deployment target which is 11.0 for ARM64 and // 10.7 for everything else. - let has_thread_local = os == "macos" && macos_deployment_target("x86_64") >= (10, 7); + let has_thread_local = os == "macos" && macos_deployment_target(Arch::X86_64) >= (10, 7); let abi = arch.target_abi(); @@ -132,7 +146,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { // macOS has -dead_strip, which doesn't rely on function_sections function_sections: false, dynamic_linking: true, - pre_link_args: pre_link_args(os, arch.target_name(), abi), + pre_link_args: pre_link_args(os, arch, abi), families: cvs!["unix"], is_like_osx: true, default_dwarf_version: 2, @@ -177,23 +191,24 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> { .and_then(|(a, b)| a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok()) } -fn macos_default_deployment_target(arch: &str) -> (u32, u32) { - if arch == "arm64" { (11, 0) } else { (10, 7) } +fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { + // Note: Arm64_sim is not included since macOS has no simulator. + if matches!(arch, Arm64 | Arm64_macabi) { (11, 0) } else { (10, 7) } } -fn macos_deployment_target(arch: &str) -> (u32, u32) { +fn macos_deployment_target(arch: Arch) -> (u32, u32) { deployment_target("MACOSX_DEPLOYMENT_TARGET") .unwrap_or_else(|| macos_default_deployment_target(arch)) } -fn macos_lld_platform_version(arch: &str) -> String { +fn macos_lld_platform_version(arch: Arch) -> String { let (major, minor) = macos_deployment_target(arch); format!("{}.{}", major, minor) } -pub fn macos_llvm_target(arch: &str) -> String { +pub fn macos_llvm_target(arch: Arch) -> String { let (major, minor) = macos_deployment_target(arch); - format!("{}-apple-macosx{}.{}.0", arch, major, minor) + format!("{}-apple-macosx{}.{}.0", arch.target_name(), major, minor) } pub fn macos_link_env_remove() -> Vec> { diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs index 5167af3e7f22c..3259c854791ce 100644 --- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs @@ -1,15 +1,17 @@ -use super::apple_base::{opts, Arch}; +use super::apple_base::{ios_llvm_target, opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Armv7; - let llvm_target = super::apple_base::ios_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // IPHONEOS_DEPLOYMENT_TARGET. + // This is required for the target to pick the right + // MACH-O commands, so we do too. + llvm_target: ios_llvm_target(arch).into(), pointer_width: 32, data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(), - arch: "arm".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+v7,+vfp3,+neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs index 7e9c9b5c26878..45ead8d65aba9 100644 --- a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs @@ -2,12 +2,12 @@ use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::Armv7k); + let arch = Arch::Armv7k; Target { llvm_target: "armv7k-apple-watchos".into(), pointer_width: 32, data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(), - arch: "arm".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), @@ -22,7 +22,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..base + ..opts("watchos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs index 30851564523bc..be4bc6758443e 100644 --- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs @@ -2,15 +2,16 @@ use super::apple_base::{opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::Armv7s; Target { llvm_target: "armv7s-apple-ios".into(), pointer_width: 32, data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(), - arch: "arm".into(), + arch: arch.target_arch(), options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), - ..opts("ios", Arch::Armv7s) + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index 21635642c18a3..5819981612e84 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -1,22 +1,23 @@ -use super::apple_base::{opts, Arch}; +use super::apple_base::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::I386; - let base = opts("ios", arch); - let llvm_target = super::apple_base::ios_sim_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // IPHONEOS_DEPLOYMENT_TARGET. + // This is required for the target to pick the right + // MACH-O commands, so we do too. + llvm_target: ios_sim_llvm_target(arch).into(), pointer_width: 32, data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:128-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, - ..base + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 84dae68877dfd..8b968af5eccff 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -2,28 +2,27 @@ use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - // ld64 only understand i386 and not i686 - let mut base = opts("macos", Arch::I386); - base.cpu = "yonah".into(); + // ld64 only understands i386 and not i686 + let arch = Arch::I386; + let mut base = opts("macos", arch); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); base.link_env_remove.to_mut().extend(macos_link_env_remove()); base.stack_probes = StackProbeType::X86; base.frame_pointer = FramePointer::Always; - // Clang automatically chooses a more specific target based on - // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work - // correctly, we do too. - let arch = "i686"; - let llvm_target = macos_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + // + // While ld64 doesn't understand i686, LLVM does. + llvm_target: macos_llvm_target(Arch::I686).into(), pointer_width: 32, data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:128-n8:16:32-S128" .into(), - arch: "x86".into(), + arch: arch.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 6112ef7ec1f93..c053031612ce5 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -5,8 +5,7 @@ use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64; let mut base = opts("macos", arch); - base.cpu = "core2".into(); - base.max_atomic_width = Some(128); // core2 support cmpxchg16b + base.max_atomic_width = Some(128); // core2 supports cmpxchg16b base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); base.link_env_remove.to_mut().extend(macos_link_env_remove()); @@ -14,17 +13,15 @@ pub fn target() -> Target { base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; - // Clang automatically chooses a more specific target based on - // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work - // correctly, we do too. - let llvm_target = macos_llvm_target(arch.target_name()); - Target { - llvm_target: llvm_target.into(), + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), - arch: "x86_84".into(), + arch: arch.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index 032ba0763b4c5..fbd3ebd4d0431 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -3,19 +3,16 @@ use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; - let base = opts("ios", arch); - let llvm_target = ios_sim_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + llvm_target: ios_sim_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), - arch: "x86_64".into(), + arch: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, - ..base + ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 6647c1d29217e..0f3f851996377 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -4,7 +4,8 @@ use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let llvm_target = "x86_64-apple-ios13.0-macabi"; - let mut base = opts("ios", Arch::X86_64_macabi); + let arch = Arch::X86_64_macabi; + let mut base = opts("ios", arch); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-target", llvm_target]); Target { @@ -12,7 +13,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), - arch: "x86_64".into(), + arch: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index cb70717b3c42f..550ce0b9ce577 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -2,16 +2,16 @@ use super::apple_base::{opts, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { - let base = opts("tvos", Arch::X86_64_sim); + let arch = Arch::X86_64_sim; Target { llvm_target: "x86_64-apple-tvos".into(), pointer_width: 64, data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), + arch: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, - ..base + ..opts("tvos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs index 03ea66499db1d..75ce02cba1de0 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -1,18 +1,14 @@ -use super::apple_base::{opts, Arch}; +use super::apple_base::{opts, watchos_sim_llvm_target, Arch}; use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; - let base = opts("watchos", Arch::X86_64_sim); - - let llvm_target = super::apple_base::watchos_sim_llvm_target(arch); - Target { - llvm_target: llvm_target.into(), + llvm_target: watchos_sim_llvm_target(arch).into(), pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), - arch: "x86_64".into(), + arch: arch.target_arch(), options: TargetOptions { max_atomic_width: Some(64), stack_probes: StackProbeType::X86, @@ -28,7 +24,7 @@ pub fn target() -> Target { darwinpcs\0\ -Os\0" .into(), - ..base + ..opts("watchos", arch) }, } } From 92722bb23a696acb1d35266019cba939a8c446ed Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 5 Nov 2022 12:30:28 -0400 Subject: [PATCH 334/482] Remove linuxkernel targets These are not used by the actual Rust-for-Linux project, so they're mostly just confusing. --- .../src/spec/linux_kernel_base.rs | 18 ------------ compiler/rustc_target/src/spec/mod.rs | 5 +--- .../rustc_target/src/spec/tests/tests_impl.rs | 9 +++--- .../spec/x86_64_unknown_none_linuxkernel.rs | 28 ------------------- library/unwind/src/lib.rs | 1 - src/doc/rustc/src/platform-support.md | 1 - 6 files changed, 5 insertions(+), 57 deletions(-) delete mode 100644 compiler/rustc_target/src/spec/linux_kernel_base.rs delete mode 100644 compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs deleted file mode 100644 index f41533a9548fe..0000000000000 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::spec::TargetOptions; -use crate::spec::{FramePointer, PanicStrategy, RelocModel, RelroLevel, StackProbeType}; - -pub fn opts() -> TargetOptions { - TargetOptions { - env: "gnu".into(), - disable_redzone: true, - panic_strategy: PanicStrategy::Abort, - stack_probes: StackProbeType::X86, - frame_pointer: FramePointer::Always, - position_independent_executables: true, - needs_plt: true, - relro_level: RelroLevel::Full, - relocation_model: RelocModel::Static, - - ..Default::default() - } -} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 9baf7655595bf..25f17fa077370 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -70,7 +70,6 @@ mod illumos_base; mod l4re_base; mod linux_base; mod linux_gnu_base; -mod linux_kernel_base; mod linux_musl_base; mod linux_uclibc_base; mod msvc_base; @@ -1002,7 +1001,7 @@ macro_rules! supported_targets { $( #[test] // `#[test]` fn $module() { - tests_impl::test_target(super::$module::target(), $triple); + tests_impl::test_target(super::$module::target()); } )+ } @@ -1070,8 +1069,6 @@ supported_targets! { ("thumbv7neon-linux-androideabi", thumbv7neon_linux_androideabi), ("aarch64-linux-android", aarch64_linux_android), - ("x86_64-unknown-none-linuxkernel", x86_64_unknown_none_linuxkernel), - ("aarch64-unknown-freebsd", aarch64_unknown_freebsd), ("armv6-unknown-freebsd", armv6_unknown_freebsd), ("armv7-unknown-freebsd", armv7_unknown_freebsd), diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 172da0ed5df88..e0ecf8037c3e5 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -2,15 +2,15 @@ use super::super::*; use std::assert_matches::assert_matches; // Test target self-consistency and JSON encoding/decoding roundtrip. -pub(super) fn test_target(mut target: Target, triple: &str) { +pub(super) fn test_target(mut target: Target) { let recycled_target = Target::from_json(target.to_json()).map(|(j, _)| j); target.update_to_cli(); - target.check_consistency(triple); + target.check_consistency(); assert_eq!(recycled_target, Ok(target)); } impl Target { - fn check_consistency(&self, triple: &str) { + fn check_consistency(&self) { assert_eq!(self.is_like_osx, self.vendor == "apple"); assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos"); assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi"); @@ -129,8 +129,7 @@ impl Target { if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") { assert_eq!(self.relocation_model, RelocModel::Pic); } - // PIEs are supported but not enabled by default with linuxkernel target. - if self.position_independent_executables && !triple.ends_with("-linuxkernel") { + if self.position_independent_executables { assert_eq!(self.relocation_model, RelocModel::Pic); } // The UEFI targets do not support dynamic linking but still require PIC (#101377). diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs deleted file mode 100644 index ebd9636ff5102..0000000000000 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs +++ /dev/null @@ -1,28 +0,0 @@ -// This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for -// generic Linux kernel options. - -use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, Target}; - -pub fn target() -> Target { - let mut base = super::linux_kernel_base::opts(); - base.cpu = "x86-64".into(); - base.max_atomic_width = Some(64); - base.features = - "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into(); - base.code_model = Some(CodeModel::Kernel); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); - - Target { - // FIXME: Some dispute, the linux-on-clang folks think this should use - // "Linux". We disagree because running *on* Linux is nothing like - // running *as" linux, and historically the "os" component as has always - // been used to mean the "on" part. - llvm_target: "x86_64-unknown-none-elf".into(), - pointer_width: 64, - data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" - .into(), - arch: "x86_64".into(), - - options: base, - } -} diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 46fe50cb9453d..32c0ef3e11688 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -15,7 +15,6 @@ cfg_if::cfg_if! { target_os = "espidf", ))] { // These "unix" family members do not have unwinder. - // Note this also matches x86_64-unknown-none-linuxkernel. } else if #[cfg(any( unix, windows, diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 5b4e436da7d57..0315f1e3725ff 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -310,7 +310,6 @@ target | std | host | notes `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku `x86_64-unknown-hermit` | ✓ | | HermitCore `x86_64-unknown-l4re-uclibc` | ? | | -`x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | From deefb62bc0d1e47720e93381e1d684b2b034d62b Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 5 Nov 2022 14:26:54 -0400 Subject: [PATCH 335/482] Limit efiapi calling convention to supported arches Supported architectures in UEFI are described here: https://uefi.org/specs/UEFI/2.10/02_Overview.html#calling-conventions Changes to tests modeled on 8240e7aa101815e2009c7d03b33dd2566d843e73. https://github.com/rust-lang/rust/issues/65815 --- compiler/rustc_target/src/spec/mod.rs | 4 +- .../feature-gates/feature-gate-abi-efiapi.rs | 33 +++++ .../feature-gate-abi-efiapi.stderr | 66 ++++++++++ src/test/ui/feature-gates/feature-gate-abi.rs | 8 -- .../ui/feature-gates/feature-gate-abi.stderr | 119 +++++------------- 5 files changed, 130 insertions(+), 100 deletions(-) create mode 100644 src/test/ui/feature-gates/feature-gate-abi-efiapi.rs create mode 100644 src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 25f17fa077370..1bcb02ecb3053 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1937,8 +1937,10 @@ impl Target { | PlatformIntrinsic | Unadjusted | Cdecl { .. } - | EfiApi | RustCold => true, + EfiApi => { + ["arm", "aarch64", "riscv32", "riscv64", "x86", "x86_64"].contains(&&self.arch[..]) + } X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]), Aapcs { .. } => "arm" == self.arch, CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]), diff --git a/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs b/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs new file mode 100644 index 0000000000000..0c0d736acd048 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs @@ -0,0 +1,33 @@ +// needs-llvm-components: x86 +// compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib +#![no_core] +#![feature(no_core, lang_items)] +#[lang="sized"] +trait Sized { } + +// Functions +extern "efiapi" fn f1() {} //~ ERROR efiapi ABI is experimental + +// Methods in trait defintion +trait Tr { + extern "efiapi" fn f2(); //~ ERROR efiapi ABI is experimental + extern "efiapi" fn f3() {} //~ ERROR efiapi ABI is experimental +} + +struct S; + +// Methods in trait impl +impl Tr for S { + extern "efiapi" fn f2() {} //~ ERROR efiapi ABI is experimental +} + +// Methods in inherent impl +impl S { + extern "efiapi" fn f4() {} //~ ERROR efiapi ABI is experimental +} + +// Function pointer types +type A = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental + +// Foreign modules +extern "efiapi" {} //~ ERROR efiapi ABI is experimental diff --git a/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr b/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr new file mode 100644 index 0000000000000..5b01dcc6d8595 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr @@ -0,0 +1,66 @@ +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:9:8 + | +LL | extern "efiapi" fn f1() {} + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:13:12 + | +LL | extern "efiapi" fn f2(); + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:14:12 + | +LL | extern "efiapi" fn f3() {} + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:21:12 + | +LL | extern "efiapi" fn f2() {} + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:26:12 + | +LL | extern "efiapi" fn f4() {} + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:30:17 + | +LL | type A = extern "efiapi" fn(); + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error[E0658]: efiapi ABI is experimental and subject to change + --> $DIR/feature-gate-abi-efiapi.rs:33:8 + | +LL | extern "efiapi" {} + | ^^^^^^^^ + | + = note: see issue #65815 for more information + = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs index 15b674c62e44d..712655f9775d6 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.rs +++ b/src/test/ui/feature-gates/feature-gate-abi.rs @@ -1,6 +1,5 @@ // gate-test-intrinsics // gate-test-platform_intrinsics -// gate-test-abi_efiapi // compile-flags: --crate-type=rlib #![feature(no_core, lang_items)] @@ -18,7 +17,6 @@ extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental //~^ ERROR intrinsic must be in extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change -extern "efiapi" fn f10() {} //~ ERROR efiapi ABI is experimental and subject to change // Methods in trait definition trait Tr { @@ -27,10 +25,8 @@ trait Tr { extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental //~^ ERROR intrinsic must be in extern "rust-call" fn m4(_: ()); //~ ERROR rust-call ABI is subject to change - extern "efiapi" fn m10(); //~ ERROR efiapi ABI is experimental and subject to change extern "rust-call" fn dm4(_: ()) {} //~ ERROR rust-call ABI is subject to change - extern "efiapi" fn dm10() {} //~ ERROR efiapi ABI is experimental and subject to change } struct S; @@ -42,7 +38,6 @@ impl Tr for S { extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental //~^ ERROR intrinsic must be in extern "rust-call" fn m4(_: ()) {} //~ ERROR rust-call ABI is subject to change - extern "efiapi" fn m10() {} //~ ERROR efiapi ABI is experimental and subject to change } // Methods in inherent impl @@ -52,17 +47,14 @@ impl S { extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental //~^ ERROR intrinsic must be in extern "rust-call" fn im4(_: ()) {} //~ ERROR rust-call ABI is subject to change - extern "efiapi" fn im10() {} //~ ERROR efiapi ABI is experimental and subject to change } // Function pointer types type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental type A4 = extern "rust-call" fn(_: ()); //~ ERROR rust-call ABI is subject to change -type A10 = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental and subject to change // Foreign modules extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental extern "rust-call" {} //~ ERROR rust-call ABI is subject to change -extern "efiapi" {} //~ ERROR efiapi ABI is experimental and subject to change diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr index 33ec250f09067..e9791b9513f4d 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi.stderr @@ -1,5 +1,5 @@ error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:16:8 + --> $DIR/feature-gate-abi.rs:15:8 | LL | extern "rust-intrinsic" fn f1() {} | ^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:18:8 + --> $DIR/feature-gate-abi.rs:17:8 | LL | extern "platform-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:20:8 + --> $DIR/feature-gate-abi.rs:19:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -24,17 +24,8 @@ LL | extern "rust-call" fn f4(_: ()) {} = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:21:8 - | -LL | extern "efiapi" fn f10() {} - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:25:12 + --> $DIR/feature-gate-abi.rs:23:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -42,7 +33,7 @@ LL | extern "rust-intrinsic" fn m1(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:27:12 + --> $DIR/feature-gate-abi.rs:25:12 | LL | extern "platform-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +42,7 @@ LL | extern "platform-intrinsic" fn m2(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:29:12 + --> $DIR/feature-gate-abi.rs:27:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -59,17 +50,8 @@ LL | extern "rust-call" fn m4(_: ()); = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:30:12 - | -LL | extern "efiapi" fn m10(); - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:32:12 + --> $DIR/feature-gate-abi.rs:29:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -77,17 +59,8 @@ LL | extern "rust-call" fn dm4(_: ()) {} = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:33:12 - | -LL | extern "efiapi" fn dm10() {} - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:40:12 + --> $DIR/feature-gate-abi.rs:36:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -95,7 +68,7 @@ LL | extern "rust-intrinsic" fn m1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:42:12 + --> $DIR/feature-gate-abi.rs:38:12 | LL | extern "platform-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +77,7 @@ LL | extern "platform-intrinsic" fn m2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:44:12 + --> $DIR/feature-gate-abi.rs:40:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -112,17 +85,8 @@ LL | extern "rust-call" fn m4(_: ()) {} = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:45:12 - | -LL | extern "efiapi" fn m10() {} - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:50:12 + --> $DIR/feature-gate-abi.rs:45:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -130,7 +94,7 @@ LL | extern "rust-intrinsic" fn im1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:52:12 + --> $DIR/feature-gate-abi.rs:47:12 | LL | extern "platform-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +103,7 @@ LL | extern "platform-intrinsic" fn im2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:54:12 + --> $DIR/feature-gate-abi.rs:49:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -147,17 +111,8 @@ LL | extern "rust-call" fn im4(_: ()) {} = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:55:12 - | -LL | extern "efiapi" fn im10() {} - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:59:18 + --> $DIR/feature-gate-abi.rs:53:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -165,7 +120,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:60:18 + --> $DIR/feature-gate-abi.rs:54:18 | LL | type A2 = extern "platform-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +129,7 @@ LL | type A2 = extern "platform-intrinsic" fn(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:61:18 + --> $DIR/feature-gate-abi.rs:55:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -182,17 +137,8 @@ LL | type A4 = extern "rust-call" fn(_: ()); = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:62:19 - | -LL | type A10 = extern "efiapi" fn(); - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:65:8 + --> $DIR/feature-gate-abi.rs:58:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -200,7 +146,7 @@ LL | extern "rust-intrinsic" {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:66:8 + --> $DIR/feature-gate-abi.rs:59:8 | LL | extern "platform-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +155,7 @@ LL | extern "platform-intrinsic" {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:67:8 + --> $DIR/feature-gate-abi.rs:60:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -217,63 +163,54 @@ LL | extern "rust-call" {} = note: see issue #29625 for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:68:8 - | -LL | extern "efiapi" {} - | ^^^^^^^^ - | - = note: see issue #65815 for more information - = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:25:32 + --> $DIR/feature-gate-abi.rs:23:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:27:36 + --> $DIR/feature-gate-abi.rs:25:36 | LL | extern "platform-intrinsic" fn m2(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:16:33 + --> $DIR/feature-gate-abi.rs:15:33 | LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:18:37 + --> $DIR/feature-gate-abi.rs:17:37 | LL | extern "platform-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:40:37 + --> $DIR/feature-gate-abi.rs:36:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:42:41 + --> $DIR/feature-gate-abi.rs:38:41 | LL | extern "platform-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:50:38 + --> $DIR/feature-gate-abi.rs:45:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:52:42 + --> $DIR/feature-gate-abi.rs:47:42 | LL | extern "platform-intrinsic" fn im2() {} | ^^ -error: aborting due to 34 previous errors +error: aborting due to 27 previous errors For more information about this error, try `rustc --explain E0658`. From b99fab49e337be7fb9e6d0dd14b09cae389a8281 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 8 Nov 2022 14:45:24 +0000 Subject: [PATCH 336/482] Simplify some `Autoderef::new` calls --- compiler/rustc_hir_typeck/src/autoderef.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index 59c366ad7d776..f30d53a4c8703 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -12,7 +12,7 @@ use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> { - Autoderef::new(self, self.param_env, self.body_id, span, base_ty, span) + self.autoderef_overloaded_span(span, base_ty, span) } /// Like `autoderef`, but provides a custom `Span` to use for calls to diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c248deb892b1d..eb10f3e2c107f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -19,7 +19,6 @@ use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::{Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, DUMMY_SP}; -use rustc_trait_selection::autoderef::Autoderef; use rustc_trait_selection::traits::{ObligationCause, Pattern}; use ty::VariantDef; @@ -2132,7 +2131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let ty::Array(..) | ty::Slice(..) = ty.kind() { err.help("the semantics of slice patterns changed recently; see issue #62254"); - } else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span) + } else if self.autoderef(span, expected_ty) .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) && let (Some(span), true) = (ti.span, ti.origin_expr) && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) From 4b842b85e1851ff1d36092490a04fe2f7af66335 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 8 Nov 2022 15:49:29 +0000 Subject: [PATCH 337/482] Remove overloaded_span argument from `new`, where it is usually redundant with the main span --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 3 +-- compiler/rustc_hir_typeck/src/autoderef.rs | 13 +------------ compiler/rustc_hir_typeck/src/method/confirm.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 7 +++---- compiler/rustc_trait_selection/src/autoderef.rs | 7 +++++-- .../src/traits/error_reporting/suggestions.rs | 1 - 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6a12db9d36ade..8a70f41c8a840 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1708,8 +1708,7 @@ fn receiver_is_valid<'tcx>( return true; } - let mut autoderef = - Autoderef::new(infcx, wfcx.param_env, wfcx.body_id, span, receiver_ty, span); + let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_id, span, receiver_ty); // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`. if arbitrary_self_types_enabled { diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index f30d53a4c8703..748237a7593a5 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -12,18 +12,7 @@ use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> { - self.autoderef_overloaded_span(span, base_ty, span) - } - - /// Like `autoderef`, but provides a custom `Span` to use for calls to - /// an overloaded `Deref` operator - pub fn autoderef_overloaded_span( - &'a self, - span: Span, - base_ty: Ty<'tcx>, - overloaded_span: Span, - ) -> Autoderef<'a, 'tcx> { - Autoderef::new(self, self.param_env, self.body_id, span, base_ty, overloaded_span) + Autoderef::new(self, self.param_env, self.body_id, span, base_ty) } pub fn try_overloaded_deref( diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index be4ea99862222..a0de38ef856e4 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -152,7 +152,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various typeck results. let mut autoderef = - self.autoderef_overloaded_span(self.span, unadjusted_self_ty, self.call_expr.span); + self.autoderef(self.span, unadjusted_self_ty).with_overloaded_span(self.call_expr.span); let Some((ty, n)) = autoderef.nth(pick.autoderefs) else { return self.tcx.ty_error_with_message( rustc_span::DUMMY_SP, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e88701685bc6d..3fcd073f59793 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -475,10 +475,9 @@ fn method_autoderef_steps<'tcx>( let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal); let ParamEnvAnd { param_env, value: self_ty } = goal; - let mut autoderef = - Autoderef::new(infcx, param_env, hir::CRATE_HIR_ID, DUMMY_SP, self_ty, DUMMY_SP) - .include_raw_pointers() - .silence_errors(); + let mut autoderef = Autoderef::new(infcx, param_env, hir::CRATE_HIR_ID, DUMMY_SP, self_ty) + .include_raw_pointers() + .silence_errors(); let mut reached_raw_pointer = false; let mut steps: Vec<_> = autoderef .by_ref() diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 61cfeec4bbb6e..1a478f02df212 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -99,12 +99,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { body_id: hir::HirId, span: Span, base_ty: Ty<'tcx>, - overloaded_span: Span, ) -> Autoderef<'a, 'tcx> { Autoderef { infcx, span, - overloaded_span, + overloaded_span: span, body_id, param_env, state: AutoderefSnapshot { @@ -119,6 +118,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { } } + pub fn with_overloaded_span(self, overloaded_span: Span) -> Self { + Self { overloaded_span, ..self } + } + fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option> { debug!("overloaded_deref_ty({:?})", ty); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 0f4aa87b43f5e..aece4ab792285 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -714,7 +714,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.cause.body_id, span, base_ty, - span, ); if let Some(steps) = autoderef.find_map(|(ty, steps)| { // Re-add the `&` From a794e84002434dd70fb79f1686e74f5d80be45fb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 8 Nov 2022 16:03:48 +0000 Subject: [PATCH 338/482] Remove an unused span --- compiler/rustc_hir_typeck/src/autoderef.rs | 6 +----- compiler/rustc_hir_typeck/src/method/confirm.rs | 3 +-- compiler/rustc_trait_selection/src/autoderef.rs | 10 ---------- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index 748237a7593a5..41b52a4c4a9fc 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -44,11 +44,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |InferOk { value: method, obligations: o }| { obligations.extend(o); if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() { - Some(OverloadedDeref { - region, - mutbl, - span: autoderef.overloaded_span(), - }) + Some(OverloadedDeref { region, mutbl, span: autoderef.span() }) } else { None } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index a0de38ef856e4..d996d6ec610ba 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -151,8 +151,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ) -> Ty<'tcx> { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various typeck results. - let mut autoderef = - self.autoderef(self.span, unadjusted_self_ty).with_overloaded_span(self.call_expr.span); + let mut autoderef = self.autoderef(self.call_expr.span, unadjusted_self_ty); let Some((ty, n)) = autoderef.nth(pick.autoderefs) else { return self.tcx.ty_error_with_message( rustc_span::DUMMY_SP, diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 1a478f02df212..46ee2f35976a7 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -27,7 +27,6 @@ pub struct Autoderef<'a, 'tcx> { // Meta infos: infcx: &'a InferCtxt<'tcx>, span: Span, - overloaded_span: Span, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, @@ -103,7 +102,6 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { Autoderef { infcx, span, - overloaded_span: span, body_id, param_env, state: AutoderefSnapshot { @@ -118,10 +116,6 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { } } - pub fn with_overloaded_span(self, overloaded_span: Span) -> Self { - Self { overloaded_span, ..self } - } - fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option> { debug!("overloaded_deref_ty({:?})", ty); @@ -196,10 +190,6 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.span } - pub fn overloaded_span(&self) -> Span { - self.overloaded_span - } - pub fn reached_recursion_limit(&self) -> bool { self.state.reached_recursion_limit } From e575676c8f763be98a8d31a2ef020a632094eeb3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 8 Nov 2022 13:37:49 -0800 Subject: [PATCH 339/482] Update books --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index aa5ee485bd6bd..3f64052c048c6 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit aa5ee485bd6bd80d205da7c82fcdd776f92fdd51 +Subproject commit 3f64052c048c6def93b94a2b514ee88bba918744 diff --git a/src/doc/nomicon b/src/doc/nomicon index 9c73283775466..05532356e7a4d 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 9c73283775466d22208a0b28afcab44db4c0cc10 +Subproject commit 05532356e7a4dbea2330aabb77611f5179493bb8 diff --git a/src/doc/reference b/src/doc/reference index 4ea7c5def38ac..9f0cc13ffcd27 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 4ea7c5def38ac81df33a9e48e5637a82a5ac404d +Subproject commit 9f0cc13ffcd27c1fbe1ab766a9491e15ddcf4d19 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 03491f33375c5..2b15c0abf2bad 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 03491f33375c5a2a1661c7fa4be671fe95ce1249 +Subproject commit 2b15c0abf2bada6e00553814336bc3e2d8399097 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 51a37ad19a157..d0dc6c97a6486 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 51a37ad19a15709d0601afbac6581f5aea6a45da +Subproject commit d0dc6c97a6486f68bac782fff135086eae6d77ec From 21a7ac705f791c0f12cd7194b1d900ca0ec03131 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 9 Nov 2022 02:52:59 -0600 Subject: [PATCH 340/482] Fix `rustdoc --version` when used with download-rustc Previously, rustdoc would unconditionally report the version that *rustc* was compiled with. That showed things like `nightly-2022-10-30`, which wasn't right, since this was a `dev` build compiled from source. Fix it by changing `rustc_driver::version` to a macro expanded at invocation time. --- .../src/debuginfo/mod.rs | 2 +- compiler/rustc_driver/src/lib.rs | 42 ++++++++++++++----- compiler/rustc_interface/src/lib.rs | 1 + compiler/rustc_interface/src/util.rs | 22 +++------- src/librustdoc/config.rs | 2 +- src/librustdoc/html/layout.rs | 2 +- 6 files changed, 42 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index c55db2017ee68..2ba012a77b0a9 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -59,7 +59,7 @@ impl DebugContext { let producer = format!( "cg_clif (rustc {}, cranelift {})", - rustc_interface::util::version_str().unwrap_or("unknown version"), + rustc_interface::util::rustc_version_str().unwrap_or("unknown version"), cranelift_codegen::VERSION, ); let comp_dir = tcx diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 423f0cdddfd5c..e043368fdfe02 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -6,6 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(once_cell)] +#![feature(decl_macro)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] @@ -753,20 +754,41 @@ fn print_crate_info( } /// Prints version information -pub fn version(binary: &str, matches: &getopts::Matches) { +/// +/// NOTE: this is a macro to support drivers built at a different time than the main `rustc_driver` crate. +pub macro version($binary: literal, $matches: expr) { + fn unw(x: Option<&str>) -> &str { + x.unwrap_or("unknown") + } + $crate::version_at_macro_invocation( + $binary, + $matches, + unw(option_env!("CFG_VERSION")), + unw(option_env!("CFG_VER_HASH")), + unw(option_env!("CFG_VER_DATE")), + unw(option_env!("CFG_RELEASE")), + ) +} + +#[doc(hidden)] // use the macro instead +pub fn version_at_macro_invocation( + binary: &str, + matches: &getopts::Matches, + version: &str, + commit_hash: &str, + commit_date: &str, + release: &str, +) { let verbose = matches.opt_present("verbose"); - println!("{} {}", binary, util::version_str().unwrap_or("unknown version")); + println!("{} {}", binary, version); if verbose { - fn unw(x: Option<&str>) -> &str { - x.unwrap_or("unknown") - } println!("binary: {}", binary); - println!("commit-hash: {}", unw(util::commit_hash_str())); - println!("commit-date: {}", unw(util::commit_date_str())); + println!("commit-hash: {}", commit_hash); + println!("commit-date: {}", commit_date); println!("host: {}", config::host_triple()); - println!("release: {}", unw(util::release_str())); + println!("release: {}", release); let debug_flags = matches.opt_strs("Z"); let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); @@ -1082,7 +1104,7 @@ pub fn handle_options(args: &[String]) -> Option { } if matches.opt_present("version") { - version("rustc", &matches); + version!("rustc", &matches); return None; } @@ -1227,7 +1249,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { format!("we would appreciate a bug report: {}", bug_report_url).into(), format!( "rustc {} running on {}", - util::version_str().unwrap_or("unknown_version"), + util::version_str!().unwrap_or("unknown_version"), config::host_triple() ) .into(), diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index a41a749ee68e5..542b638bbd7a4 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,4 +1,5 @@ #![feature(box_patterns)] +#![feature(decl_macro)] #![feature(internal_output_capture)] #![feature(thread_spawn_unchecked)] #![feature(once_cell)] diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 62ee72f988308..2fe3fb2fa5668 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -327,7 +327,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> M let mut file: Option = None; let expected_names = &[ - format!("rustc_codegen_{}-{}", backend_name, release_str().expect("CFG_RELEASE")), + format!("rustc_codegen_{}-{}", backend_name, env!("CFG_RELEASE")), format!("rustc_codegen_{}", backend_name), ]; for entry in d.filter_map(|e| e.ok()) { @@ -554,22 +554,12 @@ pub fn build_output_filenames( } } -/// Returns a version string such as "1.46.0 (04488afe3 2020-08-24)" -pub fn version_str() -> Option<&'static str> { +/// Returns a version string such as "1.46.0 (04488afe3 2020-08-24)" when invoked by an in-tree tool. +pub macro version_str() { option_env!("CFG_VERSION") } -/// Returns a version string such as "0.12.0-dev". -pub fn release_str() -> Option<&'static str> { - option_env!("CFG_RELEASE") -} - -/// Returns the full SHA1 hash of HEAD of the Git repo from which rustc was built. -pub fn commit_hash_str() -> Option<&'static str> { - option_env!("CFG_VER_HASH") -} - -/// Returns the "commit date" of HEAD of the Git repo from which rustc was built as a static string. -pub fn commit_date_str() -> Option<&'static str> { - option_env!("CFG_VER_DATE") +/// Returns the version string for `rustc` itself (which may be different from a tool version). +pub fn rustc_version_str() -> Option<&'static str> { + version_str!() } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 9c08eac4edcb0..789dd398be50d 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -326,7 +326,7 @@ impl Options { crate::usage("rustdoc"); return Err(0); } else if matches.opt_present("version") { - rustc_driver::version("rustdoc", matches); + rustc_driver::version!("rustdoc", matches); return Err(0); } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 48c6abfca90ce..a60e7cb10fa51 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -71,7 +71,7 @@ pub(crate) fn render( let mut themes: Vec = style_files.iter().map(|s| s.basename().unwrap()).collect(); themes.sort(); - let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version"); + let rustdoc_version = rustc_interface::util::version_str!().unwrap_or("unknown version"); let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar. let sidebar = Buffer::html().to_display(sidebar); PageLayout { From 485dcd4e4d592d0fa5eecc211d6ce1299556ac0d Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 18 Sep 2022 18:45:36 +0100 Subject: [PATCH 341/482] Prevent auto-application of associated functions with placeholders --- .../rustc_hir_typeck/src/method/suggest.rs | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 50e2b0f89267d..17078a99ca59e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -393,28 +393,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { - let ty_str = - if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { - // When the "method" is resolved through dereferencing, we really want the - // original type that has the associated function for accurate suggestions. - // (#61411) - let ty = tcx.at(span).type_of(*impl_did); - match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { - (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => { - // Use `actual` as it will have more `substs` filled in. - self.ty_to_value_string(actual.peel_refs()) - } - _ => self.ty_to_value_string(ty.peel_refs()), + let (ty_str, placeholders) = if let Some(CandidateSource::Impl(impl_did)) = + static_candidates.get(0) + { + // When the "method" is resolved through dereferencing, we really want the + // original type that has the associated function for accurate suggestions. + // (#61411) + let ty = tcx.at(span).type_of(*impl_did); + match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { + (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { + // If there are any inferred arguments, (`{integer}`), we shouldn't mark + // this as machine-applicable. + let placeholders = substs + .iter() + .filter_map(|arg| { + if let GenericArgKind::Type(ty) = arg.unpack() { + Some(ty) + } else { + None + } + }) + .any(|ty| matches!(ty.kind(), ty::Infer(_))); + // Use `actual` as it will have more `substs` filled in. + (self.ty_to_value_string(actual.peel_refs()), placeholders) } - } else { - self.ty_to_value_string(actual.peel_refs()) - }; + _ => (self.ty_to_value_string(ty.peel_refs()), true), + } + } else { + (self.ty_to_value_string(actual.peel_refs()), true) + }; + let applicability = match placeholders { + true => Applicability::HasPlaceholders, + false => Applicability::MachineApplicable, + }; if let SelfSource::MethodCall(expr) = source { err.span_suggestion( expr.span.to(span), "use associated function syntax instead", format!("{}::{}", ty_str, item_name), - Applicability::MachineApplicable, + applicability, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); From 79a9f4021fd7b21ba259d00304ecba587588b14a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 19 Sep 2022 00:53:41 +0100 Subject: [PATCH 342/482] Allow inferring generic arguments for associated methods --- .../rustc_hir_typeck/src/method/suggest.rs | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 17078a99ca59e..88c549f519302 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -14,7 +14,11 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, Node, QPath}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::{ + type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, + RegionVariableOrigin, +}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; @@ -393,7 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { - let (ty_str, placeholders) = if let Some(CandidateSource::Impl(impl_did)) = + let ty_str = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { // When the "method" is resolved through dereferencing, we really want the @@ -402,36 +406,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = tcx.at(span).type_of(*impl_did); match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { - // If there are any inferred arguments, (`{integer}`), we shouldn't mark - // this as machine-applicable. - let placeholders = substs - .iter() - .filter_map(|arg| { - if let GenericArgKind::Type(ty) = arg.unpack() { - Some(ty) - } else { - None - } + // If there are any inferred arguments, (`{integer}`), we should replace + // them with underscores to allow the compiler to infer them + let substs = substs + .into_iter() + .filter(|arg| !arg.is_suggestable(tcx, true)) + .map(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => self + .next_region_var(RegionVariableOrigin::MiscVariable( + rustc_span::DUMMY_SP, + )) + .into(), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), }) - .any(|ty| matches!(ty.kind(), ty::Infer(_))); - // Use `actual` as it will have more `substs` filled in. - (self.ty_to_value_string(actual.peel_refs()), placeholders) + .collect::>(); + format!( + "{}", + ty::Instance::new(def_actual.did(), tcx.intern_substs(&substs)) + ) } - _ => (self.ty_to_value_string(ty.peel_refs()), true), + _ => self.ty_to_value_string(ty.peel_refs()), } } else { - (self.ty_to_value_string(actual.peel_refs()), true) - }; - let applicability = match placeholders { - true => Applicability::HasPlaceholders, - false => Applicability::MachineApplicable, + self.ty_to_value_string(actual.peel_refs()) }; if let SelfSource::MethodCall(expr) = source { err.span_suggestion( expr.span.to(span), "use associated function syntax instead", format!("{}::{}", ty_str, item_name), - applicability, + Applicability::MachineApplicable, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); From eb592b4cd81a89fe087b8f46c8d54154e60ddc2a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 19 Sep 2022 01:54:11 +0100 Subject: [PATCH 343/482] Update UI test --- .../ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 3fb418b1c0aac..199454ee228e8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -8,7 +8,7 @@ LL | x.default_hello(); | --^^^^^^^^^^^^^ | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::default_hello` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` From eac5427bad398f7ff8d71515b5575784d68b902f Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 23 Sep 2022 12:40:20 +0100 Subject: [PATCH 344/482] Use `FmtPrinter` instead of creating `Instance` --- .../rustc_hir_typeck/src/method/suggest.rs | 63 ++++++----- compiler/rustc_middle/src/ty/print/pretty.rs | 6 + .../suggest-assoc-fn-call-with-turbofish.rs | 17 ++- ...uggest-assoc-fn-call-with-turbofish.stderr | 103 +++++++++++++++++- 4 files changed, 156 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 88c549f519302..a3f754fd1a95b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -22,7 +22,9 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{ + self, DefIdTree, GenericArg, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable, +}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -284,7 +286,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { return None; } - span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -408,35 +409,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { // If there are any inferred arguments, (`{integer}`), we should replace // them with underscores to allow the compiler to infer them - let substs = substs + let infer_substs: Vec> = substs .into_iter() - .filter(|arg| !arg.is_suggestable(tcx, true)) - .map(|arg| match arg.unpack() { - GenericArgKind::Lifetime(_) => self - .next_region_var(RegionVariableOrigin::MiscVariable( - rustc_span::DUMMY_SP, - )) - .into(), - GenericArgKind::Type(_) => self - .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }) - .into(), - GenericArgKind::Const(arg) => self - .next_const_var( - arg.ty(), - ConstVariableOrigin { + .map(|arg| { + if !arg.is_suggestable(tcx, true) { + match arg.unpack() { + GenericArgKind::Lifetime(_) => self + .next_region_var(RegionVariableOrigin::MiscVariable( + rustc_span::DUMMY_SP, + )) + .into(), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { span: rustc_span::DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, - ) - .into(), + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), + } + } else { + arg + } }) .collect::>(); - format!( - "{}", - ty::Instance::new(def_actual.did(), tcx.intern_substs(&substs)) + + tcx.value_path_str_with_substs( + def_actual.did(), + tcx.intern_substs(&infer_substs), ) } _ => self.ty_to_value_string(ty.peel_refs()), @@ -1862,7 +1869,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Print out the type for use in value namespace. fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String { match ty.kind() { - ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)), + ty::Adt(def, substs) => self.tcx.def_path_str_with_substs(def.did(), substs), _ => self.ty_to_string(ty), } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c8815537835b1..2432b5175197b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1659,6 +1659,12 @@ impl<'t> TyCtxt<'t> { debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer() } + + pub fn value_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + let ns = guess_def_namespace(self, def_id); + debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); + FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer() + } } impl fmt::Write for FmtPrinter<'_, '_> { diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 2a829db538390..213d1c72f9ae8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -2,10 +2,25 @@ struct GenericAssocMethod(T); impl GenericAssocMethod { fn default_hello() {} + fn self_ty_hello(_: T) {} + fn self_ty_ref_hello(_: &T) {} } fn main() { - let x = GenericAssocMethod(33i32); + // Test for inferred types + let x = GenericAssocMethod(33); x.default_hello(); //~^ ERROR no method named `default_hello` found + x.self_ty_ref_hello(); + //~^ ERROR no method named `self_ty_ref_hello` found + x.self_ty_hello(); + //~^ ERROR no method named `self_ty_hello` found + // Test for known types + let y = GenericAssocMethod(33i32); + y.default_hello(); + //~^ ERROR no method named `default_hello` found + y.self_ty_ref_hello(); + //~^ ERROR no method named `self_ty_ref_hello` found + y.self_ty_hello(); + //~^ ERROR no method named `self_ty_hello` found } diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 199454ee228e8..c6d9122228acc 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,5 +1,5 @@ -error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7 +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:12:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct @@ -8,7 +8,7 @@ LL | x.default_hello(); | --^^^^^^^^^^^^^ | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -17,6 +17,101 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_ref_hello` not found for this struct +... +LL | x.self_ty_ref_hello(); + | --^^^^^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + | +LL | fn self_ty_ref_hello(_: &T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_hello` not found for this struct +... +LL | x.self_ty_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + | +LL | fn self_ty_hello(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `default_hello` not found for this struct +... +LL | y.default_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 + | +LL | fn default_hello() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_ref_hello` not found for this struct +... +LL | y.self_ty_ref_hello(); + | --^^^^^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + | +LL | fn self_ty_ref_hello(_: &T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_hello` not found for this struct +... +LL | y.self_ty_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + | +LL | fn self_ty_hello(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0599`. From 98872d37a15b0925bb400719bd7fe0b75dc50280 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 23 Sep 2022 17:09:32 +0100 Subject: [PATCH 345/482] Attempt to fix arguments of associated functions --- .../rustc_hir_typeck/src/method/suggest.rs | 62 +++++++++++++-- src/test/ui/issues/issue-3707.stderr | 4 +- ...n-call-with-turbofish-through-deref.stderr | 4 +- ...suggest-assoc-fn-call-with-turbofish.fixed | 29 +++++++ .../suggest-assoc-fn-call-with-turbofish.rs | 11 ++- ...uggest-assoc-fn-call-with-turbofish.stderr | 77 +++++++------------ 6 files changed, 126 insertions(+), 61 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a3f754fd1a95b..e8a5cb00ffacd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ExprKind, Node, QPath}; +use rustc_hir::{Expr, ExprKind, Node, QPath}; use rustc_infer::infer::{ type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, RegionVariableOrigin, @@ -398,6 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { + let mut has_unsuggestable_args = false; let ty_str = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { @@ -413,6 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .map(|arg| { if !arg.is_suggestable(tcx, true) { + has_unsuggestable_args = true; match arg.unpack() { GenericArgKind::Lifetime(_) => self .next_region_var(RegionVariableOrigin::MiscVariable( @@ -451,12 +453,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { self.ty_to_value_string(actual.peel_refs()) }; - if let SelfSource::MethodCall(expr) = source { + if let SelfSource::MethodCall(_) = source { + let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) && + let Some(assoc) = self.associated_value(*impl_did, item_name) { + let sig = self.tcx.fn_sig(assoc.def_id); + if let Some(first) = sig.inputs().skip_binder().get(0) { + if first.peel_refs() == rcvr_ty.peel_refs() { + None + } else { + Some(if first.is_region_ptr() { + if first.is_mutable_ptr() { "&mut " } else { "&" } + } else { + "" + }) + } + } else { + None + } + } else { + None + }; + let mut applicability = Applicability::MachineApplicable; + let args = if let Some((receiver, args)) = args { + // The first arg is the same kind as the receiver + let it = if first_arg.is_some() { + Box::new(std::iter::once(receiver).chain(args.iter())) + as Box>> + } else { + // There is no `Self` kind to infer the arguments from + if has_unsuggestable_args { + applicability = Applicability::HasPlaceholders; + } + Box::new(args.iter()) as _ + }; + format!( + "({}{})", + first_arg.unwrap_or(""), + it.map(|arg| tcx + .sess + .source_map() + .span_to_snippet(arg.span) + .unwrap_or_else(|_| { + applicability = Applicability::HasPlaceholders; + "_".to_owned() + })) + .collect::>() + .join(", "), + ) + } else { + applicability = Applicability::HasPlaceholders; + "(...)".to_owned() + }; err.span_suggestion( - expr.span.to(span), + sugg_span, "use associated function syntax instead", - format!("{}::{}", ty_str, item_name), - Applicability::MachineApplicable, + format!("{}::{}{}", ty_str, item_name, args), + applicability, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); diff --git a/src/test/ui/issues/issue-3707.stderr b/src/test/ui/issues/issue-3707.stderr index 6ca2deee377a3..07c8101cbc68b 100644 --- a/src/test/ui/issues/issue-3707.stderr +++ b/src/test/ui/issues/issue-3707.stderr @@ -2,10 +2,10 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s --> $DIR/issue-3707.rs:10:14 | LL | self.boom(); - | -----^^^^ + | -----^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `Obj::boom` + | help: use associated function syntax instead: `Obj::boom()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Obj` diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr index 996d57731187d..7c9f0b6c212e1 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr @@ -2,10 +2,10 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11 | LL | state.hello(); - | ------^^^^^ + | ------^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `HasAssocMethod::hello` + | help: use associated function syntax instead: `HasAssocMethod::hello()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `HasAssocMethod` diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed new file mode 100644 index 0000000000000..0398c510feac3 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed @@ -0,0 +1,29 @@ +// run-rustfix + +struct GenericAssocMethod(T); + +impl GenericAssocMethod { + fn default_hello() {} + fn self_ty_hello(_: Self) {} + fn self_ty_ref_hello(_: &Self) {} +} + +fn main() { + // Test for inferred types + let x = GenericAssocMethod(33); + // This particular case is unfixable without more information by the user, + // but `cargo fix --broken-code` reports a bug if + // x.default_hello(); + GenericAssocMethod::<_>::self_ty_ref_hello(&x); + //~^ ERROR no method named `self_ty_ref_hello` found + GenericAssocMethod::<_>::self_ty_hello(x); + //~^ ERROR no method named `self_ty_hello` found + // Test for known types + let y = GenericAssocMethod(33i32); + GenericAssocMethod::::default_hello(); + //~^ ERROR no method named `default_hello` found + GenericAssocMethod::::self_ty_ref_hello(&y); + //~^ ERROR no method named `self_ty_ref_hello` found + GenericAssocMethod::::self_ty_hello(y); + //~^ ERROR no method named `self_ty_hello` found +} diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 213d1c72f9ae8..8bafc83bdd0b3 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -1,16 +1,19 @@ +// run-rustfix + struct GenericAssocMethod(T); impl GenericAssocMethod { fn default_hello() {} - fn self_ty_hello(_: T) {} - fn self_ty_ref_hello(_: &T) {} + fn self_ty_hello(_: Self) {} + fn self_ty_ref_hello(_: &Self) {} } fn main() { // Test for inferred types let x = GenericAssocMethod(33); - x.default_hello(); - //~^ ERROR no method named `default_hello` found + // This particular case is unfixable without more information by the user, + // but `cargo fix --broken-code` reports a bug if + // x.default_hello(); x.self_ty_ref_hello(); //~^ ERROR no method named `self_ty_ref_hello` found x.self_ty_hello(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index c6d9122228acc..e2f2d46b9e8b8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,117 +1,98 @@ -error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:12:7 - | -LL | struct GenericAssocMethod(T); - | ---------------------------- method `default_hello` not found for this struct -... -LL | x.default_hello(); - | --^^^^^^^^^^^^^ - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello` - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 - | -LL | fn default_hello() {} - | ^^^^^^^^^^^^^^^^^^ - error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:17:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | x.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello(&x)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5 | -LL | fn self_ty_ref_hello(_: &T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_ref_hello(_: &Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:19:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | x.self_ty_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello(x)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5 | -LL | fn self_ty_hello(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_hello(_: Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:23:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | y.default_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::default_hello()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:25:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | y.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello(&y)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5 | -LL | fn self_ty_ref_hello(_: &T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_ref_hello(_: &Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:27:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | y.self_ty_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello(y)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5 | -LL | fn self_ty_hello(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_hello(_: Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0599`. From f689f1196ca70454f1cdf700d5630b07a92a3820 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 26 Sep 2022 00:33:08 +0100 Subject: [PATCH 346/482] Split non-fixable case to different test --- ...ssoc-fn-call-with-turbofish-placeholder.rs | 11 ++++++++++ ...-fn-call-with-turbofish-placeholder.stderr | 22 +++++++++++++++++++ ...suggest-assoc-fn-call-with-turbofish.fixed | 3 --- .../suggest-assoc-fn-call-with-turbofish.rs | 3 --- ...uggest-assoc-fn-call-with-turbofish.stderr | 10 ++++----- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs new file mode 100644 index 0000000000000..a39b8711dd874 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs @@ -0,0 +1,11 @@ +struct GenericAssocMethod(T); + +impl GenericAssocMethod { + fn default_hello() {} +} + +fn main() { + let x = GenericAssocMethod(33); + x.default_hello(); + //~^ ERROR no method named `default_hello` found +} diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr new file mode 100644 index 0000000000000..c247e73b39cb6 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr @@ -0,0 +1,22 @@ +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:9:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `default_hello` not found for this struct +... +LL | x.default_hello(); + | --^^^^^^^^^^^^^-- + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:4:5 + | +LL | fn default_hello() {} + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed index 0398c510feac3..02dd0715c8011 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed @@ -11,9 +11,6 @@ impl GenericAssocMethod { fn main() { // Test for inferred types let x = GenericAssocMethod(33); - // This particular case is unfixable without more information by the user, - // but `cargo fix --broken-code` reports a bug if - // x.default_hello(); GenericAssocMethod::<_>::self_ty_ref_hello(&x); //~^ ERROR no method named `self_ty_ref_hello` found GenericAssocMethod::<_>::self_ty_hello(x); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 8bafc83bdd0b3..1d0ca8e780abf 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -11,9 +11,6 @@ impl GenericAssocMethod { fn main() { // Test for inferred types let x = GenericAssocMethod(33); - // This particular case is unfixable without more information by the user, - // but `cargo fix --broken-code` reports a bug if - // x.default_hello(); x.self_ty_ref_hello(); //~^ ERROR no method named `self_ty_ref_hello` found x.self_ty_hello(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index e2f2d46b9e8b8..92b03fc77142c 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:17:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct @@ -18,7 +18,7 @@ LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:19:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct @@ -37,7 +37,7 @@ LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:23:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct @@ -56,7 +56,7 @@ LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:25:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct @@ -75,7 +75,7 @@ LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:27:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct From bb1fc3cf0628db8474dce5e43b68df88f072b8dc Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 26 Sep 2022 00:43:52 +0100 Subject: [PATCH 347/482] Replace boxed iterator with vec collect --- .../rustc_hir_typeck/src/method/suggest.rs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e8a5cb00ffacd..565ee10206af8 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{Expr, ExprKind, Node, QPath}; +use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{ type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, RegionVariableOrigin, @@ -476,29 +476,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut applicability = Applicability::MachineApplicable; let args = if let Some((receiver, args)) = args { // The first arg is the same kind as the receiver - let it = if first_arg.is_some() { - Box::new(std::iter::once(receiver).chain(args.iter())) - as Box>> + let explicit_args = if first_arg.is_some() { + std::iter::once(receiver).chain(args.iter()).collect::>() } else { // There is no `Self` kind to infer the arguments from if has_unsuggestable_args { applicability = Applicability::HasPlaceholders; } - Box::new(args.iter()) as _ + args.iter().collect() }; format!( "({}{})", first_arg.unwrap_or(""), - it.map(|arg| tcx - .sess - .source_map() - .span_to_snippet(arg.span) - .unwrap_or_else(|_| { - applicability = Applicability::HasPlaceholders; - "_".to_owned() - })) - .collect::>() - .join(", "), + explicit_args + .iter() + .map(|arg| tcx + .sess + .source_map() + .span_to_snippet(arg.span) + .unwrap_or_else(|_| { + applicability = Applicability::HasPlaceholders; + "_".to_owned() + })) + .collect::>() + .join(", "), ) } else { applicability = Applicability::HasPlaceholders; From dcd92d7b8cd6dffc6037ac28d9ee0ef301df1374 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 10 Oct 2022 15:08:40 +0100 Subject: [PATCH 348/482] Update UI test --- src/test/ui/suggestions/inner_type2.rs | 2 +- src/test/ui/suggestions/inner_type2.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/suggestions/inner_type2.rs b/src/test/ui/suggestions/inner_type2.rs index c56ea7c030d8e..fac68c053eb4f 100644 --- a/src/test/ui/suggestions/inner_type2.rs +++ b/src/test/ui/suggestions/inner_type2.rs @@ -22,5 +22,5 @@ fn main() { let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 }); item.method(); //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599] - //~| HELP if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value + //~| HELP if this `MaybeUninit>` has been initialized, use one of the `assume_init` methods to access the inner value } diff --git a/src/test/ui/suggestions/inner_type2.stderr b/src/test/ui/suggestions/inner_type2.stderr index eddfd9d63409d..984366123c827 100644 --- a/src/test/ui/suggestions/inner_type2.stderr +++ b/src/test/ui/suggestions/inner_type2.stderr @@ -17,7 +17,7 @@ error[E0599]: no method named `method` found for union `MaybeUninit` in the curr LL | item.method(); | ^^^^^^ method not found in `MaybeUninit>` | - = help: if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value + = help: if this `MaybeUninit>` has been initialized, use one of the `assume_init` methods to access the inner value note: the method `method` exists on the type `Struct` --> $DIR/inner_type2.rs:6:5 | From 5e2b45194b6fd6b6abcefb07d40c76029f655592 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 5 Nov 2022 23:06:58 +0000 Subject: [PATCH 349/482] Rebase and update test --- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 ++-- src/test/ui/suggestions/issue-102354.stderr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 565ee10206af8..799043842201a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -400,7 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if static_candidates.len() == 1 { let mut has_unsuggestable_args = false; let ty_str = if let Some(CandidateSource::Impl(impl_did)) = - static_candidates.get(0) + static_candidates.get(0) { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.ty_to_value_string(actual.peel_refs()) }; if let SelfSource::MethodCall(_) = source { - let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) && + let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) && let Some(assoc) = self.associated_value(*impl_did, item_name) { let sig = self.tcx.fn_sig(assoc.def_id); if let Some(first) = sig.inputs().skip_binder().get(0) { diff --git a/src/test/ui/suggestions/issue-102354.stderr b/src/test/ui/suggestions/issue-102354.stderr index 4f76c5f2e75b2..b17c4dc5dfb50 100644 --- a/src/test/ui/suggestions/issue-102354.stderr +++ b/src/test/ui/suggestions/issue-102354.stderr @@ -13,7 +13,7 @@ LL | fn func() {} help: use associated function syntax instead | LL | i32::func(); - | ~~~~~~~~~ + | ~~~~~~~~~~~ help: disambiguate the associated function for the candidate | LL | ::func(x); From 6c1f4d23576df09c8d2e3067239b268043e84843 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 27 Oct 2022 14:43:15 +0800 Subject: [PATCH 350/482] fix #103587, Recover from common if let syntax mistakes/typos --- .../locales/en-US/parser.ftl | 3 + .../src/infer/error_reporting/mod.rs | 74 +++++++++++++++++++ compiler/rustc_parse/src/errors.rs | 9 +++ compiler/rustc_parse/src/parser/expr.rs | 16 +++- src/test/ui/inference/issue-103587.rs | 12 +++ src/test/ui/inference/issue-103587.stderr | 40 ++++++++++ src/test/ui/suggestions/if-let-typo.stderr | 15 ++++ 7 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/inference/issue-103587.rs create mode 100644 src/test/ui/inference/issue-103587.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 455ff34f7247f..6d42b23fb3a21 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -125,6 +125,9 @@ parser_if_expression_missing_condition = missing condition for `if` expression parser_expected_expression_found_let = expected expression, found `let` statement +parser_expect_eq_instead_of_eqeq = expected `=`, found `==` + .suggestion = consider using `=` here + parser_expected_else_block = expected `{"{"}`, found {$first_tok} .label = expected an `if` or a block after this `else` .suggestion = add an `if` if this is the condition of a chained `else if` statement diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 61519454a2cf5..8dd7743ee5a13 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength //! Error Reporting Code for the inference engine //! //! Because of the way inference, and in particular region inference, @@ -58,12 +59,14 @@ use crate::traits::{ StatementAsExpression, }; +use hir::intravisit::{walk_expr, walk_stmt}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::Node; use rustc_middle::dep_graph::DepContext; @@ -2336,6 +2339,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } } + // For code `if Some(..) = expr `, the type mismatch may be expected `bool` but found `()`, + // we try to suggest to add the missing `let` for `if let Some(..) = expr` + (ty::Bool, ty::Tuple(list)) => if list.len() == 0 { + self.suggest_let_for_letchains(&mut err, &trace.cause, span); + } _ => {} } } @@ -2360,6 +2368,72 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag } + /// Try to find code with pattern `if Some(..) = expr` + /// use a `visitor` to mark the `if` which its span contains given error span, + /// and then try to find a assignment in the `cond` part, which span is equal with error span + fn suggest_let_for_letchains( + &self, + err: &mut Diagnostic, + cause: &ObligationCause<'_>, + span: Span, + ) { + let hir = self.tcx.hir(); + let fn_hir_id = hir.get_parent_node(cause.body_id); + if let Some(node) = self.tcx.hir().find(fn_hir_id) && + let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(_sig, _, body_id), .. + }) = node { + let body = hir.body(*body_id); + + /// Find the if expression with given span + struct IfVisitor { + pub result: bool, + pub found_if: bool, + pub err_span: Span, + } + + impl<'v> Visitor<'v> for IfVisitor { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if self.result { return; } + match ex.kind { + hir::ExprKind::If(cond, _, _) => { + self.found_if = true; + walk_expr(self, cond); + self.found_if = false; + } + _ => walk_expr(self, ex), + } + } + + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { + if let hir::StmtKind::Local(hir::Local { + span, pat: hir::Pat{..}, ty: None, init: Some(_), .. + }) = &ex.kind + && self.found_if + && span.eq(&self.err_span) { + self.result = true; + } + walk_stmt(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + hir::intravisit::walk_body(self, body); + } + } + + let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; + visitor.visit_body(&body); + if visitor.result { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "consider adding `let`", + "let ".to_string(), + Applicability::MachineApplicable, + ); + } + } + } + fn emit_tuple_wrap_err( &self, err: &mut Diagnostic, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 0924c8537159c..89d5fe3d9da1e 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -420,6 +420,15 @@ pub(crate) struct ExpectedExpressionFoundLet { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parser_expect_eq_instead_of_eqeq)] +pub(crate) struct ExpectedEqForLetExpr { + #[primary_span] + pub span: Span, + #[suggestion_verbose(applicability = "maybe-incorrect", code = "=")] + pub sugg_span: Span, +} + #[derive(Diagnostic)] #[diag(parser_expected_else_block)] pub(crate) struct ExpectedElseBlock { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d784fef2bed58..da2d20e47ee68 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -9,9 +9,9 @@ use crate::errors::{ ArrayBracketsInsteadOfSpaces, ArrayBracketsInsteadOfSpacesSugg, AsyncMoveOrderIncorrect, BinaryFloatLiteralNotSupported, BracesForStructLiteral, CatchAfterTry, CommaAfterBaseStruct, ComparisonInterpretedAsGeneric, ComparisonOrShiftInterpretedAsGenericSugg, - DoCatchSyntaxRemoved, DotDotDot, EqFieldInit, ExpectedElseBlock, ExpectedExpressionFoundLet, - FieldExpressionWithGeneric, FloatLiteralRequiresIntegerPart, FoundExprWouldBeStmt, - HexadecimalFloatLiteralNotSupported, IfExpressionMissingCondition, + DoCatchSyntaxRemoved, DotDotDot, EqFieldInit, ExpectedElseBlock, ExpectedEqForLetExpr, + ExpectedExpressionFoundLet, FieldExpressionWithGeneric, FloatLiteralRequiresIntegerPart, + FoundExprWouldBeStmt, HexadecimalFloatLiteralNotSupported, IfExpressionMissingCondition, IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, IntLiteralTooLarge, InvalidBlockMacroSegment, InvalidComparisonOperator, InvalidComparisonOperatorSub, InvalidFloatLiteralSuffix, InvalidFloatLiteralWidth, InvalidIntLiteralWidth, @@ -2329,7 +2329,15 @@ impl<'a> Parser<'a> { RecoverColon::Yes, CommaRecoveryMode::LikelyTuple, )?; - self.expect(&token::Eq)?; + if self.token == token::EqEq { + self.sess.emit_err(ExpectedEqForLetExpr { + span: self.token.span, + sugg_span: self.token.span, + }); + self.bump(); + } else { + self.expect(&token::Eq)?; + } let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| { this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) })?; diff --git a/src/test/ui/inference/issue-103587.rs b/src/test/ui/inference/issue-103587.rs new file mode 100644 index 0000000000000..11536f9f4cc48 --- /dev/null +++ b/src/test/ui/inference/issue-103587.rs @@ -0,0 +1,12 @@ +fn main() { + let x = Some(123); + + if let Some(_) == x {} + //~^ ERROR expected `=`, found `==` + + if Some(_) = x {} + //~^ ERROR mismatched types + + if None = x { } + //~^ ERROR mismatched types +} diff --git a/src/test/ui/inference/issue-103587.stderr b/src/test/ui/inference/issue-103587.stderr new file mode 100644 index 0000000000000..b373fbfbb948c --- /dev/null +++ b/src/test/ui/inference/issue-103587.stderr @@ -0,0 +1,40 @@ +error: expected `=`, found `==` + --> $DIR/issue-103587.rs:4:20 + | +LL | if let Some(_) == x {} + | ^^ + | +help: consider using `=` here + | +LL | if let Some(_) = x {} + | ~ + +error[E0308]: mismatched types + --> $DIR/issue-103587.rs:7:8 + | +LL | if Some(_) = x {} + | ^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | if let Some(_) = x {} + | +++ + +error[E0308]: mismatched types + --> $DIR/issue-103587.rs:10:8 + | +LL | if None = x { } + | ^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let None = x { } + | +++ +help: you might have meant to compare for equality + | +LL | if None == x { } + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr index 3d9ac40ec367b..02148b7f7adfd 100644 --- a/src/test/ui/suggestions/if-let-typo.stderr +++ b/src/test/ui/suggestions/if-let-typo.stderr @@ -25,12 +25,22 @@ error[E0308]: mismatched types | LL | if Some(x) = foo {} | ^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | if let Some(x) = foo {} + | +++ error[E0308]: mismatched types --> $DIR/if-let-typo.rs:6:8 | LL | if Some(foo) = bar {} | ^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | if let Some(foo) = bar {} + | +++ error[E0308]: mismatched types --> $DIR/if-let-typo.rs:7:8 @@ -51,6 +61,11 @@ error[E0308]: mismatched types | LL | if Some(3) = foo {} | ^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | if let Some(3) = foo {} + | +++ error: aborting due to 7 previous errors From 35899ccef5abe23878fa53948a45d208b27814a6 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 8 Nov 2022 16:04:14 +0800 Subject: [PATCH 351/482] use subdiagnostic for sugesting add let --- .../rustc_error_messages/locales/en-US/infer.ftl | 1 + compiler/rustc_infer/src/errors/mod.rs | 12 ++++++++++++ .../rustc_infer/src/infer/error_reporting/mod.rs | 8 ++------ compiler/rustc_parse/src/errors.rs | 2 +- src/test/ui/did_you_mean/issue-103909.stderr | 5 +++++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 18b3408b06ab4..fa975ff2c20cf 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -171,3 +171,4 @@ infer_msl_introduces_static = introduces a `'static` lifetime requirement infer_msl_unmet_req = because this has an unmet lifetime requirement infer_msl_trait_note = this has an implicit `'static` lifetime requirement infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement +infer_suggest_add_let_for_letchains = consider adding `let` diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index bb04e1c49baea..ec4eeb8caa27c 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -180,6 +180,18 @@ pub enum SourceKindMultiSuggestion<'a> { }, } +#[derive(Subdiagnostic)] +#[suggestion( + infer_suggest_add_let_for_letchains, + style = "verbose", + applicability = "machine-applicable", + code = "let " +)] +pub(crate) struct SuggAddLetForLetChains { + #[primary_span] + pub span: Span, +} + impl<'a> SourceKindMultiSuggestion<'a> { pub fn new_fully_qualified( span: Span, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8dd7743ee5a13..22f32251f6df0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -59,6 +59,7 @@ use crate::traits::{ StatementAsExpression, }; +use crate::errors::SuggAddLetForLetChains; use hir::intravisit::{walk_expr, walk_stmt}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; @@ -2424,12 +2425,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; visitor.visit_body(&body); if visitor.result { - err.span_suggestion_verbose( - span.shrink_to_lo(), - "consider adding `let`", - "let ".to_string(), - Applicability::MachineApplicable, - ); + err.subdiagnostic(SuggAddLetForLetChains{span: span.shrink_to_lo()}); } } } diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 89d5fe3d9da1e..e3acc11811f42 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -425,7 +425,7 @@ pub(crate) struct ExpectedExpressionFoundLet { pub(crate) struct ExpectedEqForLetExpr { #[primary_span] pub span: Span, - #[suggestion_verbose(applicability = "maybe-incorrect", code = "=")] + #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")] pub sugg_span: Span, } diff --git a/src/test/ui/did_you_mean/issue-103909.stderr b/src/test/ui/did_you_mean/issue-103909.stderr index a28914051b980..8641017470ba0 100644 --- a/src/test/ui/did_you_mean/issue-103909.stderr +++ b/src/test/ui/did_you_mean/issue-103909.stderr @@ -14,6 +14,11 @@ error[E0308]: mismatched types | LL | if Err(err) = File::open("hello.txt") { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | if let Err(err) = File::open("hello.txt") { + | +++ error: aborting due to 2 previous errors From 146061cafe71e7b063b193d8b816feed3a5a4592 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 9 Nov 2022 19:23:23 +0800 Subject: [PATCH 352/482] bless clippy --- src/tools/clippy/tests/ui/crashes/ice-6250.stderr | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr index 878897c410cf5..4506d1550bd4b 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr @@ -23,6 +23,11 @@ error[E0308]: mismatched types | LL | Some(reference) = cache.data.get(key) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: consider adding `let` + | +LL | let Some(reference) = cache.data.get(key) { + | +++ error: aborting due to 3 previous errors From a286378795d8fc56567728c3f3d3130f9a37e992 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Oct 2022 21:39:37 +0000 Subject: [PATCH 353/482] DiagnosticBuilder -> Diagnostic --- .../src/diagnostics/mutability_errors.rs | 19 ++++++------------- compiler/rustc_passes/src/liveness.rs | 3 ++- .../rustc_resolve/src/late/diagnostics.rs | 10 +++++----- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 8ad40c0aa0a5d..1cb2e5e326014 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1,6 +1,4 @@ -use rustc_errors::{ - Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, -}; +use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; @@ -629,25 +627,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.buffer_error(err); } - fn suggest_map_index_mut_alternatives( - &self, - ty: Ty<'_>, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, - span: Span, - ) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) || self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did) { - struct V<'a, 'b, 'tcx, G: EmissionGuarantee> { + struct V<'a, 'tcx> { assign_span: Span, - err: &'a mut DiagnosticBuilder<'b, G>, + err: &'a mut Diagnostic, ty: Ty<'tcx>, suggested: bool, } - impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> { - fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) { + impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> { + fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { hir::intravisit::walk_stmt(self, stmt); let expr = match stmt.kind { hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr, diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index c6fe40f72fc63..c181de48a9ad8 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -87,6 +87,7 @@ use self::VarKind::*; use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -1690,7 +1691,7 @@ impl<'tcx> Liveness<'_, 'tcx> { &self, name: &str, opt_body: Option<&hir::Body<'_>>, - err: &mut rustc_errors::DiagnosticBuilder<'_, ()>, + err: &mut Diagnostic, ) -> bool { let mut has_litstring = false; let Some(opt_body) = opt_body else {return false;}; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a1338dcd4771b..8989c888ed14a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -437,7 +437,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn try_lookup_name_relaxed( &mut self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, source: PathSource<'_>, path: &[Segment], span: Span, @@ -497,7 +497,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .contains(span) { // Already reported this issue on the lhs of the type ascription. - err.delay_as_bug(); + err.downgrade_to_delayed_bug(); return (true, candidates); } } @@ -616,7 +616,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn suggest_trait_and_bounds( &mut self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, source: PathSource<'_>, res: Option, span: Span, @@ -691,7 +691,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn suggest_typo( &mut self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, source: PathSource<'_>, path: &[Segment], span: Span, @@ -750,7 +750,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn err_code_special_cases( &mut self, - err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + err: &mut Diagnostic, source: PathSource<'_>, path: &[Segment], span: Span, From c908985c348ef757b67ac98477ea33087115f5b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Oct 2022 02:05:57 +0000 Subject: [PATCH 354/482] Make span_suggestions take IntoIterator --- .../rustc_borrowck/src/diagnostics/mutability_errors.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 6 +++--- compiler/rustc_errors/src/diagnostic_builder.rs | 4 ++-- compiler/rustc_parse/src/parser/ty.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 6 +++--- .../src/traits/error_reporting/suggestions.rs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 1cb2e5e326014..7457369aa58cb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -698,7 +698,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ), (rv.span.shrink_to_hi(), ")".to_string()), ], - ].into_iter(), + ], Applicability::MachineApplicable, ); self.suggested = true; diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 43101bbb9d31c..2ce48259912b0 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -742,7 +742,7 @@ impl Diagnostic { &mut self, sp: Span, msg: impl Into, - suggestions: impl Iterator, + suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self { self.span_suggestions_with_style( @@ -763,7 +763,7 @@ impl Diagnostic { applicability: Applicability, style: SuggestionStyle, ) -> &mut Self { - let mut suggestions: Vec<_> = suggestions.collect(); + let mut suggestions: Vec<_> = suggestions.into_iter().collect(); suggestions.sort(); debug_assert!( @@ -790,7 +790,7 @@ impl Diagnostic { pub fn multipart_suggestions( &mut self, msg: impl Into, - suggestions: impl Iterator>, + suggestions: impl IntoIterator>, applicability: Applicability, ) -> &mut Self { let suggestions: Vec<_> = suggestions.collect(); diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 730061fca9936..18cbf963494fc 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -599,13 +599,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { &mut self, sp: Span, msg: impl Into, - suggestions: impl Iterator, + suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self); forward!(pub fn multipart_suggestions( &mut self, msg: impl Into, - suggestions: impl Iterator>, + suggestions: impl IntoIterator>, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_short( diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 2a8512acf8cfa..3a67c032b3bdd 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -401,7 +401,7 @@ impl<'a> Parser<'a> { .span_suggestions( span.shrink_to_hi(), "add `mut` or `const` here", - ["mut ".to_string(), "const ".to_string()].into_iter(), + ["mut ".to_string(), "const ".to_string()], Applicability::HasPlaceholders, ) .emit(); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8989c888ed14a..cdc28db13f3ac 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1941,7 +1941,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestions( span, &msg, - suggestable_variants.into_iter(), + suggestable_variants, Applicability::MaybeIncorrect, ); } @@ -1995,7 +1995,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestions( span, msg, - suggestable_variants.into_iter(), + suggestable_variants, Applicability::MaybeIncorrect, ); } @@ -2025,7 +2025,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestions( span, msg, - suggestable_variants_with_placeholders.into_iter(), + suggestable_variants_with_placeholders, Applicability::HasPlaceholders, ); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index aece4ab792285..540b1fa2b0fb7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1116,7 +1116,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_suggestions( span.shrink_to_lo(), "consider borrowing here", - ["&".to_string(), "&mut ".to_string()].into_iter(), + ["&".to_string(), "&mut ".to_string()], Applicability::MaybeIncorrect, ); } else { From 79a517a6e724d2bc9591025b7427acdf030696aa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 5 Nov 2022 18:29:47 +0000 Subject: [PATCH 355/482] rebase conflict --- compiler/rustc_errors/src/diagnostic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 2ce48259912b0..375e3ebd77df7 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -759,7 +759,7 @@ impl Diagnostic { &mut self, sp: Span, msg: impl Into, - suggestions: impl Iterator, + suggestions: impl IntoIterator, applicability: Applicability, style: SuggestionStyle, ) -> &mut Self { @@ -793,7 +793,7 @@ impl Diagnostic { suggestions: impl IntoIterator>, applicability: Applicability, ) -> &mut Self { - let suggestions: Vec<_> = suggestions.collect(); + let suggestions: Vec<_> = suggestions.into_iter().collect(); debug_assert!( !(suggestions .iter() From 87e513f1f19b0feecb1acf21e236cbe9fdd0f307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20A=2E=20Muci=C3=B1o?= Date: Tue, 8 Nov 2022 20:13:10 -0600 Subject: [PATCH 356/482] Parser: Recover from using colon as path separator in imports --- compiler/rustc_parse/src/parser/item.rs | 17 +++++++++++ src/test/ui/parser/use-colon-as-mod-sep.rs | 11 ++++++++ .../ui/parser/use-colon-as-mod-sep.stderr | 28 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/test/ui/parser/use-colon-as-mod-sep.rs create mode 100644 src/test/ui/parser/use-colon-as-mod-sep.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index bda301c52e960..d657a2891171d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -971,6 +971,23 @@ impl<'a> Parser<'a> { if self.eat(&token::ModSep) { self.parse_use_tree_glob_or_nested()? } else { + // Recover from using a colon as path separator. + while self.eat_noexpect(&token::Colon) { + self.struct_span_err(self.prev_token.span, "expected `::`, found `:`") + .span_suggestion_short( + self.prev_token.span, + "use double colon", + "::", + Applicability::MachineApplicable, + ) + .note_once("import paths are delimited using `::`") + .emit(); + + // We parse the rest of the path and append it to the original prefix. + self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?; + prefix.span = lo.to(self.prev_token.span); + } + UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID) } }; diff --git a/src/test/ui/parser/use-colon-as-mod-sep.rs b/src/test/ui/parser/use-colon-as-mod-sep.rs new file mode 100644 index 0000000000000..e1e8756b03c26 --- /dev/null +++ b/src/test/ui/parser/use-colon-as-mod-sep.rs @@ -0,0 +1,11 @@ +// Recover from using a colon as a path separator. + +use std::process:Command; +//~^ ERROR expected `::`, found `:` +use std:fs::File; +//~^ ERROR expected `::`, found `:` +use std:collections:HashMap; +//~^ ERROR expected `::`, found `:` +//~| ERROR expected `::`, found `:` + +fn main() { } diff --git a/src/test/ui/parser/use-colon-as-mod-sep.stderr b/src/test/ui/parser/use-colon-as-mod-sep.stderr new file mode 100644 index 0000000000000..e825dfed11192 --- /dev/null +++ b/src/test/ui/parser/use-colon-as-mod-sep.stderr @@ -0,0 +1,28 @@ +error: expected `::`, found `:` + --> $DIR/use-colon-as-mod-sep.rs:3:17 + | +LL | use std::process:Command; + | ^ help: use double colon + | + = note: import paths are delimited using `::` + +error: expected `::`, found `:` + --> $DIR/use-colon-as-mod-sep.rs:5:8 + | +LL | use std:fs::File; + | ^ help: use double colon + +error: expected `::`, found `:` + --> $DIR/use-colon-as-mod-sep.rs:7:8 + | +LL | use std:collections:HashMap; + | ^ help: use double colon + +error: expected `::`, found `:` + --> $DIR/use-colon-as-mod-sep.rs:7:20 + | +LL | use std:collections:HashMap; + | ^ help: use double colon + +error: aborting due to 4 previous errors + From 6c87fa0a386da12a39ebc6ed7a57c77f30dd2b9d Mon Sep 17 00:00:00 2001 From: Yiming Lei Date: Thu, 27 Oct 2022 22:38:59 -0700 Subject: [PATCH 357/482] remove redundent "<>" for ty::Slice with reference type this fix #103271 --- .../rustc_hir_typeck/src/method/suggest.rs | 6 +++ compiler/rustc_span/src/source_map.rs | 44 +++++++++++++++++++ src/test/ui/type/issue-103271.rs | 10 +++++ src/test/ui/type/issue-103271.stderr | 14 ++++++ 4 files changed, 74 insertions(+) create mode 100644 src/test/ui/type/issue-103271.rs create mode 100644 src/test/ui/type/issue-103271.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 799043842201a..43a5145b7e74d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1900,6 +1900,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Str | ty::Projection(_) | ty::Param(_) => format!("{deref_ty}"), + // we need to test something like <&[_]>::len + // and Vec::function(); + // <&[_]>::len doesn't need an extra "<>" between + // but for Adt type like Vec::function() + // we would suggest <[_]>::function(); + _ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"), _ => format!("<{deref_ty}>"), }; err.span_suggestion_verbose( diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 3baa2e03cbad7..7ea028b12efc4 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -753,6 +753,50 @@ impl SourceMap { } } + /// Given a 'Span', tries to tell if the next character is '>' + /// and the previous charactoer is '<' after skipping white space + /// return true if wrapped by '<>' + pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool { + self.span_to_source(span, |src, start_index, end_index| { + if src.get(start_index..end_index).is_none() { + return Ok(false); + } + // test the right side to match '>' after skipping white space + let end_src = &src[end_index..]; + let mut i = 0; + while let Some(cc) = end_src.chars().nth(i) { + if cc == ' ' { + i = i + 1; + } else if cc == '>' { + // found > in the right; + break; + } else { + // failed to find '>' return false immediately + return Ok(false); + } + } + // test the left side to match '<' after skipping white space + i = start_index; + let start_src = &src[0..start_index]; + while let Some(cc) = start_src.chars().nth(i) { + if cc == ' ' { + if i == 0 { + return Ok(false); + } + i = i - 1; + } else if cc == '<' { + // found < in the left + break; + } else { + // failed to find '<' return false immediately + return Ok(false); + } + } + return Ok(true); + }) + .map_or(false, |is_accessible| is_accessible) + } + /// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char` /// `c`. pub fn span_through_char(&self, sp: Span, c: char) -> Span { diff --git a/src/test/ui/type/issue-103271.rs b/src/test/ui/type/issue-103271.rs new file mode 100644 index 0000000000000..bd3254af3df71 --- /dev/null +++ b/src/test/ui/type/issue-103271.rs @@ -0,0 +1,10 @@ +fn main() { + let iter_fun = <&[u32]>::iter; + //~^ ERROR no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599] + //~| function or associated item not found in `&[u32]` + //~| HELP the function `iter` is implemented on `[u32]` + for item in iter_fun(&[1,1]) { + let x: &u32 = item; + assert_eq!(x, &1); + } +} diff --git a/src/test/ui/type/issue-103271.stderr b/src/test/ui/type/issue-103271.stderr new file mode 100644 index 0000000000000..02a59d4b99c4d --- /dev/null +++ b/src/test/ui/type/issue-103271.stderr @@ -0,0 +1,14 @@ +error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope + --> $DIR/issue-103271.rs:2:30 + | +LL | let iter_fun = <&[u32]>::iter; + | ^^^^ function or associated item not found in `&[u32]` + | +help: the function `iter` is implemented on `[u32]` + | +LL | let iter_fun = <[u32]>::iter; + | ~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From cad8900ee0de97f84082453e53e35f4e507380de Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 6 Nov 2022 09:49:09 +0100 Subject: [PATCH 358/482] bootstrap: add support for running Miri on a file --- src/bootstrap/builder.rs | 3 +- src/bootstrap/flags.rs | 25 +++++++---- src/bootstrap/run.rs | 68 +++++++++++++++++++++++++++++- src/bootstrap/test.rs | 90 +++++++++++++++++++++------------------- 4 files changed, 132 insertions(+), 54 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 406bae02d84da..6fd363935079d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -755,6 +755,7 @@ impl<'a> Builder<'a> { run::BuildManifest, run::BumpStage0, run::ReplaceVersionPlaceholder, + run::Miri, ), // These commands either don't use paths, or they're special-cased in Build::build() Kind::Clean | Kind::Format | Kind::Setup => vec![], @@ -818,7 +819,7 @@ impl<'a> Builder<'a> { Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]), Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]), Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), - Subcommand::Run { ref paths } => (Kind::Run, &paths[..]), + Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]), Subcommand::Format { .. } => (Kind::Format, &[][..]), Subcommand::Clean { .. } | Subcommand::Setup { .. } => { panic!() diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index ee341a353ac47..2001e29bd2ead 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -140,6 +140,7 @@ pub enum Subcommand { }, Run { paths: Vec, + args: Vec, }, Setup { profile: Profile, @@ -342,6 +343,9 @@ To learn more about a subcommand, run `./x.py -h`", Kind::Format => { opts.optflag("", "check", "check formatting instead of applying."); } + Kind::Run => { + opts.optmulti("", "args", "arguments for the tool", "ARGS"); + } _ => {} }; @@ -613,7 +617,7 @@ Arguments: println!("\nrun requires at least a path!\n"); usage(1, &opts, verbose, &subcommand_help); } - Subcommand::Run { paths } + Subcommand::Run { paths, args: matches.opt_strs("args") } } Kind::Setup => { let profile = if paths.len() > 1 { @@ -721,16 +725,12 @@ impl Subcommand { } pub fn test_args(&self) -> Vec<&str> { - let mut args = vec![]; - match *self { Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { - args.extend(test_args.iter().flat_map(|s| s.split_whitespace())) + test_args.iter().flat_map(|s| s.split_whitespace()).collect() } - _ => (), + _ => vec![], } - - args } pub fn rustc_args(&self) -> Vec<&str> { @@ -738,7 +738,16 @@ impl Subcommand { Subcommand::Test { ref rustc_args, .. } => { rustc_args.iter().flat_map(|s| s.split_whitespace()).collect() } - _ => Vec::new(), + _ => vec![], + } + } + + pub fn args(&self) -> Vec<&str> { + match *self { + Subcommand::Run { ref args, .. } => { + args.iter().flat_map(|s| s.split_whitespace()).collect() + } + _ => vec![], } } diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 511872903d14e..d49b41c513279 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,8 +1,12 @@ +use std::process::Command; + use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::config::TargetSelection; use crate::dist::distdir; -use crate::tool::Tool; +use crate::test; +use crate::tool::{self, SourceType, Tool}; use crate::util::output; -use std::process::Command; +use crate::Mode; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct ExpandYamlAnchors; @@ -125,3 +129,63 @@ impl Step for ReplaceVersionPlaceholder { builder.run(&mut cmd); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct Miri { + stage: u32, + host: TargetSelection, + target: TargetSelection, +} + +impl Step for Miri { + type Output = (); + const ONLY_HOSTS: bool = false; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/miri") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Miri { + stage: run.builder.top_stage, + host: run.build_triple(), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) { + let stage = self.stage; + let host = self.host; + let target = self.target; + let compiler = builder.compiler(stage, host); + + let miri = builder + .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() }) + .expect("in-tree tool"); + let miri_sysroot = test::Miri::build_miri_sysroot(builder, compiler, &miri, target); + + // # Run miri. + // Running it via `cargo run` as that figures out the right dylib path. + // add_rustc_lib_path does not add the path that contains librustc_driver-<...>.so. + let mut miri = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "run", + "src/tools/miri", + SourceType::InTree, + &[], + ); + miri.add_rustc_lib_path(builder, compiler); + // Forward arguments. + miri.arg("--").arg("--target").arg(target.rustc_target_arg()); + miri.args(builder.config.cmd.args()); + + // miri tests need to know about the stage sysroot + miri.env("MIRI_SYSROOT", &miri_sysroot); + + let mut miri = Command::from(miri); + builder.run(&mut miri); + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 931d9a67944df..46ad047081273 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -465,49 +465,14 @@ pub struct Miri { target: TargetSelection, } -impl Step for Miri { - type Output = (); - const ONLY_HOSTS: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/miri") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Miri { - stage: run.builder.top_stage, - host: run.build_triple(), - target: run.target, - }); - } - - /// Runs `cargo test` for miri. - fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let host = self.host; - let target = self.target; - let compiler = builder.compiler(stage, host); - // We need the stdlib for the *next* stage, as it was built with this compiler that also built Miri. - // Except if we are at stage 2, the bootstrap loop is complete and we can stick with our current stage. - let compiler_std = builder.compiler(if stage < 2 { stage + 1 } else { stage }, host); - - let miri = builder - .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() }) - .expect("in-tree tool"); - let _cargo_miri = builder - .ensure(tool::CargoMiri { compiler, target: self.host, extra_features: Vec::new() }) - .expect("in-tree tool"); - // The stdlib we need might be at a different stage. And just asking for the - // sysroot does not seem to populate it, so we do that first. - builder.ensure(compile::Std::new(compiler_std, host)); - let sysroot = builder.sysroot(compiler_std); - - // # Run `cargo miri setup` for the given target. +impl Miri { + /// Run `cargo miri setup` for the given target, return where the Miri sysroot was put. + pub fn build_miri_sysroot(builder: &Builder<'_>, compiler: Compiler, miri: &Path, target: TargetSelection) -> String { let mut cargo = tool::prepare_tool_cargo( builder, compiler, Mode::ToolRustc, - host, + compiler.host, "run", "src/tools/miri/cargo-miri", SourceType::InTree, @@ -535,7 +500,7 @@ impl Step for Miri { cargo.arg("--print-sysroot"); // FIXME: Is there a way in which we can re-use the usual `run` helpers? - let miri_sysroot = if builder.config.dry_run { + if builder.config.dry_run { String::new() } else { builder.verbose(&format!("running: {:?}", cargo)); @@ -548,7 +513,48 @@ impl Step for Miri { let sysroot = stdout.trim_end(); builder.verbose(&format!("`cargo miri setup --print-sysroot` said: {:?}", sysroot)); sysroot.to_owned() - }; + } + } +} + +impl Step for Miri { + type Output = (); + const ONLY_HOSTS: bool = false; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/miri") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Miri { + stage: run.builder.top_stage, + host: run.build_triple(), + target: run.target, + }); + } + + /// Runs `cargo test` for miri. + fn run(self, builder: &Builder<'_>) { + let stage = self.stage; + let host = self.host; + let target = self.target; + let compiler = builder.compiler(stage, host); + // We need the stdlib for the *next* stage, as it was built with this compiler that also built Miri. + // Except if we are at stage 2, the bootstrap loop is complete and we can stick with our current stage. + let compiler_std = builder.compiler(if stage < 2 { stage + 1 } else { stage }, host); + + let miri = builder + .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() }) + .expect("in-tree tool"); + let _cargo_miri = builder + .ensure(tool::CargoMiri { compiler, target: self.host, extra_features: Vec::new() }) + .expect("in-tree tool"); + // The stdlib we need might be at a different stage. And just asking for the + // sysroot does not seem to populate it, so we do that first. + builder.ensure(compile::Std::new(compiler_std, host)); + let sysroot = builder.sysroot(compiler_std); + // We also need a Miri sysroot. + let miri_sysroot = Miri::build_miri_sysroot(builder, compiler, &miri, target); // # Run `cargo test`. let mut cargo = tool::prepare_tool_cargo( @@ -566,7 +572,6 @@ impl Step for Miri { // miri tests need to know about the stage sysroot cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", sysroot); - cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); cargo.env("MIRI", &miri); // propagate --bless if builder.config.cmd.bless() { @@ -607,7 +612,6 @@ impl Step for Miri { // Tell `cargo miri` where to find things. cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", sysroot); - cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); cargo.env("MIRI", &miri); // Debug things. cargo.env("RUST_BACKTRACE", "1"); From 3a7a1c98c922460307f5c7fc7560525f7f78807e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 6 Nov 2022 10:13:32 +0100 Subject: [PATCH 359/482] bootstrap: put Miri sysroot into local build dir --- src/bootstrap/test.rs | 10 +++++++++- src/tools/miri/README.md | 6 ++++-- src/tools/miri/cargo-miri/src/setup.rs | 19 +++++++++++-------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 46ad047081273..2b2257b72ae79 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -467,7 +467,13 @@ pub struct Miri { impl Miri { /// Run `cargo miri setup` for the given target, return where the Miri sysroot was put. - pub fn build_miri_sysroot(builder: &Builder<'_>, compiler: Compiler, miri: &Path, target: TargetSelection) -> String { + pub fn build_miri_sysroot( + builder: &Builder<'_>, + compiler: Compiler, + miri: &Path, + target: TargetSelection, + ) -> String { + let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysrot"); let mut cargo = tool::prepare_tool_cargo( builder, compiler, @@ -486,6 +492,8 @@ impl Miri { cargo.env("MIRI_LIB_SRC", builder.src.join("library")); // Tell it where to find Miri. cargo.env("MIRI", &miri); + // Tell it where to put the sysroot. + cargo.env("MIRI_SYSROOT", &miri_sysroot); // Debug things. cargo.env("RUST_BACKTRACE", "1"); diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 5803a88c0e757..f5a20d592d06d 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -433,8 +433,10 @@ Moreover, Miri recognizes some environment variables: trigger a re-build of the standard library; you have to clear the Miri build cache manually (on Linux, `rm -rf ~/.cache/miri`). * `MIRI_SYSROOT` (recognized by `cargo miri` and the Miri driver) indicates the sysroot to use. When - using `cargo miri`, only set this if you do not want to use the automatically created sysroot. For - directly invoking the Miri driver, this variable (or a `--sysroot` flag) is mandatory. + using `cargo miri`, this skips the automatic setup -- only set this if you do not want to use the + automatically created sysroot. For directly invoking the Miri driver, this variable (or a + `--sysroot` flag) is mandatory. When invoking `cargo miri setup`, this indicates where the sysroot + will be put. * `MIRI_TEST_TARGET` (recognized by the test suite and the `./miri` script) indicates which target architecture to test against. `miri` and `cargo miri` accept the `--target` flag for the same purpose. diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs index 72d8ef2f75224..f3841a6140839 100644 --- a/src/tools/miri/cargo-miri/src/setup.rs +++ b/src/tools/miri/cargo-miri/src/setup.rs @@ -17,10 +17,8 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta let only_setup = matches!(subcommand, MiriCommand::Setup); let ask_user = !only_setup; let print_sysroot = only_setup && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path - if std::env::var_os("MIRI_SYSROOT").is_some() { - if only_setup { - println!("WARNING: MIRI_SYSROOT already set, not doing anything.") - } + if !only_setup && std::env::var_os("MIRI_SYSROOT").is_some() { + // Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`. return; } @@ -61,8 +59,13 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta } // Determine where to put the sysroot. - let user_dirs = directories::ProjectDirs::from("org", "rust-lang", "miri").unwrap(); - let sysroot_dir = user_dirs.cache_dir(); + let sysroot_dir = match std::env::var_os("MIRI_SYSROOT") { + Some(dir) => PathBuf::from(dir), + None => { + let user_dirs = directories::ProjectDirs::from("org", "rust-lang", "miri").unwrap(); + user_dirs.cache_dir().to_owned() + } + }; // Sysroot configuration and build details. let sysroot_config = if std::env::var_os("MIRI_NO_STD").is_some() { SysrootConfig::NoStd @@ -111,7 +114,7 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta (command, rustflags) }; // Make sure all target-level Miri invocations know their sysroot. - std::env::set_var("MIRI_SYSROOT", sysroot_dir); + std::env::set_var("MIRI_SYSROOT", &sysroot_dir); // Do the build. if only_setup { @@ -121,7 +124,7 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta // We want to be quiet, but still let the user know that something is happening. eprint!("Preparing a sysroot for Miri (target: {target})... "); } - Sysroot::new(sysroot_dir, target) + Sysroot::new(&sysroot_dir, target) .build_from_source(&rust_src, BuildMode::Check, sysroot_config, rustc_version, cargo_cmd) .unwrap_or_else(|_| { if only_setup { From ea984dc26f3a18c4711455b50ad6436cbe447937 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 7 Nov 2022 18:08:14 +0100 Subject: [PATCH 360/482] Migrate crate-search element to CSS variables --- src/librustdoc/html/static/css/rustdoc.css | 10 +++++++++- src/librustdoc/html/static/css/themes/ayu.css | 17 ++++++----------- src/librustdoc/html/static/css/themes/dark.css | 17 ++++++----------- src/librustdoc/html/static/css/themes/light.css | 17 ++++++----------- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f58d2c609426d..86a5b0b303f39 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -830,6 +830,9 @@ table, line-height: 1.5; font-weight: 500; } +#crate-search:hover, #crate-search:focus { + border-color: var(--crate-search-hover-border); +} /* cancel stylistic differences in padding in firefox for "appearance: none"-style (or equivalent) ` isn't bigger than its container (".search-results-title"). assert-css: ("#search", {"width": "640px"}) + +// Now checking that the crate filter is working as expected too. +show-text: true +define-function: ( + "check-filter", + (theme, border, filter, hover_border, hover_filter), + [ + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + ("reload"), + ("wait-for", "#crate-search"), + ("assert-css", ("#crate-search", {"border": "1px solid " + |border|})), + ("assert-css", ("#crate-search-div::after", {"filter": |filter|})), + ("move-cursor-to", "#crate-search"), + ("assert-css", ("#crate-search", {"border": "1px solid " + |hover_border|})), + ("assert-css", ("#crate-search-div::after", {"filter": |hover_filter|})), + ("move-cursor-to", ".search-input"), + ], +) + +call-function: ("check-filter", { + "theme": "ayu", + "border": "rgb(92, 103, 115)", + "filter": "invert(0.41) sepia(0.12) saturate(4.87) hue-rotate(171deg) brightness(0.94) contrast(0.94)", + "hover_border": "rgb(224, 224, 224)", + "hover_filter": "invert(0.98) sepia(0.12) saturate(0.81) hue-rotate(343deg) brightness(1.13) contrast(0.76)", +}) +call-function: ("check-filter", { + "theme": "dark", + "border": "rgb(224, 224, 224)", + "filter": "invert(0.94) sepia(0) saturate(7.21) hue-rotate(255deg) brightness(0.9) contrast(0.9)", + "hover_border": "rgb(33, 150, 243)", + "hover_filter": "invert(0.69) sepia(0.6) saturate(66.13) hue-rotate(184deg) brightness(1) contrast(0.91)", +}) +call-function: ("check-filter", { + "theme": "light", + "border": "rgb(224, 224, 224)", + "filter": "invert(1) sepia(0) saturate(42.23) hue-rotate(289deg) brightness(1.14) contrast(0.76)", + "hover_border": "rgb(113, 113, 113)", + "hover_filter": "invert(0.44) sepia(0.18) saturate(0.23) hue-rotate(317deg) brightness(0.96) contrast(0.93)", +}) From b6da5043180518e83f5019c87d2ec80de7d13855 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 9 Nov 2022 12:48:38 +0100 Subject: [PATCH 362/482] Ignore "Change InferCtxtBuilder from enter to build" in git blame Because it changed the indentation of many things, this commit caused a lot of diff with no functional changes, so we should ignore it. --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 307e22b0df1fd..b40066d05d355 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -4,3 +4,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60 95e00bfed801e264e9c4ac817004153ca0f19eb6 # reformat with new rustfmt 971c549ca334b7b7406e61e958efcca9c4152822 +# refactor infcx building +283abbf0e7d20176f76006825b5c52e9a4234e4c From fd06d4f1fa48a46841592b2f516e70b3d1ccd324 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 8 Nov 2022 15:00:34 +0100 Subject: [PATCH 363/482] Update browser-ui-test version to 0.13.1 --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index cc96715b28572..ed0d9e9902b99 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.12.7 \ No newline at end of file +0.13.1 \ No newline at end of file From 7749653e59be149c5b7ad7b04711fcd68430e616 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 8 Nov 2022 15:00:48 +0100 Subject: [PATCH 364/482] Add new option to prevent CORS failures --- src/tools/rustdoc-gui/tester.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index 70d5f94472f6b..d40d9a3cb542a 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -149,6 +149,7 @@ async function main(argv) { // This is more convenient that setting fields one by one. let args = [ "--variable", "DOC_PATH", opts["doc_folder"], "--enable-fail-on-js-error", + "--allow-file-access-from-files", ]; if (opts["debug"]) { debug = true; From 072f71df601ae3b03b5ac5bac0b4235c27c24303 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 9 Nov 2022 17:00:05 +0100 Subject: [PATCH 365/482] Update to new browser-ui-test version --- src/test/rustdoc-gui/code-tags.goml | 4 ++++ src/test/rustdoc-gui/item-decl-colors.goml | 5 +++++ src/test/rustdoc-gui/no-docblock.goml | 5 +++++ src/test/rustdoc-gui/trait-sidebar-item-order.goml | 5 +++++ src/test/rustdoc-gui/type-declation-overflow.goml | 6 ++++++ 5 files changed, 25 insertions(+) diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml index 837a2c1d57f5a..94c1a6525aaa5 100644 --- a/src/test/rustdoc-gui/code-tags.goml +++ b/src/test/rustdoc-gui/code-tags.goml @@ -1,4 +1,8 @@ // This test ensures that items and documentation code blocks are wrapped in


+
+// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js`
+// doesn't exist.
+fail-on-request-error: false
 goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 size: (1080, 600)
 // There should be four doc codeblocks.
diff --git a/src/test/rustdoc-gui/item-decl-colors.goml b/src/test/rustdoc-gui/item-decl-colors.goml
index ce688287a7433..9a46f256056f9 100644
--- a/src/test/rustdoc-gui/item-decl-colors.goml
+++ b/src/test/rustdoc-gui/item-decl-colors.goml
@@ -1,4 +1,9 @@
 // This test ensures that the color of the items in the type decl are working as expected.
+
+// We need to disable this check because `implementors/test_docs/trait.TraitWithoutGenerics.js`
+// doesn't exist.
+fail-on-request-error: false
+
 define-function: (
     "check-colors",
     (
diff --git a/src/test/rustdoc-gui/no-docblock.goml b/src/test/rustdoc-gui/no-docblock.goml
index 2366a60f5c61d..17a955064d733 100644
--- a/src/test/rustdoc-gui/no-docblock.goml
+++ b/src/test/rustdoc-gui/no-docblock.goml
@@ -1,4 +1,9 @@
 // This test checks that there are margins applied to methods with no docblocks.
+
+// We need to disable this check because `implementors/test_docs/trait.TraitWithNoDocblock.js`
+// doesn't exist.
+fail-on-request-error: false
+
 goto: "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithNoDocblocks.html"
 // Check that the two methods are more than 24px apart.
 compare-elements-position-near-false: ("//*[@id='tymethod.first_fn']", "//*[@id='tymethod.second_fn']", {"y": 24})
diff --git a/src/test/rustdoc-gui/trait-sidebar-item-order.goml b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
index a799444a1087e..e5d023544d682 100644
--- a/src/test/rustdoc-gui/trait-sidebar-item-order.goml
+++ b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
@@ -1,4 +1,9 @@
 // Checks that the elements in the sidebar are alphabetically sorted.
+
+// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js`
+// doesn't exist.
+fail-on-request-error: false
+
 goto: "file://" + |DOC_PATH| + "/test_docs/trait.AnotherOne.html"
 assert-text: (".sidebar-elems section .block li:nth-of-type(1) > a", "another")
 assert-text: (".sidebar-elems section .block li:nth-of-type(2) > a", "func1")
diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml
index fce3002e7508f..dcffe956c2197 100644
--- a/src/test/rustdoc-gui/type-declation-overflow.goml
+++ b/src/test/rustdoc-gui/type-declation-overflow.goml
@@ -1,4 +1,10 @@
 // This test ensures that the items declaration content overflow is handled inside the 
 directly.
+
+// We need to disable this check because
+// `implementors/test_docs/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.js`
+// doesn't exist.
+fail-on-request-error: false
+
 goto: "file://" + |DOC_PATH| + "/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html"
 // We set a fixed size so there is no chance of "random" resize.
 size: (1100, 800)

From 0a48100e6451807a4a16b66584e7f2b4821ebcf7 Mon Sep 17 00:00:00 2001
From: not_joon 
Date: Thu, 20 Oct 2022 22:06:00 +0900
Subject: [PATCH 366/482] fix broken links in guide.md

---
 src/tools/rust-analyzer/docs/dev/guide.md | 50 +++++++++++------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/src/tools/rust-analyzer/docs/dev/guide.md b/src/tools/rust-analyzer/docs/dev/guide.md
index 52a13da31c5d3..56a68ef043790 100644
--- a/src/tools/rust-analyzer/docs/dev/guide.md
+++ b/src/tools/rust-analyzer/docs/dev/guide.md
@@ -338,7 +338,7 @@ The algorithm for building a tree of modules is to start with a crate root
 declarations and recursively process child modules. This is handled by the
 [`module_tree_query`], with two slight variations.
 
-[`module_tree_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L116-L123
+[`module_tree_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L115-L133
 
 First, rust-analyzer builds a module tree for all crates in a source root
 simultaneously. The main reason for this is historical (`module_tree` predates
@@ -361,7 +361,7 @@ the same, we don't have to re-execute [`module_tree_query`]. In fact, we only
 need to re-execute it when we add/remove new files or when we change mod
 declarations.
 
-[`submodules_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L41
+[`submodules_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41
 
 We store the resulting modules in a `Vec`-based indexed arena. The indices in
 the arena becomes module IDs. And this brings us to the next topic:
@@ -389,8 +389,8 @@ integers which can "intern" a location and return an integer ID back. The salsa
 database we use includes a couple of [interners]. How to "garbage collect"
 unused locations is an open question.
 
-[`LocationInterner`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/base_db/src/loc2id.rs#L65-L71
-[interners]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/db.rs#L22-L23
+[`LocationInterner`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/loc2id.rs#L65-L71
+[interners]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/db.rs#L22-L23
 
 For example, we use `LocationInterner` to assign IDs to definitions of functions,
 structs, enums, etc. The location, [`DefLoc`] contains two bits of information:
@@ -404,7 +404,7 @@ using offsets, text ranges or syntax trees as keys and values for queries. What
 we do instead is we store "index" of the item among all of the items of a file
 (so, a positional based ID, but localized to a single file).
 
-[`DefLoc`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L127-L139
+[`DefLoc`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L129-L139
 
 One thing we've glossed over for the time being is support for macros. We have
 only proof of concept handling of macros at the moment, but they are extremely
@@ -437,7 +437,7 @@ terms of `HirFileId`! This does not recur infinitely though: any chain of
 `HirFileId`s bottoms out in `HirFileId::FileId`, that is, some source file
 actually written by the user.
 
-[`HirFileId`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L18-L125
+[`HirFileId`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L31-L93
 
 Now that we understand how to identify a definition, in a source or in a
 macro-generated file, we can discuss name resolution a bit.
@@ -451,14 +451,13 @@ each module into a position-independent representation which does not change if
 we modify bodies of the items. After that we [loop] resolving all imports until
 we've reached a fixed point.
 
-[lower]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L113-L117
-[loop]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres.rs#L186-L196
-
+[lower]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L113-L147
+[loop]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres.rs#L186-L196
 And, given all our preparation with IDs and a position-independent representation,
 it is satisfying to [test] that typing inside function body does not invalidate
 name resolution results.
 
-[test]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/tests.rs#L376
+[test]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/tests.rs#L376
 
 An interesting fact about name resolution is that it "erases" all of the
 intermediate paths from the imports: in the end, we know which items are defined
@@ -493,10 +492,10 @@ there's an intermediate [projection query] which returns only the first
 position-independent part of the lowering. The result of this query is stable.
 Naturally, name resolution [uses] this stable projection query.
 
-[imports]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59
-[`SourceMap`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59
-[projection query]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L97-L103
-[uses]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/query_definitions.rs#L49
+[imports]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59
+[`SourceMap`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59
+[projection query]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L97-L103
+[uses]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/query_definitions.rs#L49
 
 ## Type inference
 
@@ -518,10 +517,10 @@ construct a mapping from `ExprId`s to types.
 
 [@flodiebold]: https://github.com/flodiebold
 [#327]: https://github.com/rust-lang/rust-analyzer/pull/327
-[lower the AST]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs
-[positional ID]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L13-L15
-[a source map]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L41-L44
-[type inference]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ty.rs#L1208-L1223
+[lower the AST]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs
+[positional ID]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L13-L15
+[a source map]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L41-L44
+[type inference]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ty.rs#L1208-L1223
 
 ## Tying it all together: completion
 
@@ -563,10 +562,11 @@ the type to completion.
 [catch]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442
 [the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps
 [ask analysis for completion]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L439-L444
-[completion implementation]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L46-L62
-[`CompletionContext`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L14-L37
-["IntelliJ Trick"]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L72-L75
-[find an ancestor `fn` node]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L116-L120
-[semantic model]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L123
-[series of independent completion routines]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L52-L59
-[`complete_dot`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/complete_dot.rs#L6-L22
+[ask analysis for completion]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L439-L444
+[completion implementation]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L46-L62
+[`CompletionContext`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L14-L37
+["IntelliJ Trick"]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L72-L75
+[find an ancestor `fn` node]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L116-L120
+[semantic model]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L123
+[series of independent completion routines]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L52-L59
+[`complete_dot`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/complete_dot.rs#L6-L22

From 8564da858d96aec33b9b08e18fb02a19c0eb3cde Mon Sep 17 00:00:00 2001
From: Ryo Yoshida 
Date: Tue, 1 Nov 2022 00:15:05 +0900
Subject: [PATCH 367/482] fix: disregard type variable expectation for if
 expressions

---
 .../crates/hir-ty/src/infer/expr.rs           |  1 +
 .../crates/hir-ty/src/tests/coercion.rs       | 33 +++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index f56108b26c45b..b1f4de8260775 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -85,6 +85,7 @@ impl<'a> InferenceContext<'a> {
         let ty = match &self.body[tgt_expr] {
             Expr::Missing => self.err_ty(),
             &Expr::If { condition, then_branch, else_branch } => {
+                let expected = &expected.adjust_for_branches(&mut self.table);
                 self.infer_expr(
                     condition,
                     &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
index d301595bcd98a..1abdb0be7f876 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
@@ -122,6 +122,23 @@ fn test() {
     )
 }
 
+#[test]
+fn if_else_adjust_for_branches_discard_type_var() {
+    check_no_mismatches(
+        r#"
+fn test() {
+    let f = || {
+        if true {
+            &""
+        } else {
+            ""
+        }
+    };
+}
+"#,
+    );
+}
+
 #[test]
 fn match_first_coerce() {
     check_no_mismatches(
@@ -182,6 +199,22 @@ fn test() {
     );
 }
 
+#[test]
+fn match_adjust_for_branches_discard_type_var() {
+    check_no_mismatches(
+        r#"
+fn test() {
+    let f = || {
+        match 0i32 {
+            0i32 => &"",
+            _ => "",
+        }
+    };
+}
+"#,
+    );
+}
+
 #[test]
 fn return_coerce_unknown() {
     check_types(

From 35453d2a678f6b41d48b5146d26442d256718a46 Mon Sep 17 00:00:00 2001
From: unexge 
Date: Sat, 29 Oct 2022 23:44:34 +0100
Subject: [PATCH 368/482] Record diverging match arms in `InferenceResult`

---
 .../rust-analyzer/crates/hir-ty/src/infer.rs      |  2 ++
 .../rust-analyzer/crates/hir-ty/src/infer/expr.rs |  5 +++++
 .../rust-analyzer/crates/hir/src/semantics.rs     |  8 ++++++++
 .../crates/hir/src/source_analyzer.rs             | 15 +++++++++++++++
 4 files changed, 30 insertions(+)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 0efff651cc174..6e63f69c2354d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -333,6 +333,8 @@ pub struct InferenceResult {
     assoc_resolutions: FxHashMap,
     pub diagnostics: Vec,
     pub type_of_expr: ArenaMap,
+    /// For each match expr, record diverging arm's expr.
+    pub diverging_arms: FxHashMap>,
     /// For each pattern record the type it resolves to.
     ///
     /// **Note**: When a pattern type is resolved it may still contain
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index b1f4de8260775..d08f5ac83001f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -376,6 +376,7 @@ impl<'a> InferenceContext<'a> {
 
                 let matchee_diverges = self.diverges;
                 let mut all_arms_diverge = Diverges::Always;
+                let mut diverging_arms = Vec::new();
 
                 for arm in arms.iter() {
                     self.diverges = Diverges::Maybe;
@@ -388,11 +389,15 @@ impl<'a> InferenceContext<'a> {
                     }
 
                     let arm_ty = self.infer_expr_inner(arm.expr, &expected);
+                    if self.diverges.is_always() {
+                        diverging_arms.push(arm.expr);
+                    }
                     all_arms_diverge &= self.diverges;
                     coerce.coerce(self, Some(arm.expr), &arm_ty);
                 }
 
                 self.diverges = matchee_diverges | all_arms_diverge;
+                self.result.diverging_arms.insert(tgt_expr, diverging_arms);
 
                 coerce.complete()
             }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 119ec3210e175..2f835657d37a1 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -481,6 +481,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
         self.imp.is_unsafe_ident_pat(ident_pat)
     }
+
+    pub fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option {
+        self.imp.is_diverging_match_arm(match_arm)
+    }
 }
 
 impl<'db> SemanticsImpl<'db> {
@@ -1421,6 +1425,10 @@ impl<'db> SemanticsImpl<'db> {
             .map(|ty| ty.original.is_packed(self.db))
             .unwrap_or(false)
     }
+
+    fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option {
+        self.analyze(match_arm.syntax())?.is_diverging_match_arm(self.db, match_arm)
+    }
 }
 
 fn macro_call_to_macro_id(
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index f86c571005367..2e61946a738de 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -782,6 +782,21 @@ impl SourceAnalyzer {
         false
     }
 
+    pub(crate) fn is_diverging_match_arm(
+        &self,
+        db: &dyn HirDatabase,
+        match_arm: &ast::MatchArm,
+    ) -> Option {
+        let infer = self.infer.as_ref()?;
+        let match_expr = match_arm.syntax().ancestors().find_map(ast::MatchExpr::cast)?;
+        let match_id = self.expr_id(db, &match_expr.into())?;
+        let diverging_arms = infer.diverging_arms.get(&match_id)?;
+        let match_arm_expr = match_arm.expr()?;
+        let match_arm_expr_id = self.expr_id(db, &match_arm_expr)?;
+
+        Some(diverging_arms.contains(&match_arm_expr_id))
+    }
+
     fn resolve_impl_method_or_trait_def(
         &self,
         db: &dyn HirDatabase,

From 04a899673808bd9c95ae64f4f5aa8864ec5f9595 Mon Sep 17 00:00:00 2001
From: unexge 
Date: Sun, 30 Oct 2022 00:00:53 +0100
Subject: [PATCH 369/482] Update auto generated tests

---
 .../crates/ide-assists/src/tests/generated.rs | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 2c4000efe0fa2..9df029748c050 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -407,6 +407,26 @@ fn main() {
     )
 }
 
+#[test]
+fn doctest_convert_match_to_let_else() {
+    check_doc_test(
+        "convert_match_to_let_else",
+        r#####"
+fn foo(opt: Option<()>) {
+    let val = $0match opt {
+        Some(it) => it,
+        None => return,
+    };
+}
+"#####,
+        r#####"
+fn foo(opt: Option<()>) {
+    let Some(val) = opt else { return };
+}
+"#####,
+    )
+}
+
 #[test]
 fn doctest_convert_named_struct_to_tuple_struct() {
     check_doc_test(

From c3f311136990d69cd3cf544b0f1593b376505b03 Mon Sep 17 00:00:00 2001
From: Jonas Schievink 
Date: Tue, 1 Nov 2022 17:18:17 +0100
Subject: [PATCH 370/482] Revert "Record diverging match arms in
 `InferenceResult`"

This reverts commit 319611b7382fc4c84170519dade68f4f558a44b1.
---
 .../rust-analyzer/crates/hir-ty/src/infer.rs      |  2 --
 .../rust-analyzer/crates/hir-ty/src/infer/expr.rs |  5 -----
 .../rust-analyzer/crates/hir/src/semantics.rs     |  8 --------
 .../crates/hir/src/source_analyzer.rs             | 15 ---------------
 4 files changed, 30 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 6e63f69c2354d..0efff651cc174 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -333,8 +333,6 @@ pub struct InferenceResult {
     assoc_resolutions: FxHashMap,
     pub diagnostics: Vec,
     pub type_of_expr: ArenaMap,
-    /// For each match expr, record diverging arm's expr.
-    pub diverging_arms: FxHashMap>,
     /// For each pattern record the type it resolves to.
     ///
     /// **Note**: When a pattern type is resolved it may still contain
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index d08f5ac83001f..b1f4de8260775 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -376,7 +376,6 @@ impl<'a> InferenceContext<'a> {
 
                 let matchee_diverges = self.diverges;
                 let mut all_arms_diverge = Diverges::Always;
-                let mut diverging_arms = Vec::new();
 
                 for arm in arms.iter() {
                     self.diverges = Diverges::Maybe;
@@ -389,15 +388,11 @@ impl<'a> InferenceContext<'a> {
                     }
 
                     let arm_ty = self.infer_expr_inner(arm.expr, &expected);
-                    if self.diverges.is_always() {
-                        diverging_arms.push(arm.expr);
-                    }
                     all_arms_diverge &= self.diverges;
                     coerce.coerce(self, Some(arm.expr), &arm_ty);
                 }
 
                 self.diverges = matchee_diverges | all_arms_diverge;
-                self.result.diverging_arms.insert(tgt_expr, diverging_arms);
 
                 coerce.complete()
             }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 2f835657d37a1..119ec3210e175 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -481,10 +481,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
         self.imp.is_unsafe_ident_pat(ident_pat)
     }
-
-    pub fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option {
-        self.imp.is_diverging_match_arm(match_arm)
-    }
 }
 
 impl<'db> SemanticsImpl<'db> {
@@ -1425,10 +1421,6 @@ impl<'db> SemanticsImpl<'db> {
             .map(|ty| ty.original.is_packed(self.db))
             .unwrap_or(false)
     }
-
-    fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option {
-        self.analyze(match_arm.syntax())?.is_diverging_match_arm(self.db, match_arm)
-    }
 }
 
 fn macro_call_to_macro_id(
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 2e61946a738de..f86c571005367 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -782,21 +782,6 @@ impl SourceAnalyzer {
         false
     }
 
-    pub(crate) fn is_diverging_match_arm(
-        &self,
-        db: &dyn HirDatabase,
-        match_arm: &ast::MatchArm,
-    ) -> Option {
-        let infer = self.infer.as_ref()?;
-        let match_expr = match_arm.syntax().ancestors().find_map(ast::MatchExpr::cast)?;
-        let match_id = self.expr_id(db, &match_expr.into())?;
-        let diverging_arms = infer.diverging_arms.get(&match_id)?;
-        let match_arm_expr = match_arm.expr()?;
-        let match_arm_expr_id = self.expr_id(db, &match_arm_expr)?;
-
-        Some(diverging_arms.contains(&match_arm_expr_id))
-    }
-
     fn resolve_impl_method_or_trait_def(
         &self,
         db: &dyn HirDatabase,

From d3d4c7ccf90e4df81c0558ea3aa6f13096430d3c Mon Sep 17 00:00:00 2001
From: koka 
Date: Sat, 29 Oct 2022 01:14:44 +0900
Subject: [PATCH 371/482] fix: async trait method for `unnecessary_async`

---
 .../src/handlers/unnecessary_async.rs         | 67 ++++++++++++++++++-
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
index d5cd2d551349d..44f8dbdef35c1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
@@ -1,12 +1,14 @@
+use hir::AssocItem;
 use ide_db::{
     assists::{AssistId, AssistKind},
     base_db::FileId,
     defs::Definition,
     search::FileReference,
     syntax_helpers::node_ext::full_path_of_name_ref,
+    traits::resolve_target_trait,
 };
 use syntax::{
-    ast::{self, NameLike, NameRef},
+    ast::{self, HasName, NameLike, NameRef},
     AstNode, SyntaxKind, TextRange,
 };
 
@@ -44,7 +46,16 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
     if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() {
         return None;
     }
-
+    // Do nothing if the method is an async member of trait.
+    if let Some(fname) = function.name() {
+        if let Some(trait_item) = find_corresponding_trait_member(ctx, fname.to_string()) {
+            if let AssocItem::Function(method) = trait_item {
+                if method.is_async(ctx.db()) {
+                    return None;
+                }
+            }
+        }
+    }
     // Remove the `async` keyword plus whitespace after it, if any.
     let async_range = {
         let async_token = function.async_token()?;
@@ -88,6 +99,23 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
     )
 }
 
+fn find_corresponding_trait_member(
+    ctx: &AssistContext<'_>,
+    function_name: String,
+) -> Option {
+    let impl_ = ctx.find_node_at_offset::()?;
+    let trait_ = resolve_target_trait(&ctx.sema, &impl_)?;
+
+    trait_
+        .items(ctx.db())
+        .iter()
+        .find(|item| match item.name(ctx.db()) {
+            Some(method_name) => method_name.to_string() == function_name,
+            _ => false,
+        })
+        .cloned()
+}
+
 fn find_all_references(
     ctx: &AssistContext<'_>,
     def: &Definition,
@@ -254,4 +282,39 @@ pub async fn f(s: &S) { s.f2() }"#,
     fn does_not_apply_when_not_on_prototype() {
         check_assist_not_applicable(unnecessary_async, "pub async fn f() { $0f2() }")
     }
+
+    #[test]
+    fn applies_on_unnecessary_async_on_trait_method() {
+        check_assist(
+            unnecessary_async,
+            r#"
+trait Trait {
+    fn foo();
+}
+impl Trait for () {
+    $0async fn foo() {}
+}"#,
+            r#"
+trait Trait {
+    fn foo();
+}
+impl Trait for () {
+    fn foo() {}
+}"#,
+        );
+    }
+
+    #[test]
+    fn does_not_apply_on_async_trait_method() {
+        check_assist_not_applicable(
+            unnecessary_async,
+            r#"
+trait Trait {
+    async fn foo();
+}
+impl Trait for () {
+    $0async fn foo() {}
+}"#,
+        );
+    }
 }

From 4d0da06594135d87fa9dc7061025c96f95a45b46 Mon Sep 17 00:00:00 2001
From: koka 
Date: Sun, 30 Oct 2022 00:57:42 +0900
Subject: [PATCH 372/482] Simplify the procedure

fix: remove unused import
---
 .../src/handlers/unnecessary_async.rs         | 55 ++-----------------
 1 file changed, 6 insertions(+), 49 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
index 44f8dbdef35c1..0439883225330 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
@@ -1,14 +1,12 @@
-use hir::AssocItem;
 use ide_db::{
     assists::{AssistId, AssistKind},
     base_db::FileId,
     defs::Definition,
     search::FileReference,
     syntax_helpers::node_ext::full_path_of_name_ref,
-    traits::resolve_target_trait,
 };
 use syntax::{
-    ast::{self, HasName, NameLike, NameRef},
+    ast::{self, NameLike, NameRef},
     AstNode, SyntaxKind, TextRange,
 };
 
@@ -46,16 +44,13 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
     if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() {
         return None;
     }
-    // Do nothing if the method is an async member of trait.
-    if let Some(fname) = function.name() {
-        if let Some(trait_item) = find_corresponding_trait_member(ctx, fname.to_string()) {
-            if let AssocItem::Function(method) = trait_item {
-                if method.is_async(ctx.db()) {
-                    return None;
-                }
-            }
+    // Do nothing if the method is a member of trait.
+    if let Some(impl_) = function.syntax().ancestors().nth(2).and_then(ast::Impl::cast) {
+        if let Some(_) = impl_.trait_() {
+            return None;
         }
     }
+
     // Remove the `async` keyword plus whitespace after it, if any.
     let async_range = {
         let async_token = function.async_token()?;
@@ -99,23 +94,6 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
     )
 }
 
-fn find_corresponding_trait_member(
-    ctx: &AssistContext<'_>,
-    function_name: String,
-) -> Option {
-    let impl_ = ctx.find_node_at_offset::()?;
-    let trait_ = resolve_target_trait(&ctx.sema, &impl_)?;
-
-    trait_
-        .items(ctx.db())
-        .iter()
-        .find(|item| match item.name(ctx.db()) {
-            Some(method_name) => method_name.to_string() == function_name,
-            _ => false,
-        })
-        .cloned()
-}
-
 fn find_all_references(
     ctx: &AssistContext<'_>,
     def: &Definition,
@@ -283,27 +261,6 @@ pub async fn f(s: &S) { s.f2() }"#,
         check_assist_not_applicable(unnecessary_async, "pub async fn f() { $0f2() }")
     }
 
-    #[test]
-    fn applies_on_unnecessary_async_on_trait_method() {
-        check_assist(
-            unnecessary_async,
-            r#"
-trait Trait {
-    fn foo();
-}
-impl Trait for () {
-    $0async fn foo() {}
-}"#,
-            r#"
-trait Trait {
-    fn foo();
-}
-impl Trait for () {
-    fn foo() {}
-}"#,
-        );
-    }
-
     #[test]
     fn does_not_apply_on_async_trait_method() {
         check_assist_not_applicable(

From 6f07907c4a20c4a1ced5ecfc7d3302377994b57c Mon Sep 17 00:00:00 2001
From: Jonas Schievink 
Date: Tue, 1 Nov 2022 16:33:59 +0100
Subject: [PATCH 373/482] Create `Callable`s for generic types implementing
 `FnOnce`

---
 .../rust-analyzer/crates/hir-ty/src/infer.rs  |  2 +-
 .../rust-analyzer/crates/hir-ty/src/lib.rs    | 69 ++++++++++++++++++-
 src/tools/rust-analyzer/crates/hir/src/lib.rs | 16 ++++-
 .../crates/ide/src/signature_help.rs          | 27 ++++++--
 4 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 0efff651cc174..0b3c23f5747ad 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -1020,7 +1020,7 @@ impl Expectation {
     /// The primary use case is where the expected type is a fat pointer,
     /// like `&[isize]`. For example, consider the following statement:
     ///
-    ///    let x: &[isize] = &[1, 2, 3];
+    ///     let x: &[isize] = &[1, 2, 3];
     ///
     /// In this case, the expected type for the `&[1, 2, 3]` expression is
     /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 42c3b58d5ada5..2b5989c6c6f03 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -38,10 +38,12 @@ use std::sync::Arc;
 use chalk_ir::{
     fold::{Shift, TypeFoldable},
     interner::HasInterner,
-    NoSolution,
+    NoSolution, UniverseIndex,
 };
 use hir_def::{expr::ExprId, type_ref::Rawness, TypeOrConstParamId};
+use hir_expand::name;
 use itertools::Either;
+use traits::FnTrait;
 use utils::Generics;
 
 use crate::{consteval::unknown_const, db::HirDatabase, utils::generics};
@@ -508,3 +510,68 @@ where
     });
     Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) }
 }
+
+pub fn callable_sig_from_fnonce(
+    self_ty: &Canonical,
+    env: Arc,
+    db: &dyn HirDatabase,
+) -> Option {
+    let krate = env.krate;
+    let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
+    let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
+
+    let mut kinds = self_ty.binders.interned().to_vec();
+    let b = TyBuilder::trait_ref(db, fn_once_trait);
+    if b.remaining() != 2 {
+        return None;
+    }
+    let fn_once = b
+        .push(self_ty.value.clone())
+        .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
+        .build();
+    kinds.extend(fn_once.substitution.iter(Interner).skip(1).map(|x| {
+        let vk = match x.data(Interner) {
+            chalk_ir::GenericArgData::Ty(_) => {
+                chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
+            }
+            chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
+            chalk_ir::GenericArgData::Const(c) => {
+                chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
+            }
+        };
+        chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
+    }));
+
+    // FIXME: chalk refuses to solve `>::Output == ^0.1`, so we first solve
+    // `>` and then replace `^0.0` with the concrete argument tuple.
+    let trait_env = env.env.clone();
+    let obligation = InEnvironment { goal: fn_once.cast(Interner), environment: trait_env };
+    let canonical =
+        Canonical { binders: CanonicalVarKinds::from_iter(Interner, kinds), value: obligation };
+    let subst = match db.trait_solve(krate, canonical) {
+        Some(Solution::Unique(vars)) => vars.value.subst,
+        _ => return None,
+    };
+    let args = subst.at(Interner, self_ty.binders.interned().len()).ty(Interner)?;
+    let params = match args.kind(Interner) {
+        chalk_ir::TyKind::Tuple(_, subst) => {
+            subst.iter(Interner).filter_map(|arg| arg.ty(Interner).cloned()).collect::>()
+        }
+        _ => return None,
+    };
+    if params.iter().any(|ty| ty.is_unknown()) {
+        return None;
+    }
+
+    let fn_once = TyBuilder::trait_ref(db, fn_once_trait)
+        .push(self_ty.value.clone())
+        .push(args.clone())
+        .build();
+    let projection =
+        TyBuilder::assoc_type_projection(db, output_assoc_type, Some(fn_once.substitution.clone()))
+            .build();
+
+    let ret_ty = db.normalize_projection(projection, env);
+
+    Some(CallableSig::from_params_and_return(params, ret_ty.clone(), false))
+}
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index f5324208c9a4e..cbd9bf32a5486 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -2995,7 +2995,17 @@ impl Type {
         let callee = match self.ty.kind(Interner) {
             TyKind::Closure(id, _) => Callee::Closure(*id),
             TyKind::Function(_) => Callee::FnPtr,
-            _ => Callee::Def(self.ty.callable_def(db)?),
+            TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?),
+            _ => {
+                let ty = hir_ty::replace_errors_with_variables(&self.ty);
+                let sig = hir_ty::callable_sig_from_fnonce(&ty, self.env.clone(), db)?;
+                return Some(Callable {
+                    ty: self.clone(),
+                    sig,
+                    callee: Callee::Other,
+                    is_bound_method: false,
+                });
+            }
         };
 
         let sig = self.ty.callable_sig(db)?;
@@ -3464,6 +3474,7 @@ enum Callee {
     Def(CallableDefId),
     Closure(ClosureId),
     FnPtr,
+    Other,
 }
 
 pub enum CallableKind {
@@ -3472,6 +3483,8 @@ pub enum CallableKind {
     TupleEnumVariant(Variant),
     Closure,
     FnPtr,
+    /// Some other type that implements `FnOnce`.
+    Other,
 }
 
 impl Callable {
@@ -3483,6 +3496,7 @@ impl Callable {
             Def(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
             Closure(_) => CallableKind::Closure,
             FnPtr => CallableKind::FnPtr,
+            Other => CallableKind::Other,
         }
     }
     pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option {
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
index fedc1a4358272..7486b20293a66 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -149,7 +149,7 @@ fn signature_help_for_call(
                 variant.name(db)
             );
         }
-        hir::CallableKind::Closure | hir::CallableKind::FnPtr => (),
+        hir::CallableKind::Closure | hir::CallableKind::FnPtr | hir::CallableKind::Other => (),
     }
 
     res.signature.push('(');
@@ -189,9 +189,10 @@ fn signature_help_for_call(
         hir::CallableKind::Function(func) if callable.return_type().contains_unknown() => {
             render(func.ret_type(db))
         }
-        hir::CallableKind::Function(_) | hir::CallableKind::Closure | hir::CallableKind::FnPtr => {
-            render(callable.return_type())
-        }
+        hir::CallableKind::Function(_)
+        | hir::CallableKind::Closure
+        | hir::CallableKind::FnPtr
+        | hir::CallableKind::Other => render(callable.return_type()),
         hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {}
     }
     Some(res)
@@ -387,10 +388,9 @@ mod tests {
     }
 
     fn check(ra_fixture: &str, expect: Expect) {
-        // Implicitly add `Sized` to avoid noisy `T: ?Sized` in the results.
         let fixture = format!(
             r#"
-#[lang = "sized"] trait Sized {{}}
+//- minicore: sized, fn
 {ra_fixture}
             "#
         );
@@ -1331,4 +1331,19 @@ fn f() {
             "#]],
         );
     }
+
+    #[test]
+    fn help_for_generic_call() {
+        check(
+            r#"
+fn f i32>(f: F) {
+    f($0)
+}
+"#,
+            expect![[r#"
+                (u8, u16) -> i32
+                 ^^  ---
+            "#]],
+        );
+    }
 }

From b74fb9fa0f5a9b5ab3afab350afbd216c15b108d Mon Sep 17 00:00:00 2001
From: feniljain 
Date: Sun, 30 Oct 2022 14:55:44 +0530
Subject: [PATCH 374/482] fix: make custom expr prefix completions to
 understand refs

---
 .../ide-completion/src/completions/postfix.rs | 29 ++++++++++++++++---
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index 9a891cea2d458..b9bd47f7da504 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -69,10 +69,6 @@ pub(crate) fn complete_postfix(
         }
     }
 
-    if !ctx.config.snippets.is_empty() {
-        add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
-    }
-
     let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
     if let Some(try_enum) = &try_enum {
         match try_enum {
@@ -140,6 +136,10 @@ pub(crate) fn complete_postfix(
         None => return,
     };
 
+    if !ctx.config.snippets.is_empty() {
+        add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
+    }
+
     match try_enum {
         Some(try_enum) => match try_enum {
             TryEnum::Result => {
@@ -613,4 +613,25 @@ fn main() {
             r#"fn main() { log::error!("{}", 2+2) }"#,
         );
     }
+
+    #[test]
+    fn postfix_custom_snippets_completion_for_references() {
+        check_edit_with_config(
+            CompletionConfig {
+                snippets: vec![Snippet::new(
+                    &[],
+                    &["ok".into()],
+                    &["Ok(${receiver})".into()],
+                    "",
+                    &[],
+                    crate::SnippetScope::Expr,
+                )
+                .unwrap()],
+                ..TEST_CONFIG
+            },
+            "ok",
+            r#"fn main() { &&42.$0 }"#,
+            r#"fn main() { Ok(&&42) }"#,
+        );
+    }
 }

From 6a2c253693917e84e96b4a9282b1a411ccc593f3 Mon Sep 17 00:00:00 2001
From: feniljain 
Date: Fri, 7 Oct 2022 00:11:02 +0530
Subject: [PATCH 375/482] feat: add config for inserting must_use in
 `generate_enum_as_method`

---
 .../crates/ide-assists/src/assist_config.rs   |  1 +
 .../generate_enum_projection_method.rs        | 27 +++++++++++++++----
 .../crates/ide-assists/src/tests.rs           |  1 +
 .../crates/rust-analyzer/src/config.rs        |  4 +++
 .../docs/user/generated_config.adoc           |  6 +++++
 .../rust-analyzer/editors/code/package.json   |  5 ++++
 6 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
index 60d1588a44e54..b273ebc85a506 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
@@ -14,4 +14,5 @@ pub struct AssistConfig {
     pub allowed: Option>,
     pub insert_use: InsertUseConfig,
     pub prefer_no_std: bool,
+    pub assist_emit_must_use: bool,
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
index bdd3cf4f06c25..fc8b5c9d20905 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
@@ -124,6 +124,7 @@ fn generate_enum_projection_method(
         happy_case,
         sad_case,
     } = props;
+
     let variant = ctx.find_node_at_offset::()?;
     let variant_name = variant.name()?;
     let parent_enum = ast::Adt::Enum(variant.parent_enum());
@@ -144,7 +145,7 @@ fn generate_enum_projection_method(
         ast::StructKind::Unit => return None,
     };
 
-    let fn_name = format!("{}_{}", fn_name_prefix, &to_lower_snake_case(&variant_name.text()));
+    let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text()));
 
     // Return early if we've found an existing new fn
     let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?;
@@ -156,15 +157,31 @@ fn generate_enum_projection_method(
         assist_description,
         target,
         |builder| {
-            let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{v} "));
-            let method = format!(
-                "    {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type}{return_suffix} {{
+            let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
+
+            let field_type_syntax = field_type.syntax();
+
+            let method = if ctx.config.assist_emit_must_use
+            {
+                format!(
+                    "    #[must_use]
+    {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
+        if let Self::{variant_name}{pattern_suffix} = self {{
+            {happy_case}({bound_name})
+        }} else {{
+            {sad_case}
+        }}
+    }}")
+            } else {
+                format!(
+                    "    {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
         if let Self::{variant_name}{pattern_suffix} = self {{
             {happy_case}({bound_name})
         }} else {{
             {sad_case}
         }}
-    }}");
+    }}")
+            };
 
             add_method_to_adt(builder, &parent_enum, impl_def, &method);
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
index f7f2417d0745d..92ced27c78aed 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
@@ -30,6 +30,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
         skip_glob_imports: true,
     },
     prefer_no_std: false,
+    assist_emit_must_use: false,
 };
 
 pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 85322f12a834c..4bbb4443ef79f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -56,6 +56,9 @@ mod patch_old_style;
 // parsing the old name.
 config_data! {
     struct ConfigData {
+        /// Whether to insert must_use derive macro while generating `as_` methods
+        /// for enum variants.
+        assist_emitMustUse: bool               = "false",
         /// Placeholder expression to use for missing expressions in assists.
         assist_expressionFillDefault: ExprFillDefaultDef              = "\"todo\"",
 
@@ -1276,6 +1279,7 @@ impl Config {
             allowed: None,
             insert_use: self.insert_use_config(),
             prefer_no_std: self.data.imports_prefer_no_std,
+            assist_emit_must_use: self.data.assist_emitMustUse,
         }
     }
 
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index 502833de72c16..1000e7222e06e 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -1,3 +1,9 @@
+[[rust-analyzer.assist.emitMustUse]]rust-analyzer.assist.emitMustUse (default: `false`)::
++
+--
+Whether to insert must_use derive macro while generating `as_` methods
+for enum variants.
+--
 [[rust-analyzer.assist.expressionFillDefault]]rust-analyzer.assist.expressionFillDefault (default: `"todo"`)::
 +
 --
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 6771cad28a792..721a92e77150d 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -397,6 +397,11 @@
                     "type": "boolean"
                 },
                 "$generated-start": {},
+                "rust-analyzer.assist.emitMustUse": {
+                    "markdownDescription": "Whether to insert must_use derive macro while generating `as_` methods\nfor enum variants.",
+                    "default": false,
+                    "type": "boolean"
+                },
                 "rust-analyzer.assist.expressionFillDefault": {
                     "markdownDescription": "Placeholder expression to use for missing expressions in assists.",
                     "default": "todo",

From 2633fd9f6e5f6d06b13fd7a333a494c71f882a4d Mon Sep 17 00:00:00 2001
From: feniljain 
Date: Mon, 24 Oct 2022 21:06:32 +0530
Subject: [PATCH 376/482] refactor: remove repetitive string interpolation and
 doc changes

---
 .../generate_enum_projection_method.rs        | 24 +++++++------------
 .../crates/rust-analyzer/src/config.rs        |  2 +-
 .../docs/user/generated_config.adoc           |  2 +-
 .../rust-analyzer/editors/code/package.json   |  2 +-
 4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
index fc8b5c9d20905..96e8fece45c34 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
@@ -161,27 +161,21 @@ fn generate_enum_projection_method(
 
             let field_type_syntax = field_type.syntax();
 
-            let method = if ctx.config.assist_emit_must_use
-            {
-                format!(
-                    "    #[must_use]
-    {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
-        if let Self::{variant_name}{pattern_suffix} = self {{
-            {happy_case}({bound_name})
-        }} else {{
-            {sad_case}
-        }}
-    }}")
+            let must_use = if ctx.config.assist_emit_must_use {
+                "#[must_use]\n"
             } else {
-                format!(
-                    "    {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
+                ""
+            };
+
+            let method = format!(
+                "    {must_use}{vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
         if let Self::{variant_name}{pattern_suffix} = self {{
             {happy_case}({bound_name})
         }} else {{
             {sad_case}
         }}
-    }}")
-            };
+    }}"
+            );
 
             add_method_to_adt(builder, &parent_enum, impl_def, &method);
         },
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 4bbb4443ef79f..e60d4f4f76541 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -56,7 +56,7 @@ mod patch_old_style;
 // parsing the old name.
 config_data! {
     struct ConfigData {
-        /// Whether to insert must_use derive macro while generating `as_` methods
+        /// Whether to insert #[must_use] when generating `as_` methods
         /// for enum variants.
         assist_emitMustUse: bool               = "false",
         /// Placeholder expression to use for missing expressions in assists.
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index 1000e7222e06e..36794efe42726 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -1,7 +1,7 @@
 [[rust-analyzer.assist.emitMustUse]]rust-analyzer.assist.emitMustUse (default: `false`)::
 +
 --
-Whether to insert must_use derive macro while generating `as_` methods
+Whether to insert #[must_use] when generating `as_` methods
 for enum variants.
 --
 [[rust-analyzer.assist.expressionFillDefault]]rust-analyzer.assist.expressionFillDefault (default: `"todo"`)::
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 721a92e77150d..0ff66527451d3 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -398,7 +398,7 @@
                 },
                 "$generated-start": {},
                 "rust-analyzer.assist.emitMustUse": {
-                    "markdownDescription": "Whether to insert must_use derive macro while generating `as_` methods\nfor enum variants.",
+                    "markdownDescription": "Whether to insert #[must_use] when generating `as_` methods\nfor enum variants.",
                     "default": false,
                     "type": "boolean"
                 },

From 263650bf0eedf76d5eb4d09366f7cef48fc027da Mon Sep 17 00:00:00 2001
From: feniljain <49019259+feniljain@users.noreply.github.com>
Date: Wed, 2 Nov 2022 16:09:12 +0530
Subject: [PATCH 377/482] fix: indentation after inserting `#must_use`

Co-authored-by: Lukas Wirth 
---
 .../ide-assists/src/handlers/generate_enum_projection_method.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
index 96e8fece45c34..c9aa41c845ad5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
@@ -162,7 +162,7 @@ fn generate_enum_projection_method(
             let field_type_syntax = field_type.syntax();
 
             let must_use = if ctx.config.assist_emit_must_use {
-                "#[must_use]\n"
+                "#[must_use]\n    "
             } else {
                 ""
             };

From bd2ad66dd5014a4b7855179d36bbb8bedfbe4e4f Mon Sep 17 00:00:00 2001
From: unexge 
Date: Tue, 1 Nov 2022 23:02:10 +0000
Subject: [PATCH 378/482] Use let-else statements in `Convert to guarded
 return` assist

---
 .../src/handlers/convert_to_guarded_return.rs | 70 +++++--------------
 .../crates/syntax/src/ast/make.rs             | 20 ++++++
 2 files changed, 36 insertions(+), 54 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
index cb75619ced9c3..b97be34c5f7e4 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -129,32 +129,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
                 }
                 Some((path, bound_ident)) => {
                     // If-let.
-                    let match_expr = {
-                        let happy_arm = {
-                            let pat = make::tuple_struct_pat(
-                                path,
-                                once(make::ext::simple_ident_pat(make::name("it")).into()),
-                            );
-                            let expr = {
-                                let path = make::ext::ident_path("it");
-                                make::expr_path(path)
-                            };
-                            make::match_arm(once(pat.into()), None, expr)
-                        };
-
-                        let sad_arm = make::match_arm(
-                            // FIXME: would be cool to use `None` or `Err(_)` if appropriate
-                            once(make::wildcard_pat().into()),
-                            None,
-                            early_expression,
-                        );
-
-                        make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm]))
-                    };
-
-                    let let_stmt = make::let_stmt(bound_ident, None, Some(match_expr));
-                    let let_stmt = let_stmt.indent(if_indent_level);
-                    let_stmt.syntax().clone_for_update()
+                    let pat = make::tuple_struct_pat(path, once(bound_ident));
+                    let let_else_stmt = make::let_else_stmt(
+                        pat.into(),
+                        None,
+                        cond_expr,
+                        ast::make::tail_only_block_expr(early_expression),
+                    );
+                    let let_else_stmt = let_else_stmt.indent(if_indent_level);
+                    let_else_stmt.syntax().clone_for_update()
                 }
             };
 
@@ -238,10 +221,7 @@ fn main(n: Option) {
             r#"
 fn main(n: Option) {
     bar();
-    let n = match n {
-        Some(it) => it,
-        _ => return,
-    };
+    let Some(n) = n else { return };
     foo(n);
 
     // comment
@@ -264,10 +244,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    let x = match Err(92) {
-        Ok(it) => it,
-        _ => return,
-    };
+    let Ok(x) = Err(92) else { return };
     foo(x);
 }
 "#,
@@ -292,10 +269,7 @@ fn main(n: Option) {
             r#"
 fn main(n: Option) {
     bar();
-    let n = match n {
-        Some(it) => it,
-        _ => return,
-    };
+    let Some(n) = n else { return };
     foo(n);
 
     // comment
@@ -323,10 +297,7 @@ fn main(n: Option) {
             r#"
 fn main(n: Option) {
     bar();
-    let mut n = match n {
-        Some(it) => it,
-        _ => return,
-    };
+    let Some(mut n) = n else { return };
     foo(n);
 
     // comment
@@ -354,10 +325,7 @@ fn main(n: Option<&str>) {
             r#"
 fn main(n: Option<&str>) {
     bar();
-    let ref n = match n {
-        Some(it) => it,
-        _ => return,
-    };
+    let Some(ref n) = n else { return };
     foo(n);
 
     // comment
@@ -412,10 +380,7 @@ fn main() {
             r#"
 fn main() {
     while true {
-        let n = match n {
-            Some(it) => it,
-            _ => continue,
-        };
+        let Some(n) = n else { continue };
         foo(n);
         bar();
     }
@@ -469,10 +434,7 @@ fn main() {
             r#"
 fn main() {
     loop {
-        let n = match n {
-            Some(it) => it,
-            _ => continue,
-        };
+        let Some(n) = n else { continue };
         foo(n);
         bar();
     }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 4057a75e7c1e6..8c26009add2bb 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -334,6 +334,10 @@ pub fn block_expr(
     ast_from_text(&format!("fn f() {buf}"))
 }
 
+pub fn tail_only_block_expr(tail_expr: ast::Expr) -> ast::BlockExpr {
+    ast_from_text(&format!("fn f() {{ {tail_expr} }}"))
+}
+
 /// Ideally this function wouldn't exist since it involves manual indenting.
 /// It differs from `make::block_expr` by also supporting comments.
 ///
@@ -656,6 +660,22 @@ pub fn let_stmt(
     };
     ast_from_text(&format!("fn f() {{ {text} }}"))
 }
+
+pub fn let_else_stmt(
+    pattern: ast::Pat,
+    ty: Option,
+    expr: ast::Expr,
+    diverging: ast::BlockExpr,
+) -> ast::LetStmt {
+    let mut text = String::new();
+    format_to!(text, "let {pattern}");
+    if let Some(ty) = ty {
+        format_to!(text, ": {ty}");
+    }
+    format_to!(text, " = {expr} else {diverging};");
+    ast_from_text(&format!("fn f() {{ {text} }}"))
+}
+
 pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
     let semi = if expr.is_block_like() { "" } else { ";" };
     ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))

From 08a81df5d7e6943387ef3351bca5be98ac878324 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= 
Date: Wed, 2 Nov 2022 14:50:04 +0200
Subject: [PATCH 379/482] Bump ovsx

---
 .../rust-analyzer/editors/code/package-lock.json   | 14 +++++++-------
 src/tools/rust-analyzer/editors/code/package.json  |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index a72865d4fe44e..0b25564e28d37 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -23,7 +23,7 @@
                 "esbuild": "^0.14.48",
                 "eslint": "^8.19.0",
                 "eslint-config-prettier": "^8.5.0",
-                "ovsx": "^0.5.1",
+                "ovsx": "^0.5.2",
                 "prettier": "^2.7.1",
                 "tslib": "^2.4.0",
                 "typescript": "^4.7.4",
@@ -2874,9 +2874,9 @@
             }
         },
         "node_modules/ovsx": {
-            "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.1.tgz",
-            "integrity": "sha512-3OWq0l7DuVHi2bd2aQe5+QVQlFIqvrcw3/2vGXL404L6Tr+R4QHtzfnYYghv8CCa85xJHjU0RhcaC7pyXkAUbg==",
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.2.tgz",
+            "integrity": "sha512-UbLultRCk46WddeA0Cly4hoRhzBJUiLgbIEViXlgOvV54LbsppClDkMLoCevUUBHoiNdMX2NuiSgURAEXgCZdw==",
             "dev": true,
             "dependencies": {
                 "commander": "^6.1.0",
@@ -5958,9 +5958,9 @@
             }
         },
         "ovsx": {
-            "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.1.tgz",
-            "integrity": "sha512-3OWq0l7DuVHi2bd2aQe5+QVQlFIqvrcw3/2vGXL404L6Tr+R4QHtzfnYYghv8CCa85xJHjU0RhcaC7pyXkAUbg==",
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.2.tgz",
+            "integrity": "sha512-UbLultRCk46WddeA0Cly4hoRhzBJUiLgbIEViXlgOvV54LbsppClDkMLoCevUUBHoiNdMX2NuiSgURAEXgCZdw==",
             "dev": true,
             "requires": {
                 "commander": "^6.1.0",
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 0ff66527451d3..8e8b59159db92 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -49,7 +49,7 @@
         "esbuild": "^0.14.48",
         "eslint": "^8.19.0",
         "eslint-config-prettier": "^8.5.0",
-        "ovsx": "^0.5.1",
+        "ovsx": "^0.5.2",
         "prettier": "^2.7.1",
         "tslib": "^2.4.0",
         "typescript": "^4.7.4",

From af2501763d85e494171cdf6f836d474e8697d3a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= 
Date: Thu, 3 Nov 2022 15:42:55 +0200
Subject: [PATCH 380/482] Allow ovsx publishing to fail

---
 src/tools/rust-analyzer/.github/workflows/release.yaml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
index 422fe29f9d5c3..b070dd3406f20 100644
--- a/src/tools/rust-analyzer/.github/workflows/release.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -257,8 +257,7 @@ jobs:
       - name: Publish Extension (OpenVSX, release)
         if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        # token from https://dev.azure.com/rust-analyzer/
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix || true
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
         timeout-minutes: 2
 
       - name: Publish Extension (Code Marketplace, nightly)
@@ -269,5 +268,5 @@ jobs:
       - name: Publish Extension (OpenVSX, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix || true
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
         timeout-minutes: 2

From dc196197f3afcf960f8fcdf3eb2be1cf5263b978 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= 
Date: Sat, 22 Oct 2022 15:10:03 +0200
Subject: [PATCH 381/482] ide: Generate monikers for local crates.

---
 .../rust-analyzer/crates/ide/src/moniker.rs   | 28 ++++++-------
 .../crates/rust-analyzer/src/cli/lsif.rs      |  6 +--
 .../crates/rust-analyzer/src/cli/scip.rs      | 40 ++++++++++++++++++-
 3 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 852a8fd837616..07d117aff10bd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -73,8 +73,8 @@ impl MonikerResult {
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PackageInformation {
     pub name: String,
-    pub repo: String,
-    pub version: String,
+    pub repo: Option,
+    pub version: Option,
 }
 
 pub(crate) fn crate_for_file(db: &RootDatabase, file_id: FileId) -> Option {
@@ -256,18 +256,18 @@ pub(crate) fn def_to_moniker(
             let (name, repo, version) = match krate.origin(db) {
                 CrateOrigin::CratesIo { repo, name } => (
                     name.unwrap_or(krate.display_name(db)?.canonical_name().to_string()),
-                    repo?,
-                    krate.version(db)?,
+                    repo,
+                    krate.version(db),
                 ),
                 CrateOrigin::Lang(lang) => (
                     krate.display_name(db)?.canonical_name().to_string(),
-                    "https://github.com/rust-lang/rust/".to_string(),
-                    match lang {
+                    Some("https://github.com/rust-lang/rust/".to_string()),
+                    Some(match lang {
                         LangCrateOrigin::Other => {
                             "https://github.com/rust-lang/rust/library/".into()
                         }
                         lang => format!("https://github.com/rust-lang/rust/library/{lang}",),
-                    },
+                    }),
                 ),
             };
             PackageInformation { name, repo, version }
@@ -315,7 +315,7 @@ pub mod module {
 }
 "#,
             "foo::module::func",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Import,
         );
         check_moniker(
@@ -331,7 +331,7 @@ pub mod module {
 }
 "#,
             "foo::module::func",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Export,
         );
     }
@@ -348,7 +348,7 @@ pub mod module {
 }
 "#,
             "foo::module::MyTrait::func",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Export,
         );
     }
@@ -365,7 +365,7 @@ pub mod module {
 }
 "#,
             "foo::module::MyTrait::MY_CONST",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Export,
         );
     }
@@ -382,7 +382,7 @@ pub mod module {
 }
 "#,
             "foo::module::MyTrait::MyType",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Export,
         );
     }
@@ -405,7 +405,7 @@ pub mod module {
 }
 "#,
             "foo::module::MyStruct::MyTrait::func",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Export,
         );
     }
@@ -425,7 +425,7 @@ pub struct St {
 }
 "#,
             "foo::St::a",
-            r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+            r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
             MonikerKind::Import,
         );
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
index 748306ea57d4e..76abe65898075 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
@@ -106,12 +106,12 @@ impl LsifManager<'_> {
                 manager: "cargo".to_string(),
                 uri: None,
                 content: None,
-                repository: Some(lsif::Repository {
-                    url: pi.repo,
+                repository: pi.repo.map(|url| lsif::Repository {
+                    url,
                     r#type: "git".to_string(),
                     commit_id: None,
                 }),
-                version: Some(pi.version),
+                version: pi.version,
             }));
         self.package_map.insert(package_information, result_set_id);
         result_set_id
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index 8b77ccde0ee4a..b03f085d692e6 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -231,7 +231,7 @@ fn token_to_symbol(token: &TokenStaticData) -> Option {
         package: Some(scip_types::Package {
             manager: "cargo".to_string(),
             name: package_name,
-            version,
+            version: version.unwrap_or_else(|| ".".to_string()),
             ..Default::default()
         })
         .into(),
@@ -415,4 +415,42 @@ pub mod module {
             "",
         );
     }
+
+    #[test]
+    fn global_symbol_for_pub_struct() {
+        check_symbol(
+            r#"
+    //- /lib.rs crate:main
+    mod foo;
+
+    fn main() {
+        let _bar = foo::Bar { i: 0 };
+    }
+    //- /foo.rs
+    pub struct Bar$0 {
+        pub i: i32,
+    }
+    "#,
+            "rust-analyzer cargo main . foo/Bar#",
+        );
+    }
+
+    #[test]
+    fn global_symbol_for_pub_struct_reference() {
+        check_symbol(
+            r#"
+    //- /lib.rs crate:main
+    mod foo;
+
+    fn main() {
+        let _bar = foo::Bar$0 { i: 0 };
+    }
+    //- /foo.rs
+    pub struct Bar {
+        pub i: i32,
+    }
+    "#,
+            "rust-analyzer cargo main . foo/Bar#",
+        );
+    }
 }

From ab20d3802973947aeaaf87e5cbd4c81ee56b4da9 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Fri, 4 Nov 2022 21:07:15 +0100
Subject: [PATCH 382/482] Lower unsafety of fn pointer and fn item types

---
 .../crates/hir-def/src/pretty.rs              |  5 ++++-
 .../crates/hir-def/src/type_ref.rs            |  6 +++---
 .../crates/hir-ty/src/display.rs              |  7 +++++--
 .../rust-analyzer/crates/hir-ty/src/lib.rs    | 21 ++++++++++++++-----
 .../rust-analyzer/crates/hir-ty/src/lower.rs  | 19 ++++++++++++-----
 .../crates/hir-ty/src/tests/coercion.rs       |  7 +++++--
 6 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
index 6636c8a23ca5f..933970d10e472 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
@@ -143,9 +143,12 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re
             print_type_ref(elem, buf)?;
             write!(buf, "]")?;
         }
-        TypeRef::Fn(args_and_ret, varargs) => {
+        TypeRef::Fn(args_and_ret, varargs, is_unsafe) => {
             let ((_, return_type), args) =
                 args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
+            if *is_unsafe {
+                write!(buf, "unsafe ")?;
+            }
             write!(buf, "fn(")?;
             for (i, (_, typeref)) in args.iter().enumerate() {
                 if i != 0 {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
index 5b4c71be7fb83..f8bb78ddcfe02 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
@@ -119,7 +119,7 @@ pub enum TypeRef {
     Array(Box, ConstScalarOrPath),
     Slice(Box),
     /// A fn pointer. Last element of the vector is the return type.
-    Fn(Vec<(Option, TypeRef)>, bool /*varargs*/),
+    Fn(Vec<(Option, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
     ImplTrait(Vec>),
     DynTrait(Vec>),
     Macro(AstId),
@@ -229,7 +229,7 @@ impl TypeRef {
                     Vec::new()
                 };
                 params.push((None, ret_ty));
-                TypeRef::Fn(params, is_varargs)
+                TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some())
             }
             // for types are close enough for our purposes to the inner type for now...
             ast::Type::ForType(inner) => TypeRef::from_ast_opt(ctx, inner.ty()),
@@ -263,7 +263,7 @@ impl TypeRef {
         fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
             f(type_ref);
             match type_ref {
-                TypeRef::Fn(params, _) => {
+                TypeRef::Fn(params, _, _) => {
                     params.iter().for_each(|(_, param_type)| go(param_type, f))
                 }
                 TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 5ad6613263534..a22a4b170f61c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1187,8 +1187,11 @@ impl HirDisplay for TypeRef {
                 inner.hir_fmt(f)?;
                 write!(f, "]")?;
             }
-            TypeRef::Fn(parameters, is_varargs) => {
+            &TypeRef::Fn(ref parameters, is_varargs, is_unsafe) => {
                 // FIXME: Function pointer qualifiers.
+                if is_unsafe {
+                    write!(f, "unsafe ")?;
+                }
                 write!(f, "fn(")?;
                 if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
                     for index in 0..function_parameters.len() {
@@ -1203,7 +1206,7 @@ impl HirDisplay for TypeRef {
                             write!(f, ", ")?;
                         }
                     }
-                    if *is_varargs {
+                    if is_varargs {
                         write!(f, "{}...", if parameters.len() == 1 { "" } else { ", " })?;
                     }
                     write!(f, ")")?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 2b5989c6c6f03..b68c764bdca09 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -210,6 +210,7 @@ pub(crate) fn make_binders>(
 pub struct CallableSig {
     params_and_return: Arc<[Ty]>,
     is_varargs: bool,
+    safety: Safety,
 }
 
 has_interner!(CallableSig);
@@ -218,9 +219,14 @@ has_interner!(CallableSig);
 pub type PolyFnSig = Binders;
 
 impl CallableSig {
-    pub fn from_params_and_return(mut params: Vec, ret: Ty, is_varargs: bool) -> CallableSig {
+    pub fn from_params_and_return(
+        mut params: Vec,
+        ret: Ty,
+        is_varargs: bool,
+        safety: Safety,
+    ) -> CallableSig {
         params.push(ret);
-        CallableSig { params_and_return: params.into(), is_varargs }
+        CallableSig { params_and_return: params.into(), is_varargs, safety }
     }
 
     pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
@@ -237,13 +243,14 @@ impl CallableSig {
                 .map(|arg| arg.assert_ty_ref(Interner).clone())
                 .collect(),
             is_varargs: fn_ptr.sig.variadic,
+            safety: fn_ptr.sig.safety,
         }
     }
 
     pub fn to_fn_ptr(&self) -> FnPointer {
         FnPointer {
             num_binders: 0,
-            sig: FnSig { abi: (), safety: Safety::Safe, variadic: self.is_varargs },
+            sig: FnSig { abi: (), safety: self.safety, variadic: self.is_varargs },
             substitution: FnSubst(Substitution::from_iter(
                 Interner,
                 self.params_and_return.iter().cloned(),
@@ -268,7 +275,11 @@ impl TypeFoldable for CallableSig {
     ) -> Result {
         let vec = self.params_and_return.to_vec();
         let folded = vec.try_fold_with(folder, outer_binder)?;
-        Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs })
+        Ok(CallableSig {
+            params_and_return: folded.into(),
+            is_varargs: self.is_varargs,
+            safety: self.safety,
+        })
     }
 }
 
@@ -573,5 +584,5 @@ pub fn callable_sig_from_fnonce(
 
     let ret_ty = db.normalize_projection(projection, env);
 
-    Some(CallableSig::from_params_and_return(params, ret_ty.clone(), false))
+    Some(CallableSig::from_params_and_return(params, ret_ty.clone(), false, Safety::Safe))
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 22a85cf154587..baf9842d5fbf2 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -227,13 +227,17 @@ impl<'a> TyLoweringContext<'a> {
                     .intern(Interner)
             }
             TypeRef::Placeholder => TyKind::Error.intern(Interner),
-            TypeRef::Fn(params, is_varargs) => {
+            &TypeRef::Fn(ref params, variadic, is_unsafe) => {
                 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
                     Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
                 });
                 TyKind::Function(FnPointer {
                     num_binders: 0, // FIXME lower `for<'a> fn()` correctly
-                    sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
+                    sig: FnSig {
+                        abi: (),
+                        safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
+                        variadic,
+                    },
                     substitution: FnSubst(substs),
                 })
                 .intern(Interner)
@@ -1573,7 +1577,12 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
         .with_type_param_mode(ParamLoweringMode::Variable);
     let ret = ctx_ret.lower_ty(&data.ret_type);
     let generics = generics(db.upcast(), def.into());
-    let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
+    let sig = CallableSig::from_params_and_return(
+        params,
+        ret,
+        data.is_varargs(),
+        if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe },
+    );
     make_binders(db, &generics, sig)
 }
 
@@ -1617,7 +1626,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
     let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::>();
     let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
-    Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
+    Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
 }
 
 /// Build the type of a tuple struct constructor.
@@ -1644,7 +1653,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
         TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
     let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::>();
     let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
-    Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
+    Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
 }
 
 /// Build the type of a tuple enum variant constructor.
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
index 1abdb0be7f876..7e3aecc2ae0ae 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
@@ -390,7 +390,7 @@ fn test() {
     let f: fn(u32) -> isize = foo;
                            // ^^^ adjustments: Pointer(ReifyFnPointer)
     let f: unsafe fn(u32) -> isize = foo;
-                                  // ^^^ adjustments: Pointer(ReifyFnPointer)
+                                  // ^^^ adjustments: Pointer(ReifyFnPointer), Pointer(UnsafeFnPointer)
 }",
     );
 }
@@ -421,7 +421,10 @@ fn coerce_closure_to_fn_ptr() {
     check_no_mismatches(
         r"
 fn test() {
-    let f: fn(u32) -> isize = |x| { 1 };
+    let f: fn(u32) -> u32 = |x| x;
+                         // ^^^^^ adjustments: Pointer(ClosureFnPointer(Safe))
+    let f: unsafe fn(u32) -> u32 = |x| x;
+                                // ^^^^^ adjustments: Pointer(ClosureFnPointer(Unsafe))
 }",
     );
 }

From 4301794c2c91da739e06cedea31226b784a9f36c Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Thu, 3 Nov 2022 21:36:14 +0100
Subject: [PATCH 383/482] Clarify what commands are debug commands in VSCode

---
 .../rust-analyzer/editors/code/package.json    | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 8e8b59159db92..2e6afb9474f52 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -100,22 +100,27 @@
             {
                 "command": "rust-analyzer.syntaxTree",
                 "title": "Show Syntax Tree",
-                "category": "rust-analyzer"
+                "category": "rust-analyzer (debug command)"
             },
             {
                 "command": "rust-analyzer.viewHir",
                 "title": "View Hir",
-                "category": "rust-analyzer"
+                "category": "rust-analyzer (debug command)"
             },
             {
                 "command": "rust-analyzer.viewFileText",
                 "title": "View File Text (as seen by the server)",
-                "category": "rust-analyzer"
+                "category": "rust-analyzer (debug command)"
             },
             {
                 "command": "rust-analyzer.viewItemTree",
                 "title": "Debug ItemTree",
-                "category": "rust-analyzer"
+                "category": "rust-analyzer (debug command)"
+            },
+            {
+                "command": "rust-analyzer.shuffleCrateGraph",
+                "title": "Shuffle Crate Graph",
+                "category": "rust-analyzer (debug command)"
             },
             {
                 "command": "rust-analyzer.viewCrateGraph",
@@ -177,11 +182,6 @@
                 "title": "Memory Usage (Clears Database)",
                 "category": "rust-analyzer"
             },
-            {
-                "command": "rust-analyzer.shuffleCrateGraph",
-                "title": "Shuffle Crate Graph",
-                "category": "rust-analyzer"
-            },
             {
                 "command": "rust-analyzer.reloadWorkspace",
                 "title": "Reload workspace",

From bf20c36f399fd883a5ede70ab48c062efb388624 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Sat, 5 Nov 2022 00:30:21 +0100
Subject: [PATCH 384/482] Mark the Memory Usage command as debug command

---
 src/tools/rust-analyzer/editors/code/package.json | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 2e6afb9474f52..1a97a9c089375 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -122,6 +122,11 @@
                 "title": "Shuffle Crate Graph",
                 "category": "rust-analyzer (debug command)"
             },
+            {
+                "command": "rust-analyzer.memoryUsage",
+                "title": "Memory Usage (Clears Database)",
+                "category": "rust-analyzer (debug command)"
+            },
             {
                 "command": "rust-analyzer.viewCrateGraph",
                 "title": "View Crate Graph",
@@ -177,11 +182,6 @@
                 "title": "Status",
                 "category": "rust-analyzer"
             },
-            {
-                "command": "rust-analyzer.memoryUsage",
-                "title": "Memory Usage (Clears Database)",
-                "category": "rust-analyzer"
-            },
             {
                 "command": "rust-analyzer.reloadWorkspace",
                 "title": "Reload workspace",

From 8b6c208c93628a7d48d9e99d50d78d8e1c1449d7 Mon Sep 17 00:00:00 2001
From: Justin Mott 
Date: Fri, 21 Oct 2022 13:28:59 -0400
Subject: [PATCH 385/482] addressed
 https://github.com/rust-lang/rust-analyzer/issues/12536

---
 .../ide-assists/src/handlers/inline_call.rs   | 86 ++++++++++++++++---
 1 file changed, 74 insertions(+), 12 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
index 9f51cdaf8b1eb..c546ee45d964f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
@@ -1,3 +1,5 @@
+use std::collections::BTreeSet;
+
 use ast::make;
 use either::Either;
 use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo};
@@ -373,8 +375,44 @@ fn inline(
                 })
         }
     }
+
+    let mut func_let_vars: BTreeSet = BTreeSet::new();
+
+    // grab all of the local variable declarations in the function
+    for stmt in fn_body.statements() {
+        if let Some(let_stmt) = ast::LetStmt::cast(stmt.syntax().to_owned()) {
+            for has_token in let_stmt.syntax().children_with_tokens() {
+                if let Some(node) = has_token.as_node() {
+                    if let Some(ident_pat) = ast::IdentPat::cast(node.to_owned()) {
+                        func_let_vars.insert(ident_pat.syntax().text().to_string());
+                    }
+                }
+            }
+        }
+    }
+
     // Inline parameter expressions or generate `let` statements depending on whether inlining works or not.
     for ((pat, param_ty, _), usages, expr) in izip!(params, param_use_nodes, arguments).rev() {
+        // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
+        let usages: &[ast::PathExpr] = &*usages;
+        let expr: &ast::Expr = expr;
+
+        let insert_let_stmt = || {
+            let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty.clone());
+            if let Some(stmt_list) = body.stmt_list() {
+                stmt_list.push_front(
+                    make::let_stmt(pat.clone(), ty, Some(expr.clone())).clone_for_update().into(),
+                )
+            }
+        };
+
+        // check if there is a local var in the function that conflicts with parameter
+        // if it does then emit a let statement and continue
+        if func_let_vars.contains(&expr.syntax().text().to_string()) {
+            insert_let_stmt();
+            continue;
+        }
+
         let inline_direct = |usage, replacement: &ast::Expr| {
             if let Some(field) = path_expr_as_record_field(usage) {
                 cov_mark::hit!(inline_call_inline_direct_field);
@@ -383,9 +421,7 @@ fn inline(
                 ted::replace(usage.syntax(), &replacement.syntax().clone_for_update());
             }
         };
-        // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
-        let usages: &[ast::PathExpr] = &*usages;
-        let expr: &ast::Expr = expr;
+
         match usages {
             // inline single use closure arguments
             [usage]
@@ -408,18 +444,11 @@ fn inline(
             }
             // can't inline, emit a let statement
             _ => {
-                let ty =
-                    sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty.clone());
-                if let Some(stmt_list) = body.stmt_list() {
-                    stmt_list.push_front(
-                        make::let_stmt(pat.clone(), ty, Some(expr.clone()))
-                            .clone_for_update()
-                            .into(),
-                    )
-                }
+                insert_let_stmt();
             }
         }
     }
+
     if let Some(generic_arg_list) = generic_arg_list.clone() {
         if let Some((target, source)) = &sema.scope(node.syntax()).zip(sema.scope(fn_body.syntax()))
         {
@@ -1256,4 +1285,37 @@ impl A {
 "#,
         )
     }
+
+    #[test]
+    fn local_variable_shadowing_callers_argument() {
+        check_assist(
+            inline_call,
+            r#"
+fn foo(bar: u32, baz: u32) -> u32 {
+    let a = 1;
+    bar * baz * a * 6
+}
+fn main() {
+    let a = 7;
+    let b = 1;
+    let res = foo$0(a, b);
+}
+"#,
+            r#"
+fn foo(bar: u32, baz: u32) -> u32 {
+    let a = 1;
+    bar * baz * a * 6
+}
+fn main() {
+    let a = 7;
+    let b = 1;
+    let res = {
+        let bar = a;
+        let a = 1;
+        bar * b * a * 6
+    };
+}
+"#,
+        );
+    }
 }

From 74297b05659754dc39e15dd2fa7afdddc4275193 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Sat, 5 Nov 2022 12:04:21 +0100
Subject: [PATCH 386/482] fix: Fix reference searching only accounting
 substrings instead of whole identifiers

---
 .../rust-analyzer/crates/ide-db/src/search.rs | 70 ++++++++++++-------
 .../rust-analyzer/crates/ide/src/rename.rs    | 35 +++++++++-
 2 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index 82b85f2fa5edd..aa5d7e9beb54f 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -446,33 +446,47 @@ impl<'a> FindUsages<'a> {
             })
         }
 
-        // FIXME: There should be optimization potential here
-        // Currently we try to descend everything we find which
-        // means we call `Semantics::descend_into_macros` on
-        // every textual hit. That function is notoriously
-        // expensive even for things that do not get down mapped
-        // into macros.
+        let find_nodes = move |name: &str, node: &syntax::SyntaxNode, offset: TextSize| {
+            node.token_at_offset(offset).find(|it| it.text() == name).map(|token| {
+                // FIXME: There should be optimization potential here
+                // Currently we try to descend everything we find which
+                // means we call `Semantics::descend_into_macros` on
+                // every textual hit. That function is notoriously
+                // expensive even for things that do not get down mapped
+                // into macros.
+                sema.descend_into_macros(token).into_iter().filter_map(|it| it.parent())
+            })
+        };
+
         for (text, file_id, search_range) in scope_files(sema, &search_scope) {
             let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
 
             // Search for occurrences of the items name
             for offset in match_indices(&text, finder, search_range) {
-                for name in sema.find_nodes_at_offset_with_descend(&tree, offset) {
-                    if match name {
-                        ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink),
-                        ast::NameLike::Name(name) => self.found_name(&name, sink),
-                        ast::NameLike::Lifetime(lifetime) => self.found_lifetime(&lifetime, sink),
-                    } {
-                        return;
+                if let Some(iter) = find_nodes(name, &tree, offset) {
+                    for name in iter.filter_map(ast::NameLike::cast) {
+                        if match name {
+                            ast::NameLike::NameRef(name_ref) => {
+                                self.found_name_ref(&name_ref, sink)
+                            }
+                            ast::NameLike::Name(name) => self.found_name(&name, sink),
+                            ast::NameLike::Lifetime(lifetime) => {
+                                self.found_lifetime(&lifetime, sink)
+                            }
+                        } {
+                            return;
+                        }
                     }
                 }
             }
             // Search for occurrences of the `Self` referring to our type
             if let Some((self_ty, finder)) = &include_self_kw_refs {
                 for offset in match_indices(&text, finder, search_range) {
-                    for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
-                        if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
-                            return;
+                    if let Some(iter) = find_nodes("Self", &tree, offset) {
+                        for name_ref in iter.filter_map(ast::NameRef::cast) {
+                            if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
+                                return;
+                            }
                         }
                     }
                 }
@@ -493,17 +507,21 @@ impl<'a> FindUsages<'a> {
                     let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
 
                     for offset in match_indices(&text, finder, search_range) {
-                        for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
-                            if self.found_name_ref(&name_ref, sink) {
-                                return;
+                        if let Some(iter) = find_nodes("super", &tree, offset) {
+                            for name_ref in iter.filter_map(ast::NameRef::cast) {
+                                if self.found_name_ref(&name_ref, sink) {
+                                    return;
+                                }
                             }
                         }
                     }
                     if let Some(finder) = &is_crate_root {
                         for offset in match_indices(&text, finder, search_range) {
-                            for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
-                                if self.found_name_ref(&name_ref, sink) {
-                                    return;
+                            if let Some(iter) = find_nodes("crate", &tree, offset) {
+                                for name_ref in iter.filter_map(ast::NameRef::cast) {
+                                    if self.found_name_ref(&name_ref, sink) {
+                                        return;
+                                    }
                                 }
                             }
                         }
@@ -544,9 +562,11 @@ impl<'a> FindUsages<'a> {
                 let finder = &Finder::new("self");
 
                 for offset in match_indices(&text, finder, search_range) {
-                    for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
-                        if self.found_self_module_name_ref(&name_ref, sink) {
-                            return;
+                    if let Some(iter) = find_nodes("self", &tree, offset) {
+                        for name_ref in iter.filter_map(ast::NameRef::cast) {
+                            if self.found_self_module_name_ref(&name_ref, sink) {
+                                return;
+                            }
                         }
                     }
                 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index fe44856dcad2a..b4df0437050f4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -40,7 +40,9 @@ pub(crate) fn prepare_rename(
             if def.range_for_rename(&sema).is_none() {
                 bail!("No references found at position")
             }
-            let frange = sema.original_range(name_like.syntax());
+            let Some(frange) = sema.original_range_opt(name_like.syntax()) else {
+                bail!("No references found at position");
+            };
 
             always!(
                 frange.range.contains_inclusive(position.offset)
@@ -51,7 +53,7 @@ pub(crate) fn prepare_rename(
         .reduce(|acc, cur| match (acc, cur) {
             // ensure all ranges are the same
             (Ok(acc_inner), Ok(cur_inner)) if acc_inner == cur_inner => Ok(acc_inner),
-            (Err(e), _) => Err(e),
+            (e @ Err(_), _) | (_, e @ Err(_)) => e,
             _ => bail!("inconsistent text range"),
         });
 
@@ -2249,4 +2251,33 @@ fn foo((bar | bar | bar): ()) {
 "#,
         );
     }
+
+    #[test]
+    fn regression_13498() {
+        check(
+            "Testing",
+            r"
+mod foo {
+    pub struct Test$0;
+}
+
+use foo::Test as Tester;
+
+fn main() {
+    let t = Tester;
+}
+",
+            r"
+mod foo {
+    pub struct Testing;
+}
+
+use foo::Testing as Tester;
+
+fn main() {
+    let t = Tester;
+}
+",
+        )
+    }
 }

From fc4462b5643a029b21e58875fc65981b3eff39a6 Mon Sep 17 00:00:00 2001
From: DropDemBits 
Date: Mon, 10 Oct 2022 00:47:53 -0400
Subject: [PATCH 387/482] Migrate most of `ide_assists::utils` to format arg
 capture

---
 .../crates/ide-assists/src/utils.rs           | 16 +++----
 .../src/utils/gen_trait_fn_body.rs            | 44 +++++++++----------
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index db32e7182c44d..307e67927056b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -189,8 +189,8 @@ pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor
     let mut placeholder = cursor.node().to_string();
     escape(&mut placeholder);
     let tab_stop = match cursor {
-        Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
-        Cursor::Before(placeholder) => format!("$0{}", placeholder),
+        Cursor::Replace(placeholder) => format!("${{0:{placeholder}}}"),
+        Cursor::Before(placeholder) => format!("$0{placeholder}"),
     };
 
     let mut buf = node.to_string();
@@ -539,17 +539,17 @@ impl ReferenceConversion {
             ReferenceConversionType::AsRefSlice => {
                 let type_argument_name =
                     self.ty.type_arguments().next().unwrap().display(db).to_string();
-                format!("&[{}]", type_argument_name)
+                format!("&[{type_argument_name}]")
             }
             ReferenceConversionType::Dereferenced => {
                 let type_argument_name =
                     self.ty.type_arguments().next().unwrap().display(db).to_string();
-                format!("&{}", type_argument_name)
+                format!("&{type_argument_name}")
             }
             ReferenceConversionType::Option => {
                 let type_argument_name =
                     self.ty.type_arguments().next().unwrap().display(db).to_string();
-                format!("Option<&{}>", type_argument_name)
+                format!("Option<&{type_argument_name}>")
             }
             ReferenceConversionType::Result => {
                 let mut type_arguments = self.ty.type_arguments();
@@ -557,19 +557,19 @@ impl ReferenceConversion {
                     type_arguments.next().unwrap().display(db).to_string();
                 let second_type_argument_name =
                     type_arguments.next().unwrap().display(db).to_string();
-                format!("Result<&{}, &{}>", first_type_argument_name, second_type_argument_name)
+                format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>")
             }
         }
     }
 
     pub(crate) fn getter(&self, field_name: String) -> String {
         match self.conversion {
-            ReferenceConversionType::Copy => format!("self.{}", field_name),
+            ReferenceConversionType::Copy => format!("self.{field_name}"),
             ReferenceConversionType::AsRefStr
             | ReferenceConversionType::AsRefSlice
             | ReferenceConversionType::Dereferenced
             | ReferenceConversionType::Option
-            | ReferenceConversionType::Result => format!("self.{}.as_ref()", field_name),
+            | ReferenceConversionType::Result => format!("self.{field_name}.as_ref()"),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
index 7a0c912959a12..6c87e66c134d7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
@@ -41,7 +41,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
             let mut arms = vec![];
             for variant in list.variants() {
                 let name = variant.name()?;
-                let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
+                let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
 
                 match variant.field_list() {
                     // => match self { Self::Name { x } => Self::Name { x: x.clone() } }
@@ -70,7 +70,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         let mut pats = vec![];
                         let mut fields = vec![];
                         for (i, _) in list.fields().enumerate() {
-                            let field_name = format!("arg{}", i);
+                            let field_name = format!("arg{i}");
                             let pat = make::ident_pat(false, false, make::name(&field_name));
                             pats.push(pat.into());
 
@@ -118,7 +118,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                     let mut fields = vec![];
                     for (i, _) in field_list.fields().enumerate() {
                         let f_path = make::expr_path(make::ext::ident_path("self"));
-                        let target = make::expr_field(f_path, &format!("{}", i));
+                        let target = make::expr_field(f_path, &format!("{i}"));
                         fields.push(gen_clone_call(target));
                     }
                     let struct_name = make::expr_path(make::ext::ident_path("Self"));
@@ -151,7 +151,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
             let mut arms = vec![];
             for variant in list.variants() {
                 let name = variant.name()?;
-                let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
+                let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
                 let target = make::expr_path(make::ext::ident_path("f"));
 
                 match variant.field_list() {
@@ -159,7 +159,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         // => f.debug_struct(name)
                         let target = make::expr_path(make::ext::ident_path("f"));
                         let method = make::name_ref("debug_struct");
-                        let struct_name = format!("\"{}\"", name);
+                        let struct_name = format!("\"{name}\"");
                         let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
                         let mut expr = make::expr_method_call(target, method, args);
 
@@ -173,8 +173,8 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
 
                             // => .field("field_name", field)
                             let method_name = make::name_ref("field");
-                            let name = make::expr_literal(&(format!("\"{}\"", field_name))).into();
-                            let path = &format!("{}", field_name);
+                            let name = make::expr_literal(&(format!("\"{field_name}\""))).into();
+                            let path = &format!("{field_name}");
                             let path = make::expr_path(make::ext::ident_path(path));
                             let args = make::arg_list(vec![name, path]);
                             expr = make::expr_method_call(expr, method_name, args);
@@ -192,13 +192,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         // => f.debug_tuple(name)
                         let target = make::expr_path(make::ext::ident_path("f"));
                         let method = make::name_ref("debug_tuple");
-                        let struct_name = format!("\"{}\"", name);
+                        let struct_name = format!("\"{name}\"");
                         let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
                         let mut expr = make::expr_method_call(target, method, args);
 
                         let mut pats = vec![];
                         for (i, _) in list.fields().enumerate() {
-                            let name = format!("arg{}", i);
+                            let name = format!("arg{i}");
 
                             // create a field pattern for use in `MyStruct(fields..)`
                             let field_name = make::name(&name);
@@ -222,7 +222,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         arms.push(make::match_arm(Some(pat.into()), None, expr));
                     }
                     None => {
-                        let fmt_string = make::expr_literal(&(format!("\"{}\"", name))).into();
+                        let fmt_string = make::expr_literal(&(format!("\"{name}\""))).into();
                         let args = make::arg_list([target, fmt_string]);
                         let macro_name = make::expr_path(make::ext::ident_path("write"));
                         let macro_call = make::expr_macro_call(macro_name, args);
@@ -244,7 +244,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
         }
 
         ast::Adt::Struct(strukt) => {
-            let name = format!("\"{}\"", annotated_name);
+            let name = format!("\"{annotated_name}\"");
             let args = make::arg_list(Some(make::expr_literal(&name).into()));
             let target = make::expr_path(make::ext::ident_path("f"));
 
@@ -258,10 +258,10 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                     let mut expr = make::expr_method_call(target, method, args);
                     for field in field_list.fields() {
                         let name = field.name()?;
-                        let f_name = make::expr_literal(&(format!("\"{}\"", name))).into();
+                        let f_name = make::expr_literal(&(format!("\"{name}\""))).into();
                         let f_path = make::expr_path(make::ext::ident_path("self"));
                         let f_path = make::expr_ref(f_path, false);
-                        let f_path = make::expr_field(f_path, &format!("{}", name));
+                        let f_path = make::expr_field(f_path, &format!("{name}"));
                         let args = make::arg_list([f_name, f_path]);
                         expr = make::expr_method_call(expr, make::name_ref("field"), args);
                     }
@@ -275,7 +275,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                     for (i, _) in field_list.fields().enumerate() {
                         let f_path = make::expr_path(make::ext::ident_path("self"));
                         let f_path = make::expr_ref(f_path, false);
-                        let f_path = make::expr_field(f_path, &format!("{}", i));
+                        let f_path = make::expr_field(f_path, &format!("{i}"));
                         let method = make::name_ref("field");
                         expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)));
                     }
@@ -379,7 +379,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                 let mut stmts = vec![];
                 for (i, _) in field_list.fields().enumerate() {
                     let base = make::expr_path(make::ext::ident_path("self"));
-                    let target = make::expr_field(base, &format!("{}", i));
+                    let target = make::expr_field(base, &format!("{i}"));
                     stmts.push(gen_hash_call(target));
                 }
                 make::block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
@@ -453,10 +453,10 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         for field in list.fields() {
                             let field_name = field.name()?.to_string();
 
-                            let l_name = &format!("l_{}", field_name);
+                            let l_name = &format!("l_{field_name}");
                             l_fields.push(gen_record_pat_field(&field_name, l_name));
 
-                            let r_name = &format!("r_{}", field_name);
+                            let r_name = &format!("r_{field_name}");
                             r_fields.push(gen_record_pat_field(&field_name, r_name));
 
                             let lhs = make::expr_path(make::ext::ident_path(l_name));
@@ -484,12 +484,12 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                         let mut r_fields = vec![];
 
                         for (i, _) in list.fields().enumerate() {
-                            let field_name = format!("{}", i);
+                            let field_name = format!("{i}");
 
-                            let l_name = format!("l{}", field_name);
+                            let l_name = format!("l{field_name}");
                             l_fields.push(gen_tuple_field(&l_name));
 
-                            let r_name = format!("r{}", field_name);
+                            let r_name = format!("r{field_name}");
                             r_fields.push(gen_tuple_field(&r_name));
 
                             let lhs = make::expr_path(make::ext::ident_path(&l_name));
@@ -548,7 +548,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
             Some(ast::FieldList::TupleFieldList(field_list)) => {
                 let mut expr = None;
                 for (i, _) in field_list.fields().enumerate() {
-                    let idx = format!("{}", i);
+                    let idx = format!("{i}");
                     let lhs = make::expr_path(make::ext::ident_path("self"));
                     let lhs = make::expr_field(lhs, &idx);
                     let rhs = make::expr_path(make::ext::ident_path("other"));
@@ -628,7 +628,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
             Some(ast::FieldList::TupleFieldList(field_list)) => {
                 let mut exprs = vec![];
                 for (i, _) in field_list.fields().enumerate() {
-                    let idx = format!("{}", i);
+                    let idx = format!("{i}");
                     let lhs = make::expr_path(make::ext::ident_path("self"));
                     let lhs = make::expr_field(lhs, &idx);
                     let rhs = make::expr_path(make::ext::ident_path("other"));

From f61e53c2a401ffe9152bdf0030c4cd81f78c34d8 Mon Sep 17 00:00:00 2001
From: DropDemBits 
Date: Mon, 10 Oct 2022 11:04:38 -0400
Subject: [PATCH 388/482] Migrate assists to format args captures, part 1

---
 .../src/handlers/add_explicit_type.rs         |  4 +-
 .../src/handlers/add_return_type.rs           |  6 +--
 .../src/handlers/add_turbo_fish.rs            |  7 +--
 .../src/handlers/apply_demorgan.rs            |  6 +--
 .../ide-assists/src/handlers/auto_import.rs   |  6 ++-
 .../src/handlers/convert_comment_block.rs     | 13 ++---
 .../src/handlers/convert_integer_literal.rs   | 10 ++--
 .../src/handlers/convert_into_to_from.rs      |  4 +-
 .../handlers/convert_iter_for_each_to_for.rs  | 12 ++---
 .../src/handlers/convert_let_else_to_match.rs |  6 +--
 .../convert_tuple_struct_to_named_struct.rs   |  8 +++-
 ...ert_two_arm_bool_match_to_matches_macro.rs | 10 ++--
 .../src/handlers/destructure_tuple_binding.rs | 12 ++---
 .../src/handlers/extract_function.rs          | 48 ++++++++-----------
 .../src/handlers/extract_module.rs            | 31 ++++++------
 .../extract_struct_from_enum_variant.rs       | 10 ++--
 .../src/handlers/extract_type_alias.rs        | 38 +++++----------
 .../src/handlers/extract_variable.rs          | 14 +++---
 .../src/handlers/fix_visibility.rs            | 18 +++----
 19 files changed, 128 insertions(+), 135 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
index bfa9759ec84be..b5f99726fe1c8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
@@ -69,14 +69,14 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
     let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
     acc.add(
         AssistId("add_explicit_type", AssistKind::RefactorRewrite),
-        format!("Insert explicit type `{}`", inferred_type),
+        format!("Insert explicit type `{inferred_type}`"),
         pat_range,
         |builder| match ascribed_ty {
             Some(ascribed_ty) => {
                 builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
             }
             None => {
-                builder.insert(pat_range.end(), format!(": {}", inferred_type));
+                builder.insert(pat_range.end(), format!(": {inferred_type}"));
             }
         },
     )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
index f858d7a15c242..89040a8569e63 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
@@ -35,16 +35,16 @@ pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
             match builder_edit_pos {
                 InsertOrReplace::Insert(insert_pos, needs_whitespace) => {
                     let preceeding_whitespace = if needs_whitespace { " " } else { "" };
-                    builder.insert(insert_pos, &format!("{}-> {} ", preceeding_whitespace, ty))
+                    builder.insert(insert_pos, &format!("{preceeding_whitespace}-> {ty} "))
                 }
                 InsertOrReplace::Replace(text_range) => {
-                    builder.replace(text_range, &format!("-> {}", ty))
+                    builder.replace(text_range, &format!("-> {ty}"))
                 }
             }
             if let FnType::Closure { wrap_expr: true } = fn_type {
                 cov_mark::hit!(wrap_closure_non_block_expr);
                 // `|x| x` becomes `|x| -> T x` which is invalid, so wrap it in a block
-                builder.replace(tail_expr.syntax().text_range(), &format!("{{{}}}", tail_expr));
+                builder.replace(tail_expr.syntax().text_range(), &format!("{{{tail_expr}}}"));
             }
         },
     )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
index c0bf238db7317..acf82e4b25794 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
@@ -93,12 +93,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
             builder.trigger_signature_help();
             match ctx.config.snippet_cap {
                 Some(cap) => {
-                    let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
+                    let fish_head = get_snippet_fish_head(number_of_arguments);
+                    let snip = format!("::<{fish_head}>");
                     builder.insert_snippet(cap, ident.text_range().end(), snip)
                 }
                 None => {
                     let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
-                    let snip = format!("::<{}>", fish_head);
+                    let snip = format!("::<{fish_head}>");
                     builder.insert(ident.text_range().end(), snip);
                 }
             }
@@ -109,7 +110,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 /// This will create a snippet string with tabstops marked
 fn get_snippet_fish_head(number_of_arguments: usize) -> String {
     let mut fish_head = (1..number_of_arguments)
-        .format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
+        .format_with("", |i, f| f(&format_args!("${{{i}:_}}, ")))
         .to_string();
 
     // tabstop 0 is a special case and always the last one
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
index 2853d1d1be3cd..57cfa17cc8e13 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -123,20 +123,20 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
                     let lhs_range = lhs.syntax().text_range();
                     let not_lhs = invert_boolean_expression(lhs);
 
-                    edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
+                    edit.replace(lhs_range, format!("!({not_lhs}"));
                 }
 
                 if let Some(rhs) = terms.pop_back() {
                     let rhs_range = rhs.syntax().text_range();
                     let not_rhs = invert_boolean_expression(rhs);
 
-                    edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
+                    edit.replace(rhs_range, format!("{not_rhs})"));
                 }
 
                 for term in terms {
                     let term_range = term.syntax().text_range();
                     let not_term = invert_boolean_expression(term);
-                    edit.replace(term_range, not_term.syntax().text());
+                    edit.replace(term_range, not_term.to_string());
                 }
             }
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
index 678dc877d1381..a689270bc0915 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
@@ -127,10 +127,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
         .sort_by_key(|import| Reverse(relevance_score(ctx, import, current_module.as_ref())));
 
     for import in proposed_imports {
+        let import_path = import.import_path;
+
         acc.add_group(
             &group_label,
             AssistId("auto_import", AssistKind::QuickFix),
-            format!("Import `{}`", import.import_path),
+            format!("Import `{import_path}`"),
             range,
             |builder| {
                 let scope = match scope.clone() {
@@ -138,7 +140,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
                     ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
                     ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
                 };
-                insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
+                insert_use(&scope, mod_path_to_ast(&import_path), &ctx.config.insert_use);
             },
         );
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
index f171dd81a811e..312cb65abd2a1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
@@ -54,16 +54,17 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
 
             let indent_spaces = indentation.to_string();
             let output = lines
-                .map(|l| l.trim_start_matches(&indent_spaces))
-                .map(|l| {
+                .map(|line| {
+                    let line = line.trim_start_matches(&indent_spaces);
+
                     // Don't introduce trailing whitespace
-                    if l.is_empty() {
+                    if line.is_empty() {
                         line_prefix.to_string()
                     } else {
-                        format!("{} {}", line_prefix, l.trim_start_matches(&indent_spaces))
+                        format!("{line_prefix} {line}")
                     }
                 })
-                .join(&format!("\n{}", indent_spaces));
+                .join(&format!("\n{indent_spaces}"));
 
             edit.replace(target, output)
         },
@@ -96,7 +97,7 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
             let block_prefix =
                 CommentKind { shape: CommentShape::Block, ..comment.kind() }.prefix();
 
-            let output = format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation);
+            let output = format!("{block_prefix}\n{block_comment_body}\n{indentation}*/");
 
             edit.replace(target, output)
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
index 9060696cdc8e9..ff2195f7e6c4a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
@@ -32,19 +32,19 @@ pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext<'_>
         }
 
         let mut converted = match target_radix {
-            Radix::Binary => format!("0b{:b}", value),
-            Radix::Octal => format!("0o{:o}", value),
+            Radix::Binary => format!("0b{value:b}"),
+            Radix::Octal => format!("0o{value:o}"),
             Radix::Decimal => value.to_string(),
-            Radix::Hexadecimal => format!("0x{:X}", value),
+            Radix::Hexadecimal => format!("0x{value:X}"),
         };
 
-        let label = format!("Convert {} to {}{}", literal, converted, suffix.unwrap_or_default());
-
         // Appends the type suffix back into the new literal if it exists.
         if let Some(suffix) = suffix {
             converted.push_str(suffix);
         }
 
+        let label = format!("Convert {literal} to {converted}");
+
         acc.add_group(
             &group_id,
             AssistId("convert_integer_literal", AssistKind::RefactorInline),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
index 95d11abe8bc0f..872b52c98fff2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
@@ -86,9 +86,9 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
         impl_.syntax().text_range(),
         |builder| {
             builder.replace(src_type.syntax().text_range(), dest_type.to_string());
-            builder.replace(ast_trait.syntax().text_range(), format!("From<{}>", src_type));
+            builder.replace(ast_trait.syntax().text_range(), format!("From<{src_type}>"));
             builder.replace(into_fn_return.syntax().text_range(), "-> Self");
-            builder.replace(into_fn_params.syntax().text_range(), format!("(val: {})", src_type));
+            builder.replace(into_fn_params.syntax().text_range(), format!("(val: {src_type})"));
             builder.replace(into_fn_name.syntax().text_range(), "from");
 
             for s in selfs {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
index 2cf370c090743..80eecf4a09868 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -119,19 +119,19 @@ pub(crate) fn convert_for_loop_with_for_each(
             {
                 // We have either "for x in &col" and col implements a method called iter
                 //             or "for x in &mut col" and col implements a method called iter_mut
-                format_to!(buf, "{}.{}()", expr_behind_ref, method);
+                format_to!(buf, "{expr_behind_ref}.{method}()");
             } else if let ast::Expr::RangeExpr(..) = iterable {
                 // range expressions need to be parenthesized for the syntax to be correct
-                format_to!(buf, "({})", iterable);
+                format_to!(buf, "({iterable})");
             } else if impls_core_iter(&ctx.sema, &iterable) {
-                format_to!(buf, "{}", iterable);
+                format_to!(buf, "{iterable}");
             } else if let ast::Expr::RefExpr(_) = iterable {
-                format_to!(buf, "({}).into_iter()", iterable);
+                format_to!(buf, "({iterable}).into_iter()");
             } else {
-                format_to!(buf, "{}.into_iter()", iterable);
+                format_to!(buf, "{iterable}.into_iter()");
             }
 
-            format_to!(buf, ".for_each(|{}| {});", pat, body);
+            format_to!(buf, ".for_each(|{pat}| {body});");
 
             builder.replace(for_loop.syntax().text_range(), buf)
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
index 00095de257d5a..c82a3b5303259 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
@@ -80,7 +80,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
         .map(
             |(ident, ismut)| {
                 if *ismut && addmut {
-                    format!("mut {}", ident)
+                    format!("mut {ident}")
                 } else {
                     ident.to_string()
                 }
@@ -93,7 +93,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
     } else if binders.len() == 1 {
         vars
     } else {
-        format!("({})", vars)
+        format!("({vars})")
     }
 }
 
@@ -153,7 +153,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
 
             let only_expr = let_else_block.statements().next().is_none();
             let branch2 = match &let_else_block.tail_expr() {
-                Some(tail) if only_expr => format!("{},", tail.syntax().text()),
+                Some(tail) if only_expr => format!("{tail},"),
                 _ => let_else_block.syntax().text().to_string(),
             };
             let replace = if binders.is_empty() {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index d8f522708460e..92e091fca126c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -226,7 +226,13 @@ fn edit_field_references(
 }
 
 fn generate_names(fields: impl Iterator) -> Vec {
-    fields.enumerate().map(|(i, _)| ast::make::name(&format!("field{}", i + 1))).collect()
+    fields
+        .enumerate()
+        .map(|(i, _)| {
+            let idx = i + 1;
+            ast::make::name(&format!("field{idx}"))
+        })
+        .collect()
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
index 54a7f480a4e46..b1b0f587cd33d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
@@ -58,16 +58,16 @@ pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
         target_range,
         |builder| {
             let mut arm_str = String::new();
-            if let Some(ref pat) = first_arm.pat() {
+            if let Some(pat) = &first_arm.pat() {
                 arm_str += &pat.to_string();
             }
-            if let Some(ref guard) = first_arm.guard() {
-                arm_str += &format!(" {}", &guard.to_string());
+            if let Some(guard) = &first_arm.guard() {
+                arm_str += &format!(" {guard}");
             }
             if invert_matches {
-                builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
+                builder.replace(target_range, format!("!matches!({expr}, {arm_str})"));
             } else {
-                builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
+                builder.replace(target_range, format!("matches!({expr}, {arm_str})"));
             }
         },
     )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index dc581ff3bd2c7..31c2ce7c1b54a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -133,7 +133,7 @@ fn generate_name(
     _usages: &Option,
 ) -> String {
     // FIXME: detect if name already used
-    format!("_{}", index)
+    format!("_{index}")
 }
 
 enum RefType {
@@ -168,12 +168,12 @@ fn edit_tuple_assignment(
     let add_cursor = |text: &str| {
         // place cursor on first tuple item
         let first_tuple = &data.field_names[0];
-        text.replacen(first_tuple, &format!("$0{}", first_tuple), 1)
+        text.replacen(first_tuple, &format!("$0{first_tuple}"), 1)
     };
 
     // with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)`
     if in_sub_pattern {
-        let text = format!(" @ {}", tuple_pat);
+        let text = format!(" @ {tuple_pat}");
         match ctx.config.snippet_cap {
             Some(cap) => {
                 let snip = add_cursor(&text);
@@ -314,9 +314,9 @@ struct RefData {
 impl RefData {
     fn format(&self, field_name: &str) -> String {
         match (self.needs_deref, self.needs_parentheses) {
-            (true, true) => format!("(*{})", field_name),
-            (true, false) => format!("*{}", field_name),
-            (false, true) => format!("({})", field_name),
+            (true, true) => format!("(*{field_name})"),
+            (true, false) => format!("*{field_name}"),
+            (false, true) => format!("({field_name})"),
             (false, false) => field_name.to_string(),
         }
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index d6c8ea785f84a..0605883584922 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -181,7 +181,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef
     let mut counter = 0;
     while names_in_scope.contains(&name) {
         counter += 1;
-        name = format!("{}{}", &default_name, counter)
+        name = format!("{default_name}{counter}")
     }
     make::name_ref(&name)
 }
@@ -1291,19 +1291,23 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St
     match fun.outliving_locals.as_slice() {
         [] => {}
         [var] => {
-            format_to!(buf, "let {}{} = ", mut_modifier(var), var.local.name(ctx.db()))
+            let modifier = mut_modifier(var);
+            let name = var.local.name(ctx.db());
+            format_to!(buf, "let {modifier}{name} = ")
         }
         vars => {
             buf.push_str("let (");
             let bindings = vars.iter().format_with(", ", |local, f| {
-                f(&format_args!("{}{}", mut_modifier(local), local.local.name(ctx.db())))
+                let modifier = mut_modifier(local);
+                let name = local.local.name(ctx.db());
+                f(&format_args!("{modifier}{name}"))
             });
-            format_to!(buf, "{}", bindings);
+            format_to!(buf, "{bindings}");
             buf.push_str(") = ");
         }
     }
 
-    format_to!(buf, "{}", expr);
+    format_to!(buf, "{expr}");
     let insert_comma = fun
         .body
         .parent()
@@ -1447,6 +1451,8 @@ fn format_function(
     new_indent: IndentLevel,
 ) -> String {
     let mut fn_def = String::new();
+
+    let fun_name = &fun.name;
     let params = fun.make_param_list(ctx, module);
     let ret_ty = fun.make_ret_ty(ctx, module);
     let body = make_body(ctx, old_indent, new_indent, fun);
@@ -1454,42 +1460,28 @@ fn format_function(
     let async_kw = if fun.control_flow.is_async { "async " } else { "" };
     let unsafe_kw = if fun.control_flow.is_unsafe { "unsafe " } else { "" };
     let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun);
+
+    format_to!(fn_def, "\n\n{new_indent}{const_kw}{async_kw}{unsafe_kw}");
     match ctx.config.snippet_cap {
-        Some(_) => format_to!(
-            fn_def,
-            "\n\n{}{}{}{}fn $0{}",
-            new_indent,
-            const_kw,
-            async_kw,
-            unsafe_kw,
-            fun.name,
-        ),
-        None => format_to!(
-            fn_def,
-            "\n\n{}{}{}{}fn {}",
-            new_indent,
-            const_kw,
-            async_kw,
-            unsafe_kw,
-            fun.name,
-        ),
+        Some(_) => format_to!(fn_def, "fn $0{fun_name}"),
+        None => format_to!(fn_def, "fn {fun_name}"),
     }
 
     if let Some(generic_params) = generic_params {
-        format_to!(fn_def, "{}", generic_params);
+        format_to!(fn_def, "{generic_params}");
     }
 
-    format_to!(fn_def, "{}", params);
+    format_to!(fn_def, "{params}");
 
     if let Some(ret_ty) = ret_ty {
-        format_to!(fn_def, " {}", ret_ty);
+        format_to!(fn_def, " {ret_ty}");
     }
 
     if let Some(where_clause) = where_clause {
-        format_to!(fn_def, " {}", where_clause);
+        format_to!(fn_def, " {where_clause}");
     }
 
-    format_to!(fn_def, " {}", body);
+    format_to!(fn_def, " {body}");
 
     fn_def
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
index 897980c665049..56834394aebaa 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
@@ -127,7 +127,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
             for item in items_to_be_processed {
                 let item = item.indent(IndentLevel(1));
                 let mut indented_item = String::new();
-                format_to!(indented_item, "{}{}", new_item_indent, item.to_string());
+                format_to!(indented_item, "{new_item_indent}{item}");
                 body_items.push(indented_item);
             }
 
@@ -137,30 +137,28 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
                 let mut impl_body_def = String::new();
 
                 if let Some(self_ty) = impl_.self_ty() {
-                    format_to!(
-                        impl_body_def,
-                        "{}impl {} {{\n{}\n{}}}",
-                        old_item_indent + 1,
-                        self_ty.to_string(),
-                        body,
-                        old_item_indent + 1
-                    );
-
+                    {
+                        let impl_indent = old_item_indent + 1;
+                        format_to!(
+                            impl_body_def,
+                            "{impl_indent}impl {self_ty} {{\n{body}\n{impl_indent}}}",
+                        );
+                    }
                     body = impl_body_def;
 
                     // Add the import for enum/struct corresponding to given impl block
                     module.make_use_stmt_of_node_with_super(self_ty.syntax());
                     for item in module.use_items {
-                        let mut indented_item = String::new();
-                        format_to!(indented_item, "{}{}", old_item_indent + 1, item.to_string());
-                        body = format!("{}\n\n{}", indented_item, body);
+                        let item_indent = old_item_indent + 1;
+                        body = format!("{item_indent}{item}\n\n{body}");
                     }
                 }
             }
 
             let mut module_def = String::new();
 
-            format_to!(module_def, "mod {} {{\n{}\n{}}}", module.name, body, old_item_indent);
+            let module_name = module.name;
+            format_to!(module_def, "mod {module_name} {{\n{body}\n{old_item_indent}}}");
 
             let mut usages_to_be_updated_for_curr_file = vec![];
             for usages_to_be_updated_for_file in usages_to_be_processed {
@@ -199,7 +197,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
                     builder.delete(range);
                 }
 
-                builder.insert(impl_.syntax().text_range().end(), format!("\n\n{}", module_def));
+                builder.insert(impl_.syntax().text_range().end(), format!("\n\n{module_def}"));
             } else {
                 builder.replace(module.text_range, module_def)
             }
@@ -343,9 +341,10 @@ impl Module {
                 && !self.text_range.contains_range(desc.text_range())
             {
                 if let Some(name_ref) = ast::NameRef::cast(desc) {
+                    let mod_name = self.name;
                     return Some((
                         name_ref.syntax().text_range(),
-                        format!("{}::{}", self.name, name_ref),
+                        format!("{mod_name}::{name_ref}"),
                     ));
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 970e948dfd930..b4e10667b07ab 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -296,10 +296,14 @@ fn create_struct_def(
 
 fn update_variant(variant: &ast::Variant, generics: Option) -> Option<()> {
     let name = variant.name()?;
-    let ty = generics
+    let generic_args = generics
         .filter(|generics| generics.generic_params().count() > 0)
-        .map(|generics| make::ty(&format!("{}{}", &name.text(), generics.to_generic_args())))
-        .unwrap_or_else(|| make::ty(&name.text()));
+        .map(|generics| generics.to_generic_args());
+    // FIXME: replace with a `ast::make` constructor
+    let ty = match generic_args {
+        Some(generic_args) => make::ty(&format!("{name}{generic_args}")),
+        None => make::ty(&name.text()),
+    };
 
     // change from a record to a tuple field list
     let tuple_field = make::tuple_field(None, ty);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
index 03aa8601d14e1..3116935fc5e75 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
@@ -1,8 +1,7 @@
 use either::Either;
 use ide_db::syntax_helpers::node_ext::walk_ty;
-use itertools::Itertools;
 use syntax::{
-    ast::{self, edit::IndentLevel, AstNode, HasGenericParams, HasName},
+    ast::{self, edit::IndentLevel, make, AstNode, HasGenericParams, HasName},
     match_ast,
 };
 
@@ -64,41 +63,29 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 known_generics.extend(it.generic_params());
             }
             let generics = collect_used_generics(&ty, &known_generics);
+            let generic_params =
+                generics.map(|it| make::generic_param_list(it.into_iter().cloned()));
 
-            let replacement = if !generics.is_empty() {
-                format!(
-                    "Type<{}>",
-                    generics.iter().format_with(", ", |generic, f| {
-                        match generic {
-                            ast::GenericParam::ConstParam(cp) => f(&cp.name().unwrap()),
-                            ast::GenericParam::LifetimeParam(lp) => f(&lp.lifetime().unwrap()),
-                            ast::GenericParam::TypeParam(tp) => f(&tp.name().unwrap()),
-                        }
-                    })
-                )
-            } else {
-                String::from("Type")
-            };
+            let ty_args = generic_params
+                .as_ref()
+                .map_or(String::new(), |it| it.to_generic_args().to_string());
+            let replacement = format!("Type{ty_args}");
             builder.replace(target, replacement);
 
             let indent = IndentLevel::from_node(node);
-            let generics = if !generics.is_empty() {
-                format!("<{}>", generics.iter().format(", "))
-            } else {
-                String::new()
-            };
+            let generic_params = generic_params.map_or(String::new(), |it| it.to_string());
             match ctx.config.snippet_cap {
                 Some(cap) => {
                     builder.insert_snippet(
                         cap,
                         insert_pos,
-                        format!("type $0Type{} = {};\n\n{}", generics, ty, indent),
+                        format!("type $0Type{generic_params} = {ty};\n\n{indent}"),
                     );
                 }
                 None => {
                     builder.insert(
                         insert_pos,
-                        format!("type Type{} = {};\n\n{}", generics, ty, indent),
+                        format!("type Type{generic_params} = {ty};\n\n{indent}"),
                     );
                 }
             }
@@ -109,7 +96,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
 fn collect_used_generics<'gp>(
     ty: &ast::Type,
     known_generics: &'gp [ast::GenericParam],
-) -> Vec<&'gp ast::GenericParam> {
+) -> Option> {
     // can't use a closure -> closure here cause lifetime inference fails for that
     fn find_lifetime(text: &str) -> impl Fn(&&ast::GenericParam) -> bool + '_ {
         move |gp: &&ast::GenericParam| match gp {
@@ -198,7 +185,8 @@ fn collect_used_generics<'gp>(
         ast::GenericParam::LifetimeParam(_) => 0,
         ast::GenericParam::TypeParam(_) => 1,
     });
-    generics
+
+    Some(generics).filter(|it| it.len() > 0)
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index 3596b6f82381b..a738deffb95b3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -91,13 +91,13 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
 
             match anchor {
                 Anchor::Before(_) | Anchor::Replace(_) => {
-                    format_to!(buf, "let {}{} = {}", var_modifier, var_name, reference_modifier)
+                    format_to!(buf, "let {var_modifier}{var_name} = {reference_modifier}")
                 }
                 Anchor::WrapInBlock(_) => {
-                    format_to!(buf, "{{ let {} = {}", var_name, reference_modifier)
+                    format_to!(buf, "{{ let {var_name} = {reference_modifier}")
                 }
             };
-            format_to!(buf, "{}", to_extract.syntax());
+            format_to!(buf, "{to_extract}");
 
             if let Anchor::Replace(stmt) = anchor {
                 cov_mark::hit!(test_extract_var_expr_stmt);
@@ -107,8 +107,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                 match ctx.config.snippet_cap {
                     Some(cap) => {
                         let snip = buf.replace(
-                            &format!("let {}{}", var_modifier, var_name),
-                            &format!("let {}$0{}", var_modifier, var_name),
+                            &format!("let {var_modifier}{var_name}"),
+                            &format!("let {var_modifier}$0{var_name}"),
                         );
                         edit.replace_snippet(cap, expr_range, snip)
                     }
@@ -135,8 +135,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
             match ctx.config.snippet_cap {
                 Some(cap) => {
                     let snip = buf.replace(
-                        &format!("let {}{}", var_modifier, var_name),
-                        &format!("let {}$0{}", var_modifier, var_name),
+                        &format!("let {var_modifier}{var_name}"),
+                        &format!("let {var_modifier}$0{var_name}"),
                     );
                     edit.insert_snippet(cap, offset, snip)
                 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
index b33846f546653..8764543028706 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -57,8 +57,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
         if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
 
     let assist_label = match target_name {
-        None => format!("Change visibility to {}", missing_visibility),
-        Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
+        None => format!("Change visibility to {missing_visibility}"),
+        Some(name) => format!("Change visibility of {name} to {missing_visibility}"),
     };
 
     acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
@@ -68,15 +68,15 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
                 Some(current_visibility) => builder.replace_snippet(
                     cap,
                     current_visibility.syntax().text_range(),
-                    format!("$0{}", missing_visibility),
+                    format!("$0{missing_visibility}"),
                 ),
-                None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
+                None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
             },
             None => match current_visibility {
                 Some(current_visibility) => {
                     builder.replace(current_visibility.syntax().text_range(), missing_visibility)
                 }
-                None => builder.insert(offset, format!("{} ", missing_visibility)),
+                None => builder.insert(offset, format!("{missing_visibility} ")),
             },
         }
     })
@@ -114,7 +114,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
 
     let target_name = record_field_def.name(ctx.db());
     let assist_label =
-        format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
+        format!("Change visibility of {parent_name}.{target_name} to {missing_visibility}");
 
     acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
         builder.edit_file(target_file);
@@ -123,15 +123,15 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
                 Some(current_visibility) => builder.replace_snippet(
                     cap,
                     current_visibility.syntax().text_range(),
-                    format!("$0{}", missing_visibility),
+                    format!("$0{missing_visibility}"),
                 ),
-                None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
+                None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
             },
             None => match current_visibility {
                 Some(current_visibility) => {
                     builder.replace(current_visibility.syntax().text_range(), missing_visibility)
                 }
-                None => builder.insert(offset, format!("{} ", missing_visibility)),
+                None => builder.insert(offset, format!("{missing_visibility} ")),
             },
         }
     })

From e962f738ff12dbe92011f806c5097c3df94f0838 Mon Sep 17 00:00:00 2001
From: DropDemBits 
Date: Mon, 10 Oct 2022 14:20:27 -0400
Subject: [PATCH 389/482] Migrate assists to format args captures, part 3

---
 .../ide-assists/src/handlers/inline_call.rs   |  4 +--
 .../src/handlers/inline_local_variable.rs     |  4 +--
 .../src/handlers/introduce_named_lifetime.rs  |  2 +-
 .../src/handlers/merge_match_arms.rs          |  2 +-
 .../src/handlers/move_from_mod_rs.rs          |  4 +--
 .../ide-assists/src/handlers/move_guard.rs    | 10 +++----
 .../src/handlers/move_module_to_file.rs       |  4 +--
 .../src/handlers/move_to_mod_rs.rs            |  4 +--
 .../src/handlers/number_representation.rs     |  2 +-
 .../src/handlers/qualify_method_call.rs       |  2 +-
 .../ide-assists/src/handlers/qualify_path.rs  | 29 +++++++++----------
 .../ide-assists/src/handlers/raw_string.rs    |  9 ++----
 .../ide-assists/src/handlers/remove_dbg.rs    |  6 ++--
 .../replace_derive_with_manual_impl.rs        |  9 ++----
 .../src/handlers/replace_or_with_or_else.rs   |  4 +--
 .../replace_turbofish_with_explicit_type.rs   |  2 +-
 .../ide-assists/src/handlers/unwrap_tuple.rs  |  4 +--
 .../handlers/wrap_return_type_in_result.rs    |  4 +--
 18 files changed, 48 insertions(+), 57 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
index c546ee45d964f..0c546ce5d41c6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
@@ -192,10 +192,10 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
                 PathResolution::Def(hir::ModuleDef::Function(f)) => f,
                 _ => return None,
             };
-            (function, format!("Inline `{}`", path))
+            (function, format!("Inline `{path}`"))
         }
         ast::CallableExpr::MethodCall(call) => {
-            (ctx.sema.resolve_method_call(call)?, format!("Inline `{}`", name_ref))
+            (ctx.sema.resolve_method_call(call)?, format!("Inline `{name_ref}`"))
         }
     };
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
index 7259d67819416..ce44100e34beb 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
@@ -113,7 +113,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
         .collect::>>()?;
 
     let init_str = initializer_expr.syntax().text().to_string();
-    let init_in_paren = format!("({})", &init_str);
+    let init_in_paren = format!("({init_str})");
 
     let target = match target {
         ast::NameOrNameRef::Name(it) => it.syntax().text_range(),
@@ -132,7 +132,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
                 let replacement = if should_wrap { &init_in_paren } else { &init_str };
                 if ast::RecordExprField::for_field_name(&name).is_some() {
                     cov_mark::hit!(inline_field_shorthand);
-                    builder.insert(range.end(), format!(": {}", replacement));
+                    builder.insert(range.end(), format!(": {replacement}"));
                 } else {
                     builder.replace(range, replacement.clone())
                 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
index 2fc754e3e50d1..a54dc4f96de00 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
@@ -127,7 +127,7 @@ fn generate_unique_lifetime_param_name(
         Some(type_params) => {
             let used_lifetime_params: FxHashSet<_> =
                 type_params.lifetime_params().map(|p| p.syntax().text().to_string()).collect();
-            ('a'..='z').map(|it| format!("'{}", it)).find(|it| !used_lifetime_params.contains(it))
+            ('a'..='z').map(|it| format!("'{it}")).find(|it| !used_lifetime_params.contains(it))
         }
         None => Some("'a".to_string()),
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
index c24015b1c5175..641c90885bf53 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
@@ -78,7 +78,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                     .join(" | ")
             };
 
-            let arm = format!("{} => {},", pats, current_expr.syntax().text());
+            let arm = format!("{pats} => {current_expr},");
 
             if let [first, .., last] = &*arms_to_merge {
                 let start = first.syntax().text_range().start();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
index a6c85a2b18b34..1728c03cd03e2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
@@ -40,11 +40,11 @@ pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
 
     let target = source_file.syntax().text_range();
     let module_name = module.name(ctx.db())?.to_string();
-    let path = format!("../{}.rs", module_name);
+    let path = format!("../{module_name}.rs");
     let dst = AnchoredPathBuf { anchor: ctx.file_id(), path };
     acc.add(
         AssistId("move_from_mod_rs", AssistKind::Refactor),
-        format!("Convert {}/mod.rs to {}.rs", module_name, module_name),
+        format!("Convert {module_name}/mod.rs to {module_name}.rs"),
         target,
         |builder| {
             builder.move_file(ctx.file_id(), dst);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
index b8f1b36deb93c..ec3281619cc3f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
@@ -133,16 +133,16 @@ pub(crate) fn move_arm_cond_to_match_guard(
             };
             let then_arm_end = match_arm.syntax().text_range().end();
             let indent_level = match_arm.indent_level();
-            let spaces = "    ".repeat(indent_level.0 as _);
+            let spaces = indent_level;
 
             let mut first = true;
             for (cond, block) in conds_blocks {
                 if !first {
-                    edit.insert(then_arm_end, format!("\n{}", spaces));
+                    edit.insert(then_arm_end, format!("\n{spaces}"));
                 } else {
                     first = false;
                 }
-                let guard = format!("{} if {} => ", match_pat, cond.syntax().text());
+                let guard = format!("{match_pat} if {cond} => ");
                 edit.insert(then_arm_end, guard);
                 let only_expr = block.statements().next().is_none();
                 match &block.tail_expr() {
@@ -158,7 +158,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
             }
             if let Some(e) = tail {
                 cov_mark::hit!(move_guard_ifelse_else_tail);
-                let guard = format!("\n{}{} => ", spaces, match_pat);
+                let guard = format!("\n{spaces}{match_pat} => ");
                 edit.insert(then_arm_end, guard);
                 let only_expr = e.statements().next().is_none();
                 match &e.tail_expr() {
@@ -183,7 +183,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
                     {
                         cov_mark::hit!(move_guard_ifelse_has_wildcard);
                     }
-                    _ => edit.insert(then_arm_end, format!("\n{}{} => {{}}", spaces, match_pat)),
+                    _ => edit.insert(then_arm_end, format!("\n{spaces}{match_pat} => {{}}")),
                 }
             }
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
index 7468318a594af..a7c605325ea69 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
@@ -52,7 +52,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 let mut buf = String::from("./");
                 match parent_module.name(ctx.db()) {
                     Some(name) if !parent_module.is_mod_rs(ctx.db()) => {
-                        format_to!(buf, "{}/", name)
+                        format_to!(buf, "{name}/")
                     }
                     _ => (),
                 }
@@ -82,7 +82,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 items
             };
 
-            let buf = format!("mod {};", module_name);
+            let buf = format!("mod {module_name};");
 
             let replacement_start = match module_ast.mod_token() {
                 Some(mod_token) => mod_token.text_range(),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
index a909ce8b26791..076d25411a818 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
@@ -40,11 +40,11 @@ pub(crate) fn move_to_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 
     let target = source_file.syntax().text_range();
     let module_name = module.name(ctx.db())?.to_string();
-    let path = format!("./{}/mod.rs", module_name);
+    let path = format!("./{module_name}/mod.rs");
     let dst = AnchoredPathBuf { anchor: ctx.file_id(), path };
     acc.add(
         AssistId("move_to_mod_rs", AssistKind::Refactor),
-        format!("Convert {}.rs to {}/mod.rs", module_name, module_name),
+        format!("Convert {module_name}.rs to {module_name}/mod.rs"),
         target,
         |builder| {
             builder.move_file(ctx.file_id(), dst);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
index 424db7437a743..7e3fef516bfd8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
@@ -38,7 +38,7 @@ pub(crate) fn reformat_number_literal(acc: &mut Assists, ctx: &AssistContext<'_>
     converted.push_str(suffix);
 
     let group_id = GroupLabel("Reformat number literal".into());
-    let label = format!("Convert {} to {}", literal, converted);
+    let label = format!("Convert {literal} to {converted}");
     let range = literal.syntax().text_range();
     acc.add_group(
         &group_id,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
index e57d1d065d622..1ea87429c5092 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
@@ -54,7 +54,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) ->
 
     acc.add(
         AssistId("qualify_method_call", AssistKind::RefactorInline),
-        format!("Qualify `{}` method call", ident.text()),
+        format!("Qualify `{ident}` method call"),
         range,
         |builder| {
             qualify_candidate.qualify(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
index 4b2af550bc5e4..e759e1561cbd0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
@@ -118,14 +118,14 @@ impl QualifyCandidate<'_> {
         match self {
             QualifyCandidate::QualifierStart(segment, generics) => {
                 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
-                replacer(format!("{}{}::{}", import, generics, segment));
+                replacer(format!("{import}{generics}::{segment}"));
             }
             QualifyCandidate::UnqualifiedName(generics) => {
                 let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
-                replacer(format!("{}{}", import, generics));
+                replacer(format!("{import}{generics}"));
             }
             QualifyCandidate::TraitAssocItem(qualifier, segment) => {
-                replacer(format!("<{} as {}>::{}", qualifier, import, segment));
+                replacer(format!("<{qualifier} as {import}>::{segment}"));
             }
             QualifyCandidate::TraitMethod(db, mcall_expr) => {
                 Self::qualify_trait_method(db, mcall_expr, replacer, import, item);
@@ -155,16 +155,11 @@ impl QualifyCandidate<'_> {
                 hir::Access::Exclusive => make::expr_ref(receiver, true),
                 hir::Access::Owned => receiver,
             };
-            replacer(format!(
-                "{}::{}{}{}",
-                import,
-                method_name,
-                generics,
-                match arg_list {
-                    Some(args) => make::arg_list(iter::once(receiver).chain(args)),
-                    None => make::arg_list(iter::once(receiver)),
-                }
-            ));
+            let arg_list = match arg_list {
+                Some(args) => make::arg_list(iter::once(receiver).chain(args)),
+                None => make::arg_list(iter::once(receiver)),
+            };
+            replacer(format!("{import}::{method_name}{generics}{arg_list}"));
         }
         Some(())
     }
@@ -218,15 +213,17 @@ fn group_label(candidate: &ImportCandidate) -> GroupLabel {
         }
     }
     .text();
-    GroupLabel(format!("Qualify {}", name))
+    GroupLabel(format!("Qualify {name}"))
 }
 
 fn label(candidate: &ImportCandidate, import: &LocatedImport) -> String {
+    let import_path = &import.import_path;
+
     match candidate {
         ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => {
-            format!("Qualify as `{}`", import.import_path)
+            format!("Qualify as `{import_path}`")
         }
-        _ => format!("Qualify with `{}`", import.import_path),
+        _ => format!("Qualify with `{import_path}`"),
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
index dbe8cb7bf031f..c9bc25b27a5ed 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
@@ -34,13 +34,10 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
             let hashes = "#".repeat(required_hashes(&value).max(1));
             if matches!(value, Cow::Borrowed(_)) {
                 // Avoid replacing the whole string to better position the cursor.
-                edit.insert(token.syntax().text_range().start(), format!("r{}", hashes));
+                edit.insert(token.syntax().text_range().start(), format!("r{hashes}"));
                 edit.insert(token.syntax().text_range().end(), hashes);
             } else {
-                edit.replace(
-                    token.syntax().text_range(),
-                    format!("r{}\"{}\"{}", hashes, value, hashes),
-                );
+                edit.replace(token.syntax().text_range(), format!("r{hashes}\"{value}\"{hashes}"));
             }
         },
     )
@@ -83,7 +80,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
                 }
             }
 
-            edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped));
+            edit.replace(token.syntax().text_range(), format!("\"{escaped}\""));
         },
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
index afaa7c933c739..3d9cbff177ba9 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
@@ -102,7 +102,7 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
             };
             (
                 macro_call.syntax().text_range(),
-                if wrap { format!("({})", expr) } else { expr.to_string() },
+                if wrap { format!("({expr})") } else { expr.to_string() },
             )
         }
         // dbg!(expr0, expr1, ...)
@@ -127,8 +127,8 @@ mod tests {
     fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
         check_assist(
             remove_dbg,
-            &format!("fn main() {{\n{}\n}}", ra_fixture_before),
-            &format!("fn main() {{\n{}\n}}", ra_fixture_after),
+            &format!("fn main() {{\n{ra_fixture_before}\n}}"),
+            &format!("fn main() {{\n{ra_fixture_after}\n}}"),
         );
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 9fd5e1886d206..f9ba289ee175f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -124,7 +124,7 @@ fn add_assist(
 ) -> Option<()> {
     let target = attr.syntax().text_range();
     let annotated_name = adt.name()?;
-    let label = format!("Convert to manual `impl {} for {}`", replace_trait_path, annotated_name);
+    let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`");
 
     acc.add(
         AssistId("replace_derive_with_manual_impl", AssistKind::Refactor),
@@ -158,11 +158,8 @@ fn add_assist(
                         }
                     }
 
-                    builder.insert_snippet(
-                        cap,
-                        insert_pos,
-                        format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)),
-                    )
+                    let rendered = render_snippet(cap, impl_def.syntax(), cursor);
+                    builder.insert_snippet(cap, insert_pos, format!("\n\n{rendered}"))
                 }
             };
         },
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
index 7d91be6210136..77382056c1833 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
@@ -62,7 +62,7 @@ pub(crate) fn replace_or_with_or_else(acc: &mut Assists, ctx: &AssistContext<'_>
 
     acc.add(
         AssistId("replace_or_with_or_else", AssistKind::RefactorRewrite),
-        format!("Replace {} with {}", name.text(), replace),
+        format!("Replace {name} with {replace}"),
         call.syntax().text_range(),
         |builder| {
             builder.replace(name.syntax().text_range(), replace);
@@ -138,7 +138,7 @@ pub(crate) fn replace_or_else_with_or(acc: &mut Assists, ctx: &AssistContext<'_>
 
     acc.add(
         AssistId("replace_or_else_with_or", AssistKind::RefactorRewrite),
-        format!("Replace {} with {}", name.text(), replace),
+        format!("Replace {name} with {replace}"),
         call.syntax().text_range(),
         |builder| {
             builder.replace(name.syntax().text_range(), replace);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
index 521447c26dfbe..c177adc7a10d7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
@@ -79,7 +79,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
             "Replace turbofish with explicit type",
             TextRange::new(initializer_start, turbofish_range.end()),
             |builder| {
-                builder.insert(ident_range.end(), format!(": {}", returned_type));
+                builder.insert(ident_range.end(), format!(": {returned_type}"));
                 builder.delete(turbofish_range);
             },
         );
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
index 25c58d086e977..d09614c51127e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
@@ -69,13 +69,13 @@ pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
                 for (pat, ty, expr) in
                     itertools::izip!(tuple_pat.fields(), tys.fields(), tuple_init.fields())
                 {
-                    zipped_decls.push_str(&format!("{}let {pat}: {ty} = {expr};\n", indents))
+                    zipped_decls.push_str(&format!("{indents}let {pat}: {ty} = {expr};\n"))
                 }
                 edit.replace(parent.text_range(), zipped_decls.trim());
             } else {
                 let mut zipped_decls = String::new();
                 for (pat, expr) in itertools::izip!(tuple_pat.fields(), tuple_init.fields()) {
-                    zipped_decls.push_str(&format!("{}let {pat} = {expr};\n", indents));
+                    zipped_decls.push_str(&format!("{indents}let {pat} = {expr};\n"));
                 }
                 edit.replace(parent.text_range(), zipped_decls.trim());
             }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
index 83446387db1cf..b6c489eb62eef 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
@@ -76,11 +76,11 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext<
 
             match ctx.config.snippet_cap {
                 Some(cap) => {
-                    let snippet = format!("Result<{}, ${{0:_}}>", type_ref);
+                    let snippet = format!("Result<{type_ref}, ${{0:_}}>");
                     builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet)
                 }
                 None => builder
-                    .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)),
+                    .replace(type_ref.syntax().text_range(), format!("Result<{type_ref}, _>")),
             }
         },
     )

From fe778c59ff488ebc43255944975f432005a62d5b Mon Sep 17 00:00:00 2001
From: Rongjian Zhang 
Date: Thu, 3 Nov 2022 13:17:03 +0800
Subject: [PATCH 390/482] docs: add crates section to the manual

---
 src/tools/rust-analyzer/docs/user/manual.adoc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
index c30838e5f5e1e..62e1c5b41b6d1 100644
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ b/src/tools/rust-analyzer/docs/user/manual.adoc
@@ -487,6 +487,12 @@ https://docs.helix-editor.com/[Helix] supports LSP by default.
 However, it won't install `rust-analyzer` automatically.
 You can follow instructions for installing <>.
 
+=== Crates
+
+There is a package named `ra_ap_rust_analyzer` available on [crates.io](https://crates.io/crates/ra_ap_rust-analyzer), for someone who wants to use it programmatically.
+
+For more details, see [the publish workflow](https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml).
+
 == Troubleshooting
 
 Start with looking at the rust-analyzer version.

From 9e043134bd02bbb2a2483703d01bc5f0093ccd15 Mon Sep 17 00:00:00 2001
From: Rongjian Zhang 
Date: Sun, 6 Nov 2022 01:33:57 +0800
Subject: [PATCH 391/482] docs: fix adoc links

---
 src/tools/rust-analyzer/docs/user/manual.adoc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
index 62e1c5b41b6d1..49500e390a502 100644
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ b/src/tools/rust-analyzer/docs/user/manual.adoc
@@ -489,9 +489,9 @@ You can follow instructions for installing <
Date: Wed, 9 Nov 2022 23:40:06 -0500
Subject: [PATCH 392/482] update mailmap

---
 .mailmap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.mailmap b/.mailmap
index 564a68955d301..f887d29096e03 100644
--- a/.mailmap
+++ b/.mailmap
@@ -217,7 +217,7 @@ Hsiang-Cheng Yang 
 Ian Jackson  
 Ian Jackson  
 Ian Jackson  
-Ibraheem Ahmed 
+Ibraheem Ahmed  
 Ilyong Cho 
 inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com>
 Irina Popa 

From 28de389b5f1d34e381ad832517e792437e5584c5 Mon Sep 17 00:00:00 2001
From: zhaixiaojuan 
Date: Sat, 17 Sep 2022 18:00:34 +0800
Subject: [PATCH 393/482] Add loongarch64 abi support

---
 .../rustc_target/src/abi/call/loongarch.rs    | 342 ++++++++++++++++++
 compiler/rustc_target/src/abi/call/mod.rs     |   2 +
 2 files changed, 344 insertions(+)
 create mode 100644 compiler/rustc_target/src/abi/call/loongarch.rs

diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs
new file mode 100644
index 0000000000000..d29b479de5da6
--- /dev/null
+++ b/compiler/rustc_target/src/abi/call/loongarch.rs
@@ -0,0 +1,342 @@
+use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
+use crate::abi::{self, Abi, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
+use crate::spec::HasTargetSpec;
+
+#[derive(Copy, Clone)]
+enum RegPassKind {
+    Float(Reg),
+    Integer(Reg),
+    Unknown,
+}
+
+#[derive(Copy, Clone)]
+enum FloatConv {
+    FloatPair(Reg, Reg),
+    Float(Reg),
+    MixedPair(Reg, Reg),
+}
+
+#[derive(Copy, Clone)]
+struct CannotUseFpConv;
+
+fn is_loongarch_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool {
+    match arg.layout.abi {
+        Abi::Vector { .. } => true,
+        _ => arg.layout.is_aggregate(),
+    }
+}
+
+fn should_use_fp_conv_helper<'a, Ty, C>(
+    cx: &C,
+    arg_layout: &TyAndLayout<'a, Ty>,
+    xlen: u64,
+    flen: u64,
+    field1_kind: &mut RegPassKind,
+    field2_kind: &mut RegPassKind,
+) -> Result<(), CannotUseFpConv>
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+{
+    match arg_layout.abi {
+        Abi::Scalar(scalar) => match scalar.primitive() {
+            abi::Int(..) | abi::Pointer => {
+                if arg_layout.size.bits() > xlen {
+                    return Err(CannotUseFpConv);
+                }
+                match (*field1_kind, *field2_kind) {
+                    (RegPassKind::Unknown, _) => {
+                        *field1_kind = RegPassKind::Integer(Reg {
+                            kind: RegKind::Integer,
+                            size: arg_layout.size,
+                        });
+                    }
+                    (RegPassKind::Float(_), RegPassKind::Unknown) => {
+                        *field2_kind = RegPassKind::Integer(Reg {
+                            kind: RegKind::Integer,
+                            size: arg_layout.size,
+                        });
+                    }
+                    _ => return Err(CannotUseFpConv),
+                }
+            }
+            abi::F32 | abi::F64 => {
+                if arg_layout.size.bits() > flen {
+                    return Err(CannotUseFpConv);
+                }
+                match (*field1_kind, *field2_kind) {
+                    (RegPassKind::Unknown, _) => {
+                        *field1_kind =
+                            RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size });
+                    }
+                    (_, RegPassKind::Unknown) => {
+                        *field2_kind =
+                            RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size });
+                    }
+                    _ => return Err(CannotUseFpConv),
+                }
+            }
+        },
+        Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv),
+        Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields {
+            FieldsShape::Primitive => {
+                unreachable!("aggregates can't have `FieldsShape::Primitive`")
+            }
+            FieldsShape::Union(_) => {
+                if !arg_layout.is_zst() {
+                    return Err(CannotUseFpConv);
+                }
+            }
+            FieldsShape::Array { count, .. } => {
+                for _ in 0..count {
+                    let elem_layout = arg_layout.field(cx, 0);
+                    should_use_fp_conv_helper(
+                        cx,
+                        &elem_layout,
+                        xlen,
+                        flen,
+                        field1_kind,
+                        field2_kind,
+                    )?;
+                }
+            }
+            FieldsShape::Arbitrary { .. } => {
+                match arg_layout.variants {
+                    abi::Variants::Multiple { .. } => return Err(CannotUseFpConv),
+                    abi::Variants::Single { .. } => (),
+                }
+                for i in arg_layout.fields.index_by_increasing_offset() {
+                    let field = arg_layout.field(cx, i);
+                    should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?;
+                }
+            }
+        },
+    }
+    Ok(())
+}
+
+fn should_use_fp_conv<'a, Ty, C>(
+    cx: &C,
+    arg: &TyAndLayout<'a, Ty>,
+    xlen: u64,
+    flen: u64,
+) -> Option
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+{
+    let mut field1_kind = RegPassKind::Unknown;
+    let mut field2_kind = RegPassKind::Unknown;
+    if should_use_fp_conv_helper(cx, arg, xlen, flen, &mut field1_kind, &mut field2_kind).is_err() {
+        return None;
+    }
+    match (field1_kind, field2_kind) {
+        (RegPassKind::Integer(l), RegPassKind::Float(r)) => Some(FloatConv::MixedPair(l, r)),
+        (RegPassKind::Float(l), RegPassKind::Integer(r)) => Some(FloatConv::MixedPair(l, r)),
+        (RegPassKind::Float(l), RegPassKind::Float(r)) => Some(FloatConv::FloatPair(l, r)),
+        (RegPassKind::Float(f), RegPassKind::Unknown) => Some(FloatConv::Float(f)),
+        _ => None,
+    }
+}
+
+fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+{
+    if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) {
+        match conv {
+            FloatConv::Float(f) => {
+                arg.cast_to(f);
+            }
+            FloatConv::FloatPair(l, r) => {
+                arg.cast_to(CastTarget::pair(l, r));
+            }
+            FloatConv::MixedPair(l, r) => {
+                arg.cast_to(CastTarget::pair(l, r));
+            }
+        }
+        return false;
+    }
+
+    let total = arg.layout.size;
+
+    // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
+    // the argument list with the address."
+    // "Aggregates larger than 2✕XLEN bits are passed by reference and are
+    // replaced in the argument list with the address, as are C++ aggregates
+    // with nontrivial copy constructors, destructors, or vtables."
+    if total.bits() > 2 * xlen {
+        // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN.
+        if is_loongarch_aggregate(arg) {
+            arg.make_indirect();
+        }
+        return true;
+    }
+
+    let xlen_reg = match xlen {
+        32 => Reg::i32(),
+        64 => Reg::i64(),
+        _ => unreachable!("Unsupported XLEN: {}", xlen),
+    };
+    if is_loongarch_aggregate(arg) {
+        if total.bits() <= xlen {
+            arg.cast_to(xlen_reg);
+        } else {
+            arg.cast_to(Uniform { unit: xlen_reg, total: Size::from_bits(xlen * 2) });
+        }
+        return false;
+    }
+
+    // "When passed in registers, scalars narrower than XLEN bits are widened
+    // according to the sign of their type up to 32 bits, then sign-extended to
+    // XLEN bits."
+    extend_integer_width(arg, xlen);
+    false
+}
+
+fn classify_arg<'a, Ty, C>(
+    cx: &C,
+    arg: &mut ArgAbi<'a, Ty>,
+    xlen: u64,
+    flen: u64,
+    is_vararg: bool,
+    avail_gprs: &mut u64,
+    avail_fprs: &mut u64,
+) where
+    Ty: TyAbiInterface<'a, C> + Copy,
+{
+    if !is_vararg {
+        match should_use_fp_conv(cx, &arg.layout, xlen, flen) {
+            Some(FloatConv::Float(f)) if *avail_fprs >= 1 => {
+                *avail_fprs -= 1;
+                arg.cast_to(f);
+                return;
+            }
+            Some(FloatConv::FloatPair(l, r)) if *avail_fprs >= 2 => {
+                *avail_fprs -= 2;
+                arg.cast_to(CastTarget::pair(l, r));
+                return;
+            }
+            Some(FloatConv::MixedPair(l, r)) if *avail_fprs >= 1 && *avail_gprs >= 1 => {
+                *avail_gprs -= 1;
+                *avail_fprs -= 1;
+                arg.cast_to(CastTarget::pair(l, r));
+                return;
+            }
+            _ => (),
+        }
+    }
+
+    let total = arg.layout.size;
+    let align = arg.layout.align.abi.bits();
+
+    // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
+    // the argument list with the address."
+    // "Aggregates larger than 2✕XLEN bits are passed by reference and are
+    // replaced in the argument list with the address, as are C++ aggregates
+    // with nontrivial copy constructors, destructors, or vtables."
+    if total.bits() > 2 * xlen {
+        // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN.
+        if is_loongarch_aggregate(arg) {
+            arg.make_indirect();
+        }
+        if *avail_gprs >= 1 {
+            *avail_gprs -= 1;
+        }
+        return;
+    }
+
+    let double_xlen_reg = match xlen {
+        32 => Reg::i64(),
+        64 => Reg::i128(),
+        _ => unreachable!("Unsupported XLEN: {}", xlen),
+    };
+
+    let xlen_reg = match xlen {
+        32 => Reg::i32(),
+        64 => Reg::i64(),
+        _ => unreachable!("Unsupported XLEN: {}", xlen),
+    };
+
+    if total.bits() > xlen {
+        let align_regs = align > xlen;
+        if is_loongarch_aggregate(arg) {
+            arg.cast_to(Uniform {
+                unit: if align_regs { double_xlen_reg } else { xlen_reg },
+                total: Size::from_bits(xlen * 2),
+            });
+        }
+        if align_regs && is_vararg {
+            *avail_gprs -= *avail_gprs % 2;
+        }
+        if *avail_gprs >= 2 {
+            *avail_gprs -= 2;
+        } else {
+            *avail_gprs = 0;
+        }
+        return;
+    } else if is_loongarch_aggregate(arg) {
+        arg.cast_to(xlen_reg);
+        if *avail_gprs >= 1 {
+            *avail_gprs -= 1;
+        }
+        return;
+    }
+
+    // "When passed in registers, scalars narrower than XLEN bits are widened
+    // according to the sign of their type up to 32 bits, then sign-extended to
+    // XLEN bits."
+    if *avail_gprs >= 1 {
+        extend_integer_width(arg, xlen);
+        *avail_gprs -= 1;
+    }
+}
+
+fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) {
+    if let Abi::Scalar(scalar) = arg.layout.abi {
+        if let abi::Int(i, _) = scalar.primitive() {
+            // 32-bit integers are always sign-extended
+            if i.size().bits() == 32 && xlen > 32 {
+                if let PassMode::Direct(ref mut attrs) = arg.mode {
+                    attrs.ext(ArgExtension::Sext);
+                    return;
+                }
+            }
+        }
+    }
+
+    arg.extend_integer_width_to(xlen);
+}
+
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+    C: HasDataLayout + HasTargetSpec,
+{
+    let xlen = cx.data_layout().pointer_size.bits();
+    let flen = match &cx.target_spec().llvm_abiname[..] {
+        "ilp32f" | "lp64f" => 32,
+        "ilp32d" | "lp64d" => 64,
+        _ => 0,
+    };
+
+    let mut avail_gprs = 8;
+    let mut avail_fprs = 8;
+
+    if !fn_abi.ret.is_ignore() && classify_ret(cx, &mut fn_abi.ret, xlen, flen) {
+        avail_gprs -= 1;
+    }
+
+    for (i, arg) in fn_abi.args.iter_mut().enumerate() {
+        if arg.is_ignore() {
+            continue;
+        }
+        classify_arg(
+            cx,
+            arg,
+            xlen,
+            flen,
+            i >= fn_abi.fixed_count as usize,
+            &mut avail_gprs,
+            &mut avail_fprs,
+        );
+    }
+}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 9e5f0e4d158b2..c5a6f9893b6f9 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -10,6 +10,7 @@ mod arm;
 mod avr;
 mod bpf;
 mod hexagon;
+mod loongarch;
 mod m68k;
 mod mips;
 mod mips64;
@@ -696,6 +697,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "amdgpu" => amdgpu::compute_abi_info(cx, self),
             "arm" => arm::compute_abi_info(cx, self),
             "avr" => avr::compute_abi_info(self),
+            "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
             "mips" => mips::compute_abi_info(cx, self),
             "mips64" => mips64::compute_abi_info(cx, self),

From a42071a4973dd0c15c2b3a4fbe8e72139472ba03 Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Wed, 2 Nov 2022 00:54:36 +0000
Subject: [PATCH 394/482] Use TraitEngine in more places, make FulfillmentCtxt
 constructor more private

---
 compiler/rustc_hir_typeck/src/coercion.rs                | 3 ++-
 compiler/rustc_trait_selection/src/autoderef.rs          | 4 ++--
 .../rustc_trait_selection/src/traits/chalk_fulfill.rs    | 2 +-
 .../src/traits/error_reporting/mod.rs                    | 9 +++++----
 compiler/rustc_trait_selection/src/traits/fulfill.rs     | 4 ++--
 5 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 4d8ab2c1c7ad9..71949b4211819 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -62,6 +62,7 @@ use rustc_span::{self, BytePos, DesugaringKind, Span};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
+use rustc_trait_selection::traits::TraitEngineExt as _;
 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
 
 use smallvec::{smallvec, SmallVec};
@@ -1038,7 +1039,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let Ok(ok) = coerce.coerce(source, target) else {
                 return false;
             };
-            let mut fcx = traits::FulfillmentContext::new_in_snapshot();
+            let mut fcx = >::new_in_snapshot(self.tcx);
             fcx.register_predicate_obligations(self, ok.obligations);
             fcx.select_where_possible(&self).is_empty()
         })
diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs
index 46ee2f35976a7..54c738d838975 100644
--- a/compiler/rustc_trait_selection/src/autoderef.rs
+++ b/compiler/rustc_trait_selection/src/autoderef.rs
@@ -1,6 +1,6 @@
 use crate::errors::AutoDerefReachedRecursionLimit;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::{self, TraitEngine};
+use crate::traits::{self, TraitEngine, TraitEngineExt};
 use rustc_hir as hir;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
@@ -139,7 +139,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        let mut fulfillcx = traits::FulfillmentContext::new_in_snapshot();
+        let mut fulfillcx = >::new_in_snapshot(tcx);
         let normalized_ty = fulfillcx.normalize_projection_type(
             &self.infcx,
             self.param_env,
diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
index d32a990f182dc..8f9d5eaac9d1d 100644
--- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
@@ -19,7 +19,7 @@ pub struct FulfillmentContext<'tcx> {
 }
 
 impl FulfillmentContext<'_> {
-    pub(crate) fn new() -> Self {
+    pub(super) fn new() -> Self {
         FulfillmentContext {
             obligations: FxIndexSet::default(),
             relationships: FxHashMap::default(),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index e64586407c923..98c13ffdafb02 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -3,13 +3,14 @@ pub mod on_unimplemented;
 pub mod suggestions;
 
 use super::{
-    FulfillmentContext, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
-    Obligation, ObligationCause, ObligationCauseCode, OutputTypeParameterMismatch, Overflow,
-    PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+    FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
+    ObligationCauseCode, OutputTypeParameterMismatch, Overflow, PredicateObligation,
+    SelectionContext, SelectionError, TraitNotObjectSafe,
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt, TyCtxtInferExt};
+use crate::traits::engine::TraitEngineExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::normalize::AtExt as _;
 use crate::traits::specialize::to_pretty_impl_header;
@@ -352,7 +353,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                     })
                     .to_predicate(self.tcx),
                 );
-                let mut fulfill_cx = FulfillmentContext::new_in_snapshot();
+                let mut fulfill_cx = >::new_in_snapshot(self.tcx);
                 fulfill_cx.register_predicate_obligation(self, obligation);
                 if fulfill_cx.select_all_or_error(self).is_empty() {
                     return Ok((
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index a417e1440b9ee..b486c07f354b9 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -85,7 +85,7 @@ static_assert_size!(PendingPredicateObligation<'_>, 72);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
-    pub fn new() -> FulfillmentContext<'tcx> {
+    pub(super) fn new() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
             relationships: FxHashMap::default(),
@@ -93,7 +93,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn new_in_snapshot() -> FulfillmentContext<'tcx> {
+    pub(super) fn new_in_snapshot() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
             predicates: ObligationForest::new(),
             relationships: FxHashMap::default(),

From 475dab554ec6cf3fe1ac5b9ac37016afd3c14b2c Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Thu, 10 Nov 2022 04:36:45 +0000
Subject: [PATCH 395/482] bless a chalk test

---
 src/test/ui/chalkify/trait-objects.stderr | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/test/ui/chalkify/trait-objects.stderr b/src/test/ui/chalkify/trait-objects.stderr
index 098bd2d3226e5..422d39742eb55 100644
--- a/src/test/ui/chalkify/trait-objects.stderr
+++ b/src/test/ui/chalkify/trait-objects.stderr
@@ -22,6 +22,10 @@ LL |     f(2);
    |     ^^^^ expected an `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32`
    |
    = help: the trait `Fn<(i32,)>` is not implemented for `dyn Fn(i32) -> i32`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn main() where dyn Fn(i32) -> i32: Fn<(i32,)> {
+   |           ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 3 previous errors
 

From ff7893b39821121dfc1b0f27f80a2120085211ef Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Sun, 6 Nov 2022 01:38:57 +0000
Subject: [PATCH 396/482] Suggest is_some or let when encountering Option and
 bool type mismatch

---
 compiler/rustc_hir_typeck/src/demand.rs       |  3 +-
 compiler/rustc_hir_typeck/src/expr.rs         | 12 ++++-
 .../src/fn_ctxt/suggestions.rs                | 49 ++++++++++++++++++-
 src/test/ui/suggestions/option-to-bool.rs     |  9 ++++
 src/test/ui/suggestions/option-to-bool.stderr | 16 ++++++
 5 files changed, 85 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/suggestions/option-to-bool.rs
 create mode 100644 src/test/ui/suggestions/option-to-bool.stderr

diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 16febfc46da90..7f78f5fb8a7b2 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -42,7 +42,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             || self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty)
             || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
             || self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
-            || self.suggest_into(err, expr, expr_ty, expected);
+            || self.suggest_into(err, expr, expr_ty, expected)
+            || self.suggest_option_to_bool(err, expr, expr_ty, expected);
 
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
         self.note_need_for_fn_pointer(err, expected, expr_ty);
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 43669489e69bb..e948d832e3280 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -103,8 +103,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
-            let expr = expr.peel_drop_temps();
-            self.suggest_deref_ref_or_into(&mut err, expr, expected_ty, ty, None);
+            // FIXME(compiler-errors): We probably should fold some of the
+            // `suggest_` functions from  `emit_coerce_suggestions` into here,
+            // since some of those aren't necessarily just coerce suggestions.
+            let _ = self.suggest_deref_ref_or_into(
+                &mut err,
+                expr.peel_drop_temps(),
+                expected_ty,
+                ty,
+                None,
+            ) || self.suggest_option_to_bool(&mut err, expr, ty, expected_ty);
             extend_err(&mut err);
             err.emit();
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index e3b3fb499b16a..a14759e254c49 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -13,7 +13,7 @@ use rustc_hir_analysis::astconv::AstConv;
 use rustc_infer::infer::{self, TyCtxtInferExt};
 use rustc_infer::traits::{self, StatementAsExpression};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{self, Binder, IsSuggestable, ToPredicate, Ty};
+use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
@@ -1116,6 +1116,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
+    /// When expecting a `bool` and finding an `Option`, suggests using `let Some(..)` or `.is_some()`
+    pub(crate) fn suggest_option_to_bool(
+        &self,
+        diag: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        expr_ty: Ty<'tcx>,
+        expected_ty: Ty<'tcx>,
+    ) -> bool {
+        if !expected_ty.is_bool() {
+            return false;
+        }
+
+        let ty::Adt(def, _) = expr_ty.peel_refs().kind() else { return false; };
+        if !self.tcx.is_diagnostic_item(sym::Option, def.did()) {
+            return false;
+        }
+
+        let hir = self.tcx.hir();
+        let cond_parent = hir.parent_iter(expr.hir_id).skip_while(|(_, node)| {
+            matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, _, _), .. }) if op.node == hir::BinOpKind::And)
+        }).next();
+        // Don't suggest:
+        //     `let Some(_) = a.is_some() && b`
+        //                     ++++++++++
+        // since the user probably just misunderstood how `let else`
+        // and `&&` work together.
+        if let Some((_, hir::Node::Local(local))) = cond_parent
+            && let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) = &local.pat.kind
+            && let hir::QPath::Resolved(None, path) = qpath
+            && let Some(did) = path.res.opt_def_id()
+                .and_then(|did| self.tcx.opt_parent(did))
+                .and_then(|did| self.tcx.opt_parent(did))
+            && self.tcx.is_diagnostic_item(sym::Option, did)
+        {
+            return false;
+        }
+
+        diag.span_suggestion(
+            expr.span.shrink_to_hi(),
+            "use `Option::is_some` to test if the `Option` has a value",
+            ".is_some()",
+            Applicability::MachineApplicable,
+        );
+
+        true
+    }
+
     /// Suggest wrapping the block in square brackets instead of curly braces
     /// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
     pub(crate) fn suggest_block_to_brackets(
diff --git a/src/test/ui/suggestions/option-to-bool.rs b/src/test/ui/suggestions/option-to-bool.rs
new file mode 100644
index 0000000000000..2a1823b15f589
--- /dev/null
+++ b/src/test/ui/suggestions/option-to-bool.rs
@@ -0,0 +1,9 @@
+#![cfg_attr(let_chains, feature(let_chains))]
+
+fn foo(x: Option) {
+    if true && x {}
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::is_some` to test if the `Option` has a value
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/option-to-bool.stderr b/src/test/ui/suggestions/option-to-bool.stderr
new file mode 100644
index 0000000000000..57a934b83420c
--- /dev/null
+++ b/src/test/ui/suggestions/option-to-bool.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/option-to-bool.rs:4:16
+   |
+LL |     if true && x {}
+   |                ^ expected `bool`, found enum `Option`
+   |
+   = note: expected type `bool`
+              found enum `Option`
+help: use `Option::is_some` to test if the `Option` has a value
+   |
+LL |     if true && x.is_some() {}
+   |                 ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 6b4e43b5165047cfbff735bf4db03f6e2dbd54ae Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Fri, 4 Nov 2022 13:43:13 +0100
Subject: [PATCH 397/482] Made `Hash` and `Hasher` const_trait

---
 library/core/src/hash/mod.rs | 68 +++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 24 deletions(-)

diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index aa13435e6808d..f3a60ed1d5796 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -183,6 +183,7 @@ mod sip;
 /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Hash"]
+#[const_trait]
 pub trait Hash {
     /// Feeds this value into the given [`Hasher`].
     ///
@@ -234,12 +235,19 @@ pub trait Hash {
     /// [`hash`]: Hash::hash
     /// [`hash_slice`]: Hash::hash_slice
     #[stable(feature = "hash_slice", since = "1.3.0")]
-    fn hash_slice(data: &[Self], state: &mut H)
+    fn hash_slice(data: &[Self], state: &mut H)
     where
         Self: Sized,
     {
-        for piece in data {
-            piece.hash(state);
+        //FIXME(const_iter_slice): Revert to for loop
+        //for piece in data {
+        //    piece.hash(state);
+        //}
+
+        let mut i = 0;
+        while i < data.len() {
+            data[i].hash(state);
+            i += 1;
         }
     }
 }
@@ -313,6 +321,7 @@ pub use macros::Hash;
 /// [`write_u8`]: Hasher::write_u8
 /// [`write_u32`]: Hasher::write_u32
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
 pub trait Hasher {
     /// Returns the hash value for the values written so far.
     ///
@@ -558,7 +567,8 @@ pub trait Hasher {
 }
 
 #[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
-impl Hasher for &mut H {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const Hasher for &mut H {
     fn finish(&self) -> u64 {
         (**self).finish()
     }
@@ -806,14 +816,15 @@ mod impls {
     macro_rules! impl_write {
         ($(($ty:ident, $meth:ident),)*) => {$(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Hash for $ty {
+            #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+            impl const Hash for $ty {
                 #[inline]
-                fn hash(&self, state: &mut H) {
+                fn hash(&self, state: &mut H) {
                     state.$meth(*self)
                 }
 
                 #[inline]
-                fn hash_slice(data: &[$ty], state: &mut H) {
+                fn hash_slice(data: &[$ty], state: &mut H) {
                     let newlen = data.len() * mem::size_of::<$ty>();
                     let ptr = data.as_ptr() as *const u8;
                     // SAFETY: `ptr` is valid and aligned, as this macro is only used
@@ -842,33 +853,37 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for bool {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for bool {
         #[inline]
-        fn hash(&self, state: &mut H) {
+        fn hash(&self, state: &mut H) {
             state.write_u8(*self as u8)
         }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for char {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for char {
         #[inline]
-        fn hash(&self, state: &mut H) {
+        fn hash(&self, state: &mut H) {
             state.write_u32(*self as u32)
         }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for str {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for str {
         #[inline]
-        fn hash(&self, state: &mut H) {
+        fn hash(&self, state: &mut H) {
             state.write_str(self);
         }
     }
 
     #[stable(feature = "never_hash", since = "1.29.0")]
-    impl Hash for ! {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for ! {
         #[inline]
-        fn hash(&self, _: &mut H) {
+        fn hash(&self, _: &mut H) {
             *self
         }
     }
@@ -876,9 +891,10 @@ mod impls {
     macro_rules! impl_hash_tuple {
         () => (
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Hash for () {
+            #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+            impl const Hash for () {
                 #[inline]
-                fn hash(&self, _state: &mut H) {}
+                fn hash(&self, _state: &mut H) {}
             }
         );
 
@@ -886,10 +902,11 @@ mod impls {
             maybe_tuple_doc! {
                 $($name)+ @
                 #[stable(feature = "rust1", since = "1.0.0")]
-                impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
+                #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+                impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
                     #[allow(non_snake_case)]
                     #[inline]
-                    fn hash(&self, state: &mut S) {
+                    fn hash(&self, state: &mut S) {
                         let ($(ref $name,)+) = *self;
                         $($name.hash(state);)+
                     }
@@ -932,24 +949,27 @@ mod impls {
     impl_hash_tuple! { T B C D E F G H I J K L }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for [T] {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for [T] {
         #[inline]
-        fn hash(&self, state: &mut H) {
+        fn hash(&self, state: &mut H) {
             state.write_length_prefix(self.len());
             Hash::hash_slice(self, state)
         }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for &T {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for &T {
         #[inline]
-        fn hash(&self, state: &mut H) {
+        fn hash(&self, state: &mut H) {
             (**self).hash(state);
         }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for &mut T {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    impl const Hash for &mut T {
         #[inline]
         fn hash(&self, state: &mut H) {
             (**self).hash(state);

From e8b95e9c4be5997f866f32c09087c94c8463fe79 Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Fri, 4 Nov 2022 21:30:39 +0100
Subject: [PATCH 398/482] Make `BuildHasher` const_trait

---
 library/core/src/hash/mod.rs | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index f3a60ed1d5796..b66475e43ac5f 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -86,7 +86,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
-use crate::marker;
+use crate::marker::{self, Destruct};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
@@ -648,6 +648,7 @@ impl const Hasher for &mut H {
 /// [`build_hasher`]: BuildHasher::build_hasher
 /// [`HashMap`]: ../../std/collections/struct.HashMap.html
 #[stable(since = "1.7.0", feature = "build_hasher")]
+#[const_trait]
 pub trait BuildHasher {
     /// Type of the hasher that will be created.
     #[stable(since = "1.7.0", feature = "build_hasher")]
@@ -708,9 +709,10 @@ pub trait BuildHasher {
     /// );
     /// ```
     #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")]
-    fn hash_one(&self, x: T) -> u64
+    fn hash_one(&self, x: T) -> u64
     where
         Self: Sized,
+        Self::Hasher: ~const Hasher + ~const Destruct,
     {
         let mut hasher = self.build_hasher();
         x.hash(&mut hasher);
@@ -774,7 +776,8 @@ impl fmt::Debug for BuildHasherDefault {
 }
 
 #[stable(since = "1.7.0", feature = "build_hasher")]
-impl BuildHasher for BuildHasherDefault {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const BuildHasher for BuildHasherDefault {
     type Hasher = H;
 
     fn build_hasher(&self) -> H {

From 1b84e4ab0f5aa31ed63e7ed162b8ea8c3d59ff86 Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Sun, 6 Nov 2022 17:46:38 +0100
Subject: [PATCH 399/482] Made `Sip` const `Hasher`

---
 library/core/src/hash/sip.rs            | 38 ++++++++++++++++---------
 library/core/src/lib.rs                 |  1 +
 library/std/src/collections/hash/map.rs |  9 ++++--
 library/std/src/lib.rs                  |  1 +
 4 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 81bf1dfdf4510..b389ae4a01995 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -118,7 +118,7 @@ macro_rules! load_int_le {
 /// Safety: this performs unchecked indexing of `buf` at `start..start+len`, so
 /// that must be in-bounds.
 #[inline]
-unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+const unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
     debug_assert!(len < 8);
     let mut i = 0; // current byte index (from LSB) in the output u64
     let mut out = 0;
@@ -138,7 +138,7 @@ unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
         out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << (i * 8);
         i += 1;
     }
-    debug_assert_eq!(i, len);
+    debug_assert!(i == len);
     out
 }
 
@@ -150,8 +150,9 @@ impl SipHasher {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
     #[must_use]
-    pub fn new() -> SipHasher {
+    pub const fn new() -> SipHasher {
         SipHasher::new_with_keys(0, 0)
     }
 
@@ -162,8 +163,9 @@ impl SipHasher {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
     #[must_use]
-    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
+    pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
         SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
     }
 }
@@ -176,7 +178,8 @@ impl SipHasher13 {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    pub fn new() -> SipHasher13 {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    pub const fn new() -> SipHasher13 {
         SipHasher13::new_with_keys(0, 0)
     }
 
@@ -187,14 +190,15 @@ impl SipHasher13 {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
         SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
     }
 }
 
 impl Hasher {
     #[inline]
-    fn new_with_keys(key0: u64, key1: u64) -> Hasher {
+    const fn new_with_keys(key0: u64, key1: u64) -> Hasher {
         let mut state = Hasher {
             k0: key0,
             k1: key1,
@@ -209,7 +213,7 @@ impl Hasher {
     }
 
     #[inline]
-    fn reset(&mut self) {
+    const fn reset(&mut self) {
         self.length = 0;
         self.state.v0 = self.k0 ^ 0x736f6d6570736575;
         self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
@@ -220,7 +224,8 @@ impl Hasher {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl super::Hasher for SipHasher {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const super::Hasher for SipHasher {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
         self.0.hasher.write(msg)
@@ -238,7 +243,11 @@ impl super::Hasher for SipHasher {
 }
 
 #[unstable(feature = "hashmap_internals", issue = "none")]
-impl super::Hasher for SipHasher13 {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const super::Hasher for SipHasher13
+where
+    Hasher: ~const super::Hasher,
+{
     #[inline]
     fn write(&mut self, msg: &[u8]) {
         self.hasher.write(msg)
@@ -255,7 +264,7 @@ impl super::Hasher for SipHasher13 {
     }
 }
 
-impl super::Hasher for Hasher {
+impl const super::Hasher for Hasher {
     // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined
     // for this type. We could add them, copy the `short_write` implementation
     // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*`
@@ -335,7 +344,7 @@ impl super::Hasher for Hasher {
     }
 }
 
-impl Clone for Hasher {
+impl const Clone for Hasher {
     #[inline]
     fn clone(&self) -> Hasher {
         Hasher {
@@ -359,6 +368,7 @@ impl Default for Hasher {
 }
 
 #[doc(hidden)]
+#[const_trait]
 trait Sip {
     fn c_rounds(_: &mut State);
     fn d_rounds(_: &mut State);
@@ -367,7 +377,7 @@ trait Sip {
 #[derive(Debug, Clone, Default)]
 struct Sip13Rounds;
 
-impl Sip for Sip13Rounds {
+impl const Sip for Sip13Rounds {
     #[inline]
     fn c_rounds(state: &mut State) {
         compress!(state);
@@ -384,7 +394,7 @@ impl Sip for Sip13Rounds {
 #[derive(Debug, Clone, Default)]
 struct Sip24Rounds;
 
-impl Sip for Sip24Rounds {
+impl const Sip for Sip24Rounds {
     #[inline]
     fn c_rounds(state: &mut State) {
         compress!(state);
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 659409557c910..5dc7427bee003 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -112,6 +112,7 @@
 #![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
 #![feature(const_fmt_arguments_new)]
+#![feature(const_hash)]
 #![feature(const_heap)]
 #![feature(const_convert)]
 #![feature(const_index_range_slice_index)]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 708edc5de4751..1963c24b6e94d 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -3161,14 +3161,16 @@ impl DefaultHasher {
     #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
     #[inline]
     #[allow(deprecated)]
+    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
     #[must_use]
-    pub fn new() -> DefaultHasher {
+    pub const fn new() -> DefaultHasher {
         DefaultHasher(SipHasher13::new_with_keys(0, 0))
     }
 }
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-impl Default for DefaultHasher {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const Default for DefaultHasher {
     /// Creates a new `DefaultHasher` using [`new`].
     /// See its documentation for more.
     ///
@@ -3180,7 +3182,8 @@ impl Default for DefaultHasher {
 }
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-impl Hasher for DefaultHasher {
+#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+impl const Hasher for DefaultHasher {
     // The underlying `SipHasher13` doesn't override the other
     // `write_*` methods, so it's ok not to forward them here.
 
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 385585dada896..8aa0424bc4bf0 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -314,6 +314,7 @@
 #![feature(maybe_uninit_uninit_array)]
 #![feature(const_maybe_uninit_uninit_array)]
 #![feature(const_waker)]
+#![feature(const_hash)]
 //
 // Library features (alloc):
 #![feature(alloc_layout_extra)]

From c2cf9d5e84a6964cb874894ebf0669ac40aa50cb Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Sun, 6 Nov 2022 18:01:44 +0100
Subject: [PATCH 400/482] Added `const_hash` tracking issue id

---
 library/core/src/hash/mod.rs            | 24 ++++++++++++------------
 library/core/src/hash/sip.rs            | 12 ++++++------
 library/std/src/collections/hash/map.rs |  6 +++---
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index b66475e43ac5f..d8bb92fcc8d50 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -567,7 +567,7 @@ pub trait Hasher {
 }
 
 #[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const Hasher for &mut H {
     fn finish(&self) -> u64 {
         (**self).finish()
@@ -776,7 +776,7 @@ impl fmt::Debug for BuildHasherDefault {
 }
 
 #[stable(since = "1.7.0", feature = "build_hasher")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const BuildHasher for BuildHasherDefault {
     type Hasher = H;
 
@@ -819,7 +819,7 @@ mod impls {
     macro_rules! impl_write {
         ($(($ty:ident, $meth:ident),)*) => {$(
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+            #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
             impl const Hash for $ty {
                 #[inline]
                 fn hash(&self, state: &mut H) {
@@ -856,7 +856,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for bool {
         #[inline]
         fn hash(&self, state: &mut H) {
@@ -865,7 +865,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for char {
         #[inline]
         fn hash(&self, state: &mut H) {
@@ -874,7 +874,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for str {
         #[inline]
         fn hash(&self, state: &mut H) {
@@ -883,7 +883,7 @@ mod impls {
     }
 
     #[stable(feature = "never_hash", since = "1.29.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for ! {
         #[inline]
         fn hash(&self, _: &mut H) {
@@ -894,7 +894,7 @@ mod impls {
     macro_rules! impl_hash_tuple {
         () => (
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+            #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
             impl const Hash for () {
                 #[inline]
                 fn hash(&self, _state: &mut H) {}
@@ -905,7 +905,7 @@ mod impls {
             maybe_tuple_doc! {
                 $($name)+ @
                 #[stable(feature = "rust1", since = "1.0.0")]
-                #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+                #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
                 impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
                     #[allow(non_snake_case)]
                     #[inline]
@@ -952,7 +952,7 @@ mod impls {
     impl_hash_tuple! { T B C D E F G H I J K L }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for [T] {
         #[inline]
         fn hash(&self, state: &mut H) {
@@ -962,7 +962,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for &T {
         #[inline]
         fn hash(&self, state: &mut H) {
@@ -971,7 +971,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     impl const Hash for &mut T {
         #[inline]
         fn hash(&self, state: &mut H) {
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index b389ae4a01995..51581d2108951 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -150,7 +150,7 @@ impl SipHasher {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     #[must_use]
     pub const fn new() -> SipHasher {
         SipHasher::new_with_keys(0, 0)
@@ -163,7 +163,7 @@ impl SipHasher {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     #[must_use]
     pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
         SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
@@ -178,7 +178,7 @@ impl SipHasher13 {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     pub const fn new() -> SipHasher13 {
         SipHasher13::new_with_keys(0, 0)
     }
@@ -190,7 +190,7 @@ impl SipHasher13 {
         since = "1.13.0",
         note = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
         SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
     }
@@ -224,7 +224,7 @@ impl Hasher {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const super::Hasher for SipHasher {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
@@ -243,7 +243,7 @@ impl const super::Hasher for SipHasher {
 }
 
 #[unstable(feature = "hashmap_internals", issue = "none")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const super::Hasher for SipHasher13
 where
     Hasher: ~const super::Hasher,
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 1963c24b6e94d..df490358827e7 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -3161,7 +3161,7 @@ impl DefaultHasher {
     #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
     #[inline]
     #[allow(deprecated)]
-    #[rustc_const_unstable(feature = "const_hash", issue = "none")]
+    #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
     #[must_use]
     pub const fn new() -> DefaultHasher {
         DefaultHasher(SipHasher13::new_with_keys(0, 0))
@@ -3169,7 +3169,7 @@ impl DefaultHasher {
 }
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const Default for DefaultHasher {
     /// Creates a new `DefaultHasher` using [`new`].
     /// See its documentation for more.
@@ -3182,7 +3182,7 @@ impl const Default for DefaultHasher {
 }
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
-#[rustc_const_unstable(feature = "const_hash", issue = "none")]
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
 impl const Hasher for DefaultHasher {
     // The underlying `SipHasher13` doesn't override the other
     // `write_*` methods, so it's ok not to forward them here.

From 5a9a07c2167e0ea777bc6924d1f7efb09e6e1067 Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Mon, 7 Nov 2022 15:34:43 +0100
Subject: [PATCH 401/482] Removed unnecessary Trait bound

---
 library/core/src/hash/sip.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 51581d2108951..0dea1c43f200f 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -244,10 +244,7 @@ impl const super::Hasher for SipHasher {
 
 #[unstable(feature = "hashmap_internals", issue = "none")]
 #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
-impl const super::Hasher for SipHasher13
-where
-    Hasher: ~const super::Hasher,
-{
+impl const super::Hasher for SipHasher13 {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
         self.hasher.write(msg)

From 10bdb849c4f29c2d3307a375369c7d10dae59c41 Mon Sep 17 00:00:00 2001
From: onestacked 
Date: Tue, 8 Nov 2022 17:39:40 +0100
Subject: [PATCH 402/482] Test const `Hash`, fix nits

---
 library/core/src/hash/mod.rs   | 24 +++++++++++++--------
 library/core/src/hash/sip.rs   |  1 +
 library/core/tests/hash/mod.rs | 38 +++++++++++++++++++++++++---------
 library/core/tests/hash/sip.rs | 15 +++++++++++++-
 library/core/tests/lib.rs      |  1 +
 library/std/src/lib.rs         |  2 +-
 6 files changed, 60 insertions(+), 21 deletions(-)

diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index d8bb92fcc8d50..c755afa39eb60 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -86,6 +86,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
+use crate::intrinsics::const_eval_select;
 use crate::marker::{self, Destruct};
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -239,16 +240,21 @@ pub trait Hash {
     where
         Self: Sized,
     {
-        //FIXME(const_iter_slice): Revert to for loop
-        //for piece in data {
-        //    piece.hash(state);
-        //}
-
-        let mut i = 0;
-        while i < data.len() {
-            data[i].hash(state);
-            i += 1;
+        //FIXME(const_trait_impl): revert to only a for loop
+        fn rt(data: &[T], state: &mut H) {
+            for piece in data {
+                piece.hash(state)
+            }
+        }
+        const fn ct(data: &[T], state: &mut H) {
+            let mut i = 0;
+            while i < data.len() {
+                data[i].hash(state);
+                i += 1;
+            }
         }
+        // SAFETY: same behavior, CT just uses while instead of for
+        unsafe { const_eval_select((data, state), ct, rt) };
     }
 }
 
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 0dea1c43f200f..7f8287bf56f64 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -138,6 +138,7 @@ const unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
         out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << (i * 8);
         i += 1;
     }
+    //FIXME(fee1-dead): use debug_assert_eq
     debug_assert!(i == len);
     out
 }
diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs
index f7934d062a379..267245f05dcd2 100644
--- a/library/core/tests/hash/mod.rs
+++ b/library/core/tests/hash/mod.rs
@@ -9,16 +9,19 @@ struct MyHasher {
     hash: u64,
 }
 
-impl Default for MyHasher {
+impl const Default for MyHasher {
     fn default() -> MyHasher {
         MyHasher { hash: 0 }
     }
 }
 
-impl Hasher for MyHasher {
+impl const Hasher for MyHasher {
     fn write(&mut self, buf: &[u8]) {
-        for byte in buf {
-            self.hash += *byte as u64;
+        // FIXME(const_trait_impl): change to for loop
+        let mut i = 0;
+        while i < buf.len() {
+            self.hash += buf[i] as u64;
+            i += 1;
         }
     }
     fn write_str(&mut self, s: &str) {
@@ -32,12 +35,25 @@ impl Hasher for MyHasher {
 
 #[test]
 fn test_writer_hasher() {
-    fn hash(t: &T) -> u64 {
+    const fn hash(t: &T) -> u64 {
         let mut s = MyHasher { hash: 0 };
         t.hash(&mut s);
         s.finish()
     }
 
+    const {
+        // FIXME(fee1-dead): assert_eq
+        assert!(hash(&()) == 0);
+        assert!(hash(&5_u8) == 5);
+        assert!(hash(&5_u16) == 5);
+        assert!(hash(&5_u32) == 5);
+
+        assert!(hash(&'a') == 97);
+
+        let s: &str = "a";
+        assert!(hash(&s) == 97 + 0xFF);
+    };
+
     assert_eq!(hash(&()), 0);
 
     assert_eq!(hash(&5_u8), 5);
@@ -97,7 +113,7 @@ struct CustomHasher {
     output: u64,
 }
 
-impl Hasher for CustomHasher {
+impl const Hasher for CustomHasher {
     fn finish(&self) -> u64 {
         self.output
     }
@@ -109,27 +125,29 @@ impl Hasher for CustomHasher {
     }
 }
 
-impl Default for CustomHasher {
+impl const Default for CustomHasher {
     fn default() -> CustomHasher {
         CustomHasher { output: 0 }
     }
 }
 
-impl Hash for Custom {
-    fn hash(&self, state: &mut H) {
+impl const Hash for Custom {
+    fn hash(&self, state: &mut H) {
         state.write_u64(self.hash);
     }
 }
 
 #[test]
 fn test_custom_state() {
-    fn hash(t: &T) -> u64 {
+    const fn hash(t: &T) -> u64 {
         let mut c = CustomHasher { output: 0 };
         t.hash(&mut c);
         c.finish()
     }
 
     assert_eq!(hash(&Custom { hash: 5 }), 5);
+
+    const { assert!(hash(&Custom { hash: 6 }) == 6) };
 }
 
 // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten.
diff --git a/library/core/tests/hash/sip.rs b/library/core/tests/hash/sip.rs
index 877d084183055..3abf6efcfa9ba 100644
--- a/library/core/tests/hash/sip.rs
+++ b/library/core/tests/hash/sip.rs
@@ -8,7 +8,6 @@ use core::{mem, slice};
 struct Bytes<'a>(&'a [u8]);
 
 impl<'a> Hash for Bytes<'a> {
-    #[allow(unused_must_use)]
     fn hash(&self, state: &mut H) {
         let Bytes(v) = *self;
         state.write(v);
@@ -24,6 +23,20 @@ fn hash(x: &T) -> u64 {
     hash_with(SipHasher::new(), x)
 }
 
+#[test]
+const fn test_const_sip() {
+    let val1 = 0x45;
+    let val2 = 0xfeed;
+
+    const fn const_hash(x: &T) -> u64 {
+        let mut st = SipHasher::new();
+        x.hash(&mut st);
+        st.finish()
+    }
+
+    assert!(const_hash(&(val1)) != const_hash(&(val2)));
+}
+
 #[test]
 #[allow(unused_must_use)]
 fn test_siphash_1_3() {
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index a7db2a02bd743..61d31b3448734 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -11,6 +11,7 @@
 #![feature(const_caller_location)]
 #![feature(const_cell_into_inner)]
 #![feature(const_convert)]
+#![feature(const_hash)]
 #![feature(const_heap)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init_read)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 8aa0424bc4bf0..9334c833bb650 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -314,7 +314,6 @@
 #![feature(maybe_uninit_uninit_array)]
 #![feature(const_maybe_uninit_uninit_array)]
 #![feature(const_waker)]
-#![feature(const_hash)]
 //
 // Library features (alloc):
 #![feature(alloc_layout_extra)]
@@ -353,6 +352,7 @@
 //
 // Only for const-ness:
 #![feature(const_collections_with_hasher)]
+#![feature(const_hash)]
 #![feature(const_io_structs)]
 #![feature(const_ip)]
 #![feature(const_ipv4)]

From bd63d0a6c22031d592f969d72e0d59a10fea90b6 Mon Sep 17 00:00:00 2001
From: Nicholas Bishop 
Date: Sun, 6 Nov 2022 17:29:46 -0500
Subject: [PATCH 403/482] Use aapcs for efiapi calling convention on arm

On arm, llvm treats the C calling convention as `aapcs` on soft-float
targets and `aapcs-vfp` on hard-float targets [1]. UEFI specifies in the
arm calling convention that floating point extensions aren't used [2],
so always translate `efiapi` to `aapcs` on arm.

[1]: https://github.com/rust-lang/compiler-builtins/issues/116#issuecomment-261057422
[2]: https://uefi.org/specs/UEFI/2.10/02_Overview.html#detailed-calling-convention

https://github.com/rust-lang/rust/issues/65815
---
 compiler/rustc_target/src/spec/mod.rs | 1 +
 src/test/codegen/abi-efiapi.rs        | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1bcb02ecb3053..77d9a0920036a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1911,6 +1911,7 @@ impl Target {
                 Abi::Stdcall { unwind }
             }
             Abi::System { unwind } => Abi::C { unwind },
+            Abi::EfiApi if self.arch == "arm" => Abi::Aapcs { unwind: false },
             Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false },
             Abi::EfiApi => Abi::C { unwind: false },
 
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index b4fda5f8c8428..9061d7432a3fa 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -27,7 +27,7 @@ trait Copy { }
 //x86_64: define win64cc void @has_efiapi
 //i686: define void @has_efiapi
 //aarch64: define dso_local void @has_efiapi
-//arm: define dso_local void @has_efiapi
+//arm: define dso_local arm_aapcscc void @has_efiapi
 //riscv: define dso_local void @has_efiapi
 #[no_mangle]
 pub extern "efiapi" fn has_efiapi() {}

From 57c69e0ec85e982eb20f99440f296c84eb76ca1b Mon Sep 17 00:00:00 2001
From: yukang 
Date: Wed, 9 Nov 2022 16:43:37 +0800
Subject: [PATCH 404/482] Fix #104086, Tighten the 'introduce new binding'
 suggestion

---
 .../rustc_resolve/src/late/diagnostics.rs     | 25 ++++--
 .../suggestions/issue-104086-suggest-let.rs   | 10 +++
 .../issue-104086-suggest-let.stderr           | 81 +++++++++++++++++++
 3 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 src/test/ui/suggestions/issue-104086-suggest-let.rs
 create mode 100644 src/test/ui/suggestions/issue-104086-suggest-let.stderr

diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index cdc28db13f3ac..7bd94da42abc7 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1810,18 +1810,27 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         false
     }
 
-    fn let_binding_suggestion(&self, err: &mut Diagnostic, ident_span: Span) -> bool {
+    fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
         // try to give a suggestion for this pattern: `name = 1`, which is common in other languages
         let mut added_suggestion = false;
-        if let Some(Expr { kind: ExprKind::Assign(lhs, _rhs, _), .. }) = self.diagnostic_metadata.in_assignment &&
-            let ast::ExprKind::Path(None, _) = lhs.kind {
+        if let Some(Expr { kind: ExprKind::Assign(lhs, rhs, _), .. }) =
+            self.diagnostic_metadata.in_assignment
+        {
+            let is_rhs_assign = match rhs.kind {
+                ExprKind::Assign(..) => true,
+                _ => false,
+            };
+
+            if let ast::ExprKind::Path(None, _) = lhs.kind && !is_rhs_assign {
                 let sm = self.r.session.source_map();
                 let line_span = sm.span_extend_to_line(ident_span);
                 let ident_name = sm.span_to_snippet(ident_span).unwrap();
-                // HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros
-                if sm
-                    .span_to_snippet(line_span)
-                    .map_or(false, |s| s.trim().starts_with(&ident_name))
+                // HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros,
+                // and avoid some special cases like `x = x = x`
+                if let Ok(line) = sm.span_to_snippet(line_span) &&
+                    let stripped = line.split_whitespace().collect::() &&
+                    stripped.trim().starts_with(&ident_name) &&
+                    stripped.matches(&format!("{}=", &ident_name)).count() == 1
                 {
                     err.span_suggestion_verbose(
                         ident_span.shrink_to_lo(),
@@ -1832,6 +1841,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     added_suggestion = true;
                 }
             }
+            self.diagnostic_metadata.in_assignment = None;
+        }
         added_suggestion
     }
 
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.rs b/src/test/ui/suggestions/issue-104086-suggest-let.rs
new file mode 100644
index 0000000000000..e23109a3be69c
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.rs
@@ -0,0 +1,10 @@
+// error-pattern: not found in this scope
+
+fn main() {
+    x = x = x;
+    x = y = y = y;
+    x = y = y;
+    x = x = y;
+    x = x; // will suggest add `let`
+    x = y // will suggest add `let`
+}
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.stderr b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
new file mode 100644
index 0000000000000..2af9c142ec69e
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
@@ -0,0 +1,81 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:4:5
+   |
+LL |     x = x = x;
+   |     ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:4:9
+   |
+LL |     x = x = x;
+   |         ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:4:13
+   |
+LL |     x = x = x;
+   |             ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:5:5
+   |
+LL |     x = y = y = y;
+   |     ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:5:9
+   |
+LL |     x = y = y = y;
+   |         ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:5:13
+   |
+LL |     x = y = y = y;
+   |             ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:5:17
+   |
+LL |     x = y = y = y;
+   |                 ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:6:5
+   |
+LL |     x = y = y;
+   |     ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:6:9
+   |
+LL |     x = y = y;
+   |         ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:6:13
+   |
+LL |     x = y = y;
+   |             ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:7:5
+   |
+LL |     x = x = y;
+   |     ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:7:9
+   |
+LL |     x = x = y;
+   |         ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:7:13
+   |
+LL |     x = x = y;
+   |             ^ not found in this scope
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0425`.

From b56950f1d472c6d94679597ec0c8317ef8cf9c5b Mon Sep 17 00:00:00 2001
From: yukang 
Date: Wed, 9 Nov 2022 17:10:33 +0800
Subject: [PATCH 405/482] fix tests and code cleanup

---
 .../rustc_resolve/src/late/diagnostics.rs     |  6 +-
 .../suggestions/issue-104086-suggest-let.rs   | 24 ++++++-
 .../issue-104086-suggest-let.stderr           | 62 ++++++++++++++-----
 3 files changed, 71 insertions(+), 21 deletions(-)

diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 7bd94da42abc7..8bc820120d6be 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1816,11 +1816,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         if let Some(Expr { kind: ExprKind::Assign(lhs, rhs, _), .. }) =
             self.diagnostic_metadata.in_assignment
         {
-            let is_rhs_assign = match rhs.kind {
-                ExprKind::Assign(..) => true,
-                _ => false,
-            };
-
+            let is_rhs_assign = matches!(rhs.kind, ExprKind::Assign(..));
             if let ast::ExprKind::Path(None, _) = lhs.kind && !is_rhs_assign {
                 let sm = self.r.session.source_map();
                 let line_span = sm.span_extend_to_line(ident_span);
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.rs b/src/test/ui/suggestions/issue-104086-suggest-let.rs
index e23109a3be69c..d22ad27d0e031 100644
--- a/src/test/ui/suggestions/issue-104086-suggest-let.rs
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.rs
@@ -1,10 +1,30 @@
-// error-pattern: not found in this scope
-
 fn main() {
     x = x = x;
+    //~^ ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `x` in this scope
+
     x = y = y = y;
+    //~^ ERROR cannot find value `y` in this scope
+    //~| ERROR cannot find value `y` in this scope
+    //~| ERROR cannot find value `y` in this scope
+    //~| ERROR cannot find value `x` in this scope
+
     x = y = y;
+    //~^ ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `y` in this scope
+    //~| ERROR cannot find value `y` in this scope
+
     x = x = y;
+    //~^ ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `y` in this scope
+
     x = x; // will suggest add `let`
+    //~^ ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `x` in this scope
+
     x = y // will suggest add `let`
+    //~^ ERROR cannot find value `x` in this scope
+    //~| ERROR cannot find value `y` in this scope
 }
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.stderr b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
index 2af9c142ec69e..d37a18f005fda 100644
--- a/src/test/ui/suggestions/issue-104086-suggest-let.stderr
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
@@ -1,81 +1,115 @@
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:4:5
+  --> $DIR/issue-104086-suggest-let.rs:2:5
    |
 LL |     x = x = x;
    |     ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:4:9
+  --> $DIR/issue-104086-suggest-let.rs:2:9
    |
 LL |     x = x = x;
    |         ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:4:13
+  --> $DIR/issue-104086-suggest-let.rs:2:13
    |
 LL |     x = x = x;
    |             ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:5:5
+  --> $DIR/issue-104086-suggest-let.rs:7:5
    |
 LL |     x = y = y = y;
    |     ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:5:9
+  --> $DIR/issue-104086-suggest-let.rs:7:9
    |
 LL |     x = y = y = y;
    |         ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:5:13
+  --> $DIR/issue-104086-suggest-let.rs:7:13
    |
 LL |     x = y = y = y;
    |             ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:5:17
+  --> $DIR/issue-104086-suggest-let.rs:7:17
    |
 LL |     x = y = y = y;
    |                 ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:6:5
+  --> $DIR/issue-104086-suggest-let.rs:13:5
    |
 LL |     x = y = y;
    |     ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:6:9
+  --> $DIR/issue-104086-suggest-let.rs:13:9
    |
 LL |     x = y = y;
    |         ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:6:13
+  --> $DIR/issue-104086-suggest-let.rs:13:13
    |
 LL |     x = y = y;
    |             ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:7:5
+  --> $DIR/issue-104086-suggest-let.rs:18:5
    |
 LL |     x = x = y;
    |     ^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:7:9
+  --> $DIR/issue-104086-suggest-let.rs:18:9
    |
 LL |     x = x = y;
    |         ^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/issue-104086-suggest-let.rs:7:13
+  --> $DIR/issue-104086-suggest-let.rs:18:13
    |
 LL |     x = x = y;
    |             ^ not found in this scope
 
-error: aborting due to 13 previous errors
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:23:5
+   |
+LL |     x = x; // will suggest add `let`
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = x; // will suggest add `let`
+   |     +++
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:23:9
+   |
+LL |     x = x; // will suggest add `let`
+   |         ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:27:5
+   |
+LL |     x = y // will suggest add `let`
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = y // will suggest add `let`
+   |     +++
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/issue-104086-suggest-let.rs:27:9
+   |
+LL |     x = y // will suggest add `let`
+   |         ^ not found in this scope
+
+error: aborting due to 17 previous errors
 
 For more information about this error, try `rustc --explain E0425`.

From 6914a4555b43fca6e3841fea6b9956db7ff92b5d Mon Sep 17 00:00:00 2001
From: yukang 
Date: Wed, 9 Nov 2022 22:00:22 +0800
Subject: [PATCH 406/482] add 'is_assign_rhs' to avoid weird suggesting 'let'

---
 compiler/rustc_resolve/src/late.rs            | 14 +++++++---
 .../rustc_resolve/src/late/diagnostics.rs     | 28 +++++--------------
 .../issue-104086-suggest-let.stderr           | 28 ++++++++++++++++---
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 6d2ee25df320d..ede67813883d6 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -527,6 +527,7 @@ struct DiagnosticMetadata<'ast> {
 
     /// Used to detect possible new binding written without `let` and to provide structured suggestion.
     in_assignment: Option<&'ast Expr>,
+    is_assign_rhs: bool,
 
     /// If we are currently in a trait object definition. Used to point at the bounds when
     /// encountering a struct or enum.
@@ -3963,10 +3964,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 self.resolve_expr(elem, Some(expr));
                 self.visit_expr(idx);
             }
-            ExprKind::Assign(..) => {
-                let old = self.diagnostic_metadata.in_assignment.replace(expr);
-                visit::walk_expr(self, expr);
-                self.diagnostic_metadata.in_assignment = old;
+            ExprKind::Assign(ref lhs, ref rhs, _) => {
+                if !self.diagnostic_metadata.is_assign_rhs {
+                    self.diagnostic_metadata.in_assignment = Some(expr);
+                }
+                self.visit_expr(lhs);
+                self.diagnostic_metadata.is_assign_rhs = true;
+                self.diagnostic_metadata.in_assignment = None;
+                self.visit_expr(rhs);
+                self.diagnostic_metadata.is_assign_rhs = false;
             }
             _ => {
                 visit::walk_expr(self, expr);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 8bc820120d6be..2587a9c4b3498 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1810,36 +1810,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         false
     }
 
+    // try to give a suggestion for this pattern: `name = blah`, which is common in other languages
+    // suggest `let name = blah` to introduce a new binding
     fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
-        // try to give a suggestion for this pattern: `name = 1`, which is common in other languages
-        let mut added_suggestion = false;
-        if let Some(Expr { kind: ExprKind::Assign(lhs, rhs, _), .. }) =
-            self.diagnostic_metadata.in_assignment
-        {
-            let is_rhs_assign = matches!(rhs.kind, ExprKind::Assign(..));
-            if let ast::ExprKind::Path(None, _) = lhs.kind && !is_rhs_assign {
-                let sm = self.r.session.source_map();
-                let line_span = sm.span_extend_to_line(ident_span);
-                let ident_name = sm.span_to_snippet(ident_span).unwrap();
-                // HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros,
-                // and avoid some special cases like `x = x = x`
-                if let Ok(line) = sm.span_to_snippet(line_span) &&
-                    let stripped = line.split_whitespace().collect::() &&
-                    stripped.trim().starts_with(&ident_name) &&
-                    stripped.matches(&format!("{}=", &ident_name)).count() == 1
-                {
+        if let Some(Expr { kind: ExprKind::Assign(lhs, .. ), .. }) = self.diagnostic_metadata.in_assignment &&
+            let ast::ExprKind::Path(None, _) = lhs.kind {
+                if !ident_span.from_expansion() {
                     err.span_suggestion_verbose(
                         ident_span.shrink_to_lo(),
                         "you might have meant to introduce a new binding",
                         "let ".to_string(),
                         Applicability::MaybeIncorrect,
                     );
-                    added_suggestion = true;
+                    return true;
                 }
             }
-            self.diagnostic_metadata.in_assignment = None;
-        }
-        added_suggestion
+        false
     }
 
     fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.stderr b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
index d37a18f005fda..fb4ea3121ac67 100644
--- a/src/test/ui/suggestions/issue-104086-suggest-let.stderr
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
@@ -2,7 +2,12 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:2:5
    |
 LL |     x = x = x;
-   |     ^ not found in this scope
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = x = x;
+   |     +++
 
 error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:2:9
@@ -20,7 +25,12 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:7:5
    |
 LL |     x = y = y = y;
-   |     ^ not found in this scope
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = y = y = y;
+   |     +++
 
 error[E0425]: cannot find value `y` in this scope
   --> $DIR/issue-104086-suggest-let.rs:7:9
@@ -44,7 +54,12 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:13:5
    |
 LL |     x = y = y;
-   |     ^ not found in this scope
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = y = y;
+   |     +++
 
 error[E0425]: cannot find value `y` in this scope
   --> $DIR/issue-104086-suggest-let.rs:13:9
@@ -62,7 +77,12 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:18:5
    |
 LL |     x = x = y;
-   |     ^ not found in this scope
+   |     ^
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let x = x = y;
+   |     +++
 
 error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-104086-suggest-let.rs:18:9

From 28b87a57c7c3965e4cb7f4efbd9d1490edf35e1a Mon Sep 17 00:00:00 2001
From: Boxy 
Date: Wed, 9 Nov 2022 14:25:08 +0000
Subject: [PATCH 407/482] docs

---
 compiler/rustc_middle/src/ty/subst.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 0660e9b79a700..c1d9f496c5b22 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -506,6 +506,9 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List {
     }
 }
 
+/// Similar to [`Binder`] except that it tracks early bound generics, i.e. `struct Foo(T)`
+/// needs `T` substituted immediately. This type primarily exists to avoid forgetting to call
+/// `subst`.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[derive(Encodable, Decodable, HashStable)]
 pub struct EarlyBinder(pub T);

From 7288d6570d07dd991313ad918675e33831144901 Mon Sep 17 00:00:00 2001
From: Boxy 
Date: Thu, 10 Nov 2022 14:57:18 +0000
Subject: [PATCH 408/482] broken links go brrrrr

---
 compiler/rustc_middle/src/ty/subst.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index c1d9f496c5b22..2bcb2d824842e 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -506,7 +506,7 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List {
     }
 }
 
-/// Similar to [`Binder`] except that it tracks early bound generics, i.e. `struct Foo(T)`
+/// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo(T)`
 /// needs `T` substituted immediately. This type primarily exists to avoid forgetting to call
 /// `subst`.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]

From af3c41d8b2bb8e8a7ac58ebae8fdc62c5741dd1b Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Thu, 10 Nov 2022 05:12:53 +0000
Subject: [PATCH 409/482] Don't ICE when encountering ConstKind::Error in
 RequiredConstsVisitor

---
 compiler/rustc_mir_transform/src/required_consts.rs | 2 +-
 src/test/ui/consts/invalid-const-in-body.rs         | 6 ++++++
 src/test/ui/consts/invalid-const-in-body.stderr     | 8 ++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/consts/invalid-const-in-body.rs
 create mode 100644 src/test/ui/consts/invalid-const-in-body.stderr

diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs
index cc75947d9dda7..0ea8f2ba93fd8 100644
--- a/compiler/rustc_mir_transform/src/required_consts.rs
+++ b/compiler/rustc_mir_transform/src/required_consts.rs
@@ -17,7 +17,7 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
         let literal = constant.literal;
         match literal {
             ConstantKind::Ty(c) => match c.kind() {
-                ConstKind::Param(_) => {}
+                ConstKind::Param(_) | ConstKind::Error(_) => {}
                 _ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c),
             },
             ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
diff --git a/src/test/ui/consts/invalid-const-in-body.rs b/src/test/ui/consts/invalid-const-in-body.rs
new file mode 100644
index 0000000000000..f0fa3bb7bd136
--- /dev/null
+++ b/src/test/ui/consts/invalid-const-in-body.rs
@@ -0,0 +1,6 @@
+fn f() -> impl Sized {
+    2.0E
+    //~^ ERROR expected at least one digit in exponent
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/invalid-const-in-body.stderr b/src/test/ui/consts/invalid-const-in-body.stderr
new file mode 100644
index 0000000000000..3be6583594612
--- /dev/null
+++ b/src/test/ui/consts/invalid-const-in-body.stderr
@@ -0,0 +1,8 @@
+error: expected at least one digit in exponent
+  --> $DIR/invalid-const-in-body.rs:2:5
+   |
+LL |     2.0E
+   |     ^^^^
+
+error: aborting due to previous error
+

From 9d6a7b46ce2d9956113a6a6e7471a9d1acadc35e Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Thu, 10 Nov 2022 05:39:06 +0000
Subject: [PATCH 410/482] Use const_error_with_guaranteed more

---
 .../rustc_middle/src/mir/interpret/mod.rs     |  3 +-
 compiler/rustc_middle/src/mir/mod.rs          |  4 ++-
 compiler/rustc_middle/src/ty/consts.rs        |  5 ++-
 .../src/build/expr/as_constant.rs             | 31 +++++++++++++++----
 compiler/rustc_mir_build/src/thir/constant.rs | 17 ++++++++--
 .../rustc_mir_build/src/thir/pattern/mod.rs   |  2 +-
 compiler/rustc_ty_utils/src/consts.rs         |  4 ++-
 7 files changed, 51 insertions(+), 15 deletions(-)

diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 5e3dfcbcc4962..32ec585576920 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -106,6 +106,7 @@ use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{HashMapExt, Lock};
 use rustc_data_structures::tiny_list::TinyList;
+use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -176,7 +177,7 @@ pub enum LitToConstError {
     /// This is used for graceful error handling (`delay_span_bug`) in
     /// type checking (`Const::from_anon_const`).
     TypeError,
-    Reported,
+    Reported(ErrorGuaranteed),
 }
 
 #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 5290d5aae46ca..54f3964d28f06 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2251,7 +2251,9 @@ impl<'tcx> ConstantKind<'tcx> {
                 match tcx.const_eval_resolve(param_env, uneval, None) {
                     Ok(val) => Self::Val(val, ty),
                     Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
-                    Err(_) => Self::Ty(tcx.const_error(ty)),
+                    Err(ErrorHandled::Reported(guar)) => {
+                        Self::Ty(tcx.const_error_with_guaranteed(ty, guar))
+                    }
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 33fdf1a837094..e2e2761501b48 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -2,7 +2,6 @@ use crate::mir::interpret::LitToConstInput;
 use crate::mir::ConstantKind;
 use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
 use rustc_data_structures::intern::Interned;
-use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::HashStable;
@@ -225,7 +224,7 @@ impl<'tcx> Const<'tcx> {
         if let Some(val) = self.kind().try_eval_for_typeck(tcx, param_env) {
             match val {
                 Ok(val) => Const::from_value(tcx, val, self.ty()),
-                Err(ErrorGuaranteed { .. }) => tcx.const_error(self.ty()),
+                Err(guar) => tcx.const_error_with_guaranteed(self.ty(), guar),
             }
         } else {
             // Either the constant isn't evaluatable or ValTree creation failed.
@@ -240,7 +239,7 @@ impl<'tcx> Const<'tcx> {
         if let Some(val) = self.kind().try_eval_for_mir(tcx, param_env) {
             match val {
                 Ok(const_val) => ConstantKind::from_value(const_val, self.ty()),
-                Err(ErrorGuaranteed { .. }) => ConstantKind::Ty(tcx.const_error(self.ty())),
+                Err(guar) => ConstantKind::Ty(tcx.const_error_with_guaranteed(self.ty(), guar)),
             }
         } else {
             ConstantKind::Ty(self)
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 98df9c3f0e8df..7d8a940bde5ce 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -9,6 +9,7 @@ use rustc_middle::mir::interpret::{
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt};
+use rustc_span::DUMMY_SP;
 use rustc_target::abi::Size;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -26,7 +27,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let literal =
                     match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) {
                         Ok(c) => c,
-                        Err(LitToConstError::Reported) => ConstantKind::Ty(tcx.const_error(ty)),
+                        Err(LitToConstError::Reported(guar)) => {
+                            ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar))
+                        }
                         Err(LitToConstError::TypeError) => {
                             bug!("encountered type error in `lit_to_mir_constant")
                         }
@@ -105,7 +108,15 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
     let LitToConstInput { lit, ty, neg } = lit_input;
     let trunc = |n| {
         let param_ty = ty::ParamEnv::reveal_all().and(ty);
-        let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
+        let width = tcx
+            .layout_of(param_ty)
+            .map_err(|_| {
+                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    format!("couldn't compute width of literal: {:?}", lit_input.lit),
+                ))
+            })?
+            .size;
         trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
         let result = width.truncate(n);
         trace!("trunc result: {}", result);
@@ -136,12 +147,20 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
         (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
             trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?
         }
-        (ast::LitKind::Float(n, _), ty::Float(fty)) => {
-            parse_float_into_constval(*n, *fty, neg).ok_or(LitToConstError::Reported)?
-        }
+        (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg)
+            .ok_or_else(|| {
+                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    format!("couldn't parse float literal: {:?}", lit_input.lit),
+                ))
+            })?,
         (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
         (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
-        (ast::LitKind::Err, _) => return Err(LitToConstError::Reported),
+        (ast::LitKind::Err, _) => {
+            return Err(LitToConstError::Reported(
+                tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
+            ));
+        }
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index f626571b5b2c5..85e8801bda3ec 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -1,6 +1,7 @@
 use rustc_ast as ast;
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
+use rustc_span::DUMMY_SP;
 
 pub(crate) fn lit_to_const<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -10,7 +11,15 @@ pub(crate) fn lit_to_const<'tcx>(
 
     let trunc = |n| {
         let param_ty = ParamEnv::reveal_all().and(ty);
-        let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
+        let width = tcx
+            .layout_of(param_ty)
+            .map_err(|_| {
+                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    format!("couldn't compute width of literal: {:?}", lit_input.lit),
+                ))
+            })?
+            .size;
         trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
         let result = width.truncate(n);
         trace!("trunc result: {}", result);
@@ -44,7 +53,11 @@ pub(crate) fn lit_to_const<'tcx>(
         }
         (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
         (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
-        (ast::LitKind::Err, _) => return Err(LitToConstError::Reported),
+        (ast::LitKind::Err, _) => {
+            return Err(LitToConstError::Reported(
+                tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
+            ));
+        }
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 2526522a25c8c..776c748c7e5fe 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -614,7 +614,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
         match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
             Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
-            Err(LitToConstError::Reported) => PatKind::Wild,
+            Err(LitToConstError::Reported(_)) => PatKind::Wild,
             Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
         }
     }
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 3cef47c0f8ba4..cb41c4f94e2e6 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -235,7 +235,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
                     neg,
                 }) {
                     Ok(c) => c,
-                    Err(LitToConstError::Reported) => self.tcx.const_error(node.ty),
+                    Err(LitToConstError::Reported(guar)) => {
+                        self.tcx.const_error_with_guaranteed(node.ty, guar)
+                    }
                     Err(LitToConstError::TypeError) => {
                         bug!("encountered type error in lit_to_const")
                     }

From 067d5fb0f9bba96c3013a23eee42dc2a39c591fe Mon Sep 17 00:00:00 2001
From: Camille GILLOT 
Date: Tue, 8 Nov 2022 18:47:26 +0000
Subject: [PATCH 411/482] Make AbsoluteBytePos a u64.

---
 compiler/rustc_query_impl/src/on_disk_cache.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index a6cb8f7bd5532..eaed9aeb85020 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -119,12 +119,11 @@ pub type EncodedDepNodeIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
 struct SourceFileIndex(u32);
 
 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)]
-pub struct AbsoluteBytePos(u32);
+pub struct AbsoluteBytePos(u64);
 
 impl AbsoluteBytePos {
     fn new(pos: usize) -> AbsoluteBytePos {
-        debug_assert!(pos <= u32::MAX as usize);
-        AbsoluteBytePos(pos as u32)
+        AbsoluteBytePos(pos.try_into().expect("Incremental cache file size overflowed u64."))
     }
 
     fn to_usize(self) -> usize {

From 63d8dbd68d5643827a0b866e0f07624bf6f6a926 Mon Sep 17 00:00:00 2001
From: Maybe Waffle 
Date: Fri, 29 Jul 2022 23:06:13 +0400
Subject: [PATCH 412/482] recover wrong-cased `use`s (`Use`, `USE`, etc)

---
 compiler/rustc_parse/src/parser/item.rs       | 25 ++++++++++++++---
 compiler/rustc_parse/src/parser/mod.rs        | 27 +++++++++++++++++++
 .../ui/parser/item-kw-case-mismatch.fixed     |  7 +++++
 src/test/ui/parser/item-kw-case-mismatch.rs   |  7 +++++
 .../ui/parser/item-kw-case-mismatch.stderr    | 14 ++++++++++
 5 files changed, 77 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/parser/item-kw-case-mismatch.fixed
 create mode 100644 src/test/ui/parser/item-kw-case-mismatch.rs
 create mode 100644 src/test/ui/parser/item-kw-case-mismatch.stderr

diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index d657a2891171d..55aa879017215 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -143,8 +143,15 @@ impl<'a> Parser<'a> {
         let lo = self.token.span;
         let vis = self.parse_visibility(FollowedByType::No)?;
         let mut def = self.parse_defaultness();
-        let kind =
-            self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, fn_parse_mode)?;
+        let kind = self.parse_item_kind(
+            &mut attrs,
+            mac_allowed,
+            lo,
+            &vis,
+            &mut def,
+            fn_parse_mode,
+            false,
+        )?;
         if let Some((ident, kind)) = kind {
             self.error_on_unconsumed_default(def, &kind);
             let span = lo.to(self.prev_token.span);
@@ -205,11 +212,12 @@ impl<'a> Parser<'a> {
         vis: &Visibility,
         def: &mut Defaultness,
         fn_parse_mode: FnParseMode,
+        kw_case_insensitive: bool,
     ) -> PResult<'a, Option> {
         let def_final = def == &Defaultness::Final;
         let mut def = || mem::replace(def, Defaultness::Final);
 
-        let info = if self.eat_keyword(kw::Use) {
+        let info = if self.eat_keyword_case(kw::Use, kw_case_insensitive) {
             self.parse_use_item()?
         } else if self.check_fn_front_matter(def_final) {
             // FUNCTION ITEM
@@ -286,6 +294,17 @@ impl<'a> Parser<'a> {
         } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
             self.recover_missing_kw_before_item()?;
             return Ok(None);
+        } else if self.isnt_macro_invocation() && !kw_case_insensitive {
+            // Recover wrong cased keywords
+            return self.parse_item_kind(
+                attrs,
+                macros_allowed,
+                lo,
+                vis,
+                &mut def(),
+                fn_parse_mode,
+                true,
+            );
         } else if macros_allowed && self.check_path() {
             // MACRO INVOCATION ITEM
             (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 2e59c005e315a..8a84a8cfc9688 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -648,6 +648,33 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Eats a keyword, optionally ignoring the case.
+    /// If the case differs (and is ignored) an error is issued.
+    /// This is useful for recovery.
+    fn eat_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool {
+        if self.eat_keyword(kw) {
+            return true;
+        }
+
+        if case_insensitive
+        && let Some((ident, /* is_raw */ false)) = self.token.ident()
+        && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
+            self
+                .struct_span_err(ident.span, format!("keyword `{kw}` is written in a wrong case"))
+                .span_suggestion(
+                    ident.span,
+                    "write it in the correct case",
+                    kw,
+                    Applicability::MachineApplicable
+                ).emit();
+
+            self.bump();
+            return true;
+        }
+
+        false
+    }
+
     fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
         if self.token.is_keyword(kw) {
             self.bump();
diff --git a/src/test/ui/parser/item-kw-case-mismatch.fixed b/src/test/ui/parser/item-kw-case-mismatch.fixed
new file mode 100644
index 0000000000000..d99f89ccef5b4
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+#![allow(unused_imports)]
+
+fn main() {}
+
+use std::ptr::read;  //~ ERROR keyword `use` is written in a wrong case
+use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.rs b/src/test/ui/parser/item-kw-case-mismatch.rs
new file mode 100644
index 0000000000000..605552b5f147f
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.rs
@@ -0,0 +1,7 @@
+// run-rustfix
+#![allow(unused_imports)]
+
+fn main() {}
+
+Use std::ptr::read;  //~ ERROR keyword `use` is written in a wrong case
+USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.stderr b/src/test/ui/parser/item-kw-case-mismatch.stderr
new file mode 100644
index 0000000000000..aebbc9d558f27
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.stderr
@@ -0,0 +1,14 @@
+error: keyword `use` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:6:1
+   |
+LL | Use std::ptr::read;
+   | ^^^ help: write it in the correct case (notice the capitalization): `use`
+
+error: keyword `use` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:7:1
+   |
+LL | USE std::ptr::write;
+   | ^^^ help: write it in the correct case: `use`
+
+error: aborting due to 2 previous errors
+

From f9476597f87ffa4f64447c621e239ae31242d8c8 Mon Sep 17 00:00:00 2001
From: Maybe Waffle 
Date: Tue, 13 Sep 2022 22:48:29 +0400
Subject: [PATCH 413/482] Recover wrong cased keywords starting functions

---
 compiler/rustc_ast/src/token.rs               |  9 +++
 compiler/rustc_parse/src/parser/expr.rs       |  2 +-
 compiler/rustc_parse/src/parser/item.rs       | 79 ++++++++++---------
 compiler/rustc_parse/src/parser/mod.rs        | 30 +++++--
 compiler/rustc_parse/src/parser/ty.rs         |  4 +-
 .../ui/parser/item-kw-case-mismatch.fixed     | 27 +++++++
 src/test/ui/parser/item-kw-case-mismatch.rs   | 27 +++++++
 .../ui/parser/item-kw-case-mismatch.stderr    | 78 +++++++++++++++++-
 8 files changed, 205 insertions(+), 51 deletions(-)

diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 83b10d906e297..7455a63c02e4d 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -615,6 +615,15 @@ impl Token {
         self.is_non_raw_ident_where(|id| id.name == kw)
     }
 
+    /// Returns `true` if the token is a given keyword, `kw` or if `case_insensitive` is true and this token is an identifier equal to `kw` ignoring the case.
+    pub fn is_keyword_case(&self, kw: Symbol, case_insensitive: bool) -> bool {
+        self.is_keyword(kw)
+            || (case_insensitive
+                && self.is_non_raw_ident_where(|id| {
+                    id.name.as_str().to_lowercase() == kw.as_str().to_lowercase()
+                }))
+    }
+
     pub fn is_path_segment_keyword(&self) -> bool {
         self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index da2d20e47ee68..f38ee5f655e6c 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2090,7 +2090,7 @@ impl<'a> Parser<'a> {
             if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
 
         let asyncness = if self.token.uninterpolated_span().rust_2018() {
-            self.parse_asyncness()
+            self.parse_asyncness(false)
         } else {
             Async::No
         };
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 55aa879017215..53afb39174e9a 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -34,7 +34,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a `mod  { ... }` or `mod ;` item.
     fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety();
+        let unsafety = self.parse_unsafety(false);
         self.expect_keyword(kw::Mod)?;
         let id = self.parse_ident()?;
         let mod_kind = if self.eat(&token::Semi) {
@@ -215,14 +215,14 @@ impl<'a> Parser<'a> {
         kw_case_insensitive: bool,
     ) -> PResult<'a, Option> {
         let def_final = def == &Defaultness::Final;
-        let mut def = || mem::replace(def, Defaultness::Final);
+        let mut def_ = || mem::replace(def, Defaultness::Final);
 
         let info = if self.eat_keyword_case(kw::Use, kw_case_insensitive) {
             self.parse_use_item()?
-        } else if self.check_fn_front_matter(def_final) {
+        } else if self.check_fn_front_matter(def_final, kw_case_insensitive) {
             // FUNCTION ITEM
             let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis)?;
-            (ident, ItemKind::Fn(Box::new(Fn { defaultness: def(), sig, generics, body })))
+            (ident, ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, body })))
         } else if self.eat_keyword(kw::Extern) {
             if self.eat_keyword(kw::Crate) {
                 // EXTERN CRATE
@@ -233,7 +233,7 @@ impl<'a> Parser<'a> {
             }
         } else if self.is_unsafe_foreign_mod() {
             // EXTERN BLOCK
-            let unsafety = self.parse_unsafety();
+            let unsafety = self.parse_unsafety(false);
             self.expect_keyword(kw::Extern)?;
             self.parse_item_foreign_mod(attrs, unsafety)?
         } else if self.is_static_global() {
@@ -242,15 +242,15 @@ impl<'a> Parser<'a> {
             let m = self.parse_mutability();
             let (ident, ty, expr) = self.parse_item_global(Some(m))?;
             (ident, ItemKind::Static(ty, m, expr))
-        } else if let Const::Yes(const_span) = self.parse_constness() {
+        } else if let Const::Yes(const_span) = self.parse_constness(false) {
             // CONST ITEM
             if self.token.is_keyword(kw::Impl) {
                 // recover from `const impl`, suggest `impl const`
-                self.recover_const_impl(const_span, attrs, def())?
+                self.recover_const_impl(const_span, attrs, def_())?
             } else {
                 self.recover_const_mut(const_span);
                 let (ident, ty, expr) = self.parse_item_global(None)?;
-                (ident, ItemKind::Const(def(), ty, expr))
+                (ident, ItemKind::Const(def_(), ty, expr))
             }
         } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
             // TRAIT ITEM
@@ -259,7 +259,7 @@ impl<'a> Parser<'a> {
             || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl])
         {
             // IMPL ITEM
-            self.parse_item_impl(attrs, def())?
+            self.parse_item_impl(attrs, def_())?
         } else if self.check_keyword(kw::Mod)
             || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Mod])
         {
@@ -267,7 +267,7 @@ impl<'a> Parser<'a> {
             self.parse_item_mod(attrs)?
         } else if self.eat_keyword(kw::Type) {
             // TYPE ITEM
-            self.parse_type_alias(def())?
+            self.parse_type_alias(def_())?
         } else if self.eat_keyword(kw::Enum) {
             // ENUM ITEM
             self.parse_item_enum()?
@@ -295,16 +295,10 @@ impl<'a> Parser<'a> {
             self.recover_missing_kw_before_item()?;
             return Ok(None);
         } else if self.isnt_macro_invocation() && !kw_case_insensitive {
+            _ = def_;
+
             // Recover wrong cased keywords
-            return self.parse_item_kind(
-                attrs,
-                macros_allowed,
-                lo,
-                vis,
-                &mut def(),
-                fn_parse_mode,
-                true,
-            );
+            return self.parse_item_kind(attrs, macros_allowed, lo, vis, def, fn_parse_mode, true);
         } else if macros_allowed && self.check_path() {
             // MACRO INVOCATION ITEM
             (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
@@ -557,7 +551,7 @@ impl<'a> Parser<'a> {
         attrs: &mut AttrVec,
         defaultness: Defaultness,
     ) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety();
+        let unsafety = self.parse_unsafety(false);
         self.expect_keyword(kw::Impl)?;
 
         // First, parse generic parameters if necessary.
@@ -571,7 +565,7 @@ impl<'a> Parser<'a> {
             generics
         };
 
-        let constness = self.parse_constness();
+        let constness = self.parse_constness(false);
         if let Const::Yes(span) = constness {
             self.sess.gated_spans.gate(sym::const_trait_impl, span);
         }
@@ -815,7 +809,7 @@ impl<'a> Parser<'a> {
 
     /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
     fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety();
+        let unsafety = self.parse_unsafety(false);
         // Parse optional `auto` prefix.
         let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
 
@@ -1781,7 +1775,7 @@ impl<'a> Parser<'a> {
         let (ident, is_raw) = self.ident_or_err()?;
         if !is_raw && ident.is_reserved() {
             let snapshot = self.create_snapshot_for_diagnostic();
-            let err = if self.check_fn_front_matter(false) {
+            let err = if self.check_fn_front_matter(false, false) {
                 let inherited_vis = Visibility {
                     span: rustc_span::DUMMY_SP,
                     kind: VisibilityKind::Inherited,
@@ -2191,7 +2185,11 @@ impl<'a> Parser<'a> {
     ///
     /// `check_pub` adds additional `pub` to the checks in case users place it
     /// wrongly, can be used to ensure `pub` never comes after `default`.
-    pub(super) fn check_fn_front_matter(&mut self, check_pub: bool) -> bool {
+    pub(super) fn check_fn_front_matter(
+        &mut self,
+        check_pub: bool,
+        kw_case_insensitive: bool,
+    ) -> bool {
         // We use an over-approximation here.
         // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
         // `pub` is added in case users got confused with the ordering like `async pub fn`,
@@ -2201,23 +2199,30 @@ impl<'a> Parser<'a> {
         } else {
             &[kw::Const, kw::Async, kw::Unsafe, kw::Extern]
         };
-        self.check_keyword(kw::Fn) // Definitely an `fn`.
+        self.check_keyword_case(kw::Fn, kw_case_insensitive) // Definitely an `fn`.
             // `$qual fn` or `$qual $qual`:
-            || quals.iter().any(|&kw| self.check_keyword(kw))
+            || quals.iter().any(|&kw| self.check_keyword_case(kw, kw_case_insensitive))
                 && self.look_ahead(1, |t| {
                     // `$qual fn`, e.g. `const fn` or `async fn`.
-                    t.is_keyword(kw::Fn)
+                    t.is_keyword_case(kw::Fn, kw_case_insensitive)
                     // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
-                    || t.is_non_raw_ident_where(|i| quals.contains(&i.name)
-                        // Rule out 2015 `const async: T = val`.
-                        && i.is_reserved()
+                    || (
+                        (
+                            t.is_non_raw_ident_where(|i|
+                                quals.contains(&i.name)
+                                    // Rule out 2015 `const async: T = val`.
+                                    && i.is_reserved()
+                            )
+                            || kw_case_insensitive
+                                && t.is_non_raw_ident_where(|i| quals.iter().any(|qual| qual.as_str() == i.name.as_str().to_lowercase()))
+                        )
                         // Rule out unsafe extern block.
                         && !self.is_unsafe_foreign_mod())
                 })
             // `extern ABI fn`
-            || self.check_keyword(kw::Extern)
+            || self.check_keyword_case(kw::Extern, kw_case_insensitive)
                 && self.look_ahead(1, |t| t.can_begin_literal_maybe_minus())
-                && self.look_ahead(2, |t| t.is_keyword(kw::Fn))
+                && self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, kw_case_insensitive))
     }
 
     /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
@@ -2233,22 +2238,22 @@ impl<'a> Parser<'a> {
     /// `Visibility::Inherited` when no visibility is known.
     pub(super) fn parse_fn_front_matter(&mut self, orig_vis: &Visibility) -> PResult<'a, FnHeader> {
         let sp_start = self.token.span;
-        let constness = self.parse_constness();
+        let constness = self.parse_constness(true);
 
         let async_start_sp = self.token.span;
-        let asyncness = self.parse_asyncness();
+        let asyncness = self.parse_asyncness(true);
 
         let unsafe_start_sp = self.token.span;
-        let unsafety = self.parse_unsafety();
+        let unsafety = self.parse_unsafety(true);
 
         let ext_start_sp = self.token.span;
-        let ext = self.parse_extern();
+        let ext = self.parse_extern(true);
 
         if let Async::Yes { span, .. } = asyncness {
             self.ban_async_in_2015(span);
         }
 
-        if !self.eat_keyword(kw::Fn) {
+        if !self.eat_keyword_case(kw::Fn, true) {
             // It is possible for `expect_one_of` to recover given the contents of
             // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
             // account for this.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 8a84a8cfc9688..2de68bb27b20b 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -636,6 +636,20 @@ impl<'a> Parser<'a> {
         self.token.is_keyword(kw)
     }
 
+    fn check_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool {
+        if self.check_keyword(kw) {
+            return true;
+        }
+
+        if case_insensitive
+        && let Some((ident, /* is_raw */ false)) = self.token.ident()
+        && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
+            true
+        } else {
+            false
+        }
+    }
+
     /// If the next token is the given keyword, eats it and returns `true`.
     /// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
     // Public for rustfmt usage.
@@ -1154,8 +1168,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses asyncness: `async` or nothing.
-    fn parse_asyncness(&mut self) -> Async {
-        if self.eat_keyword(kw::Async) {
+    fn parse_asyncness(&mut self, case_insensitive: bool) -> Async {
+        if self.eat_keyword_case(kw::Async, case_insensitive) {
             let span = self.prev_token.uninterpolated_span();
             Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
         } else {
@@ -1164,8 +1178,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses unsafety: `unsafe` or nothing.
-    fn parse_unsafety(&mut self) -> Unsafe {
-        if self.eat_keyword(kw::Unsafe) {
+    fn parse_unsafety(&mut self, case_insensitive: bool) -> Unsafe {
+        if self.eat_keyword_case(kw::Unsafe, case_insensitive) {
             Unsafe::Yes(self.prev_token.uninterpolated_span())
         } else {
             Unsafe::No
@@ -1173,10 +1187,10 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses constness: `const` or nothing.
-    fn parse_constness(&mut self) -> Const {
+    fn parse_constness(&mut self, case_insensitive: bool) -> Const {
         // Avoid const blocks to be parsed as const items
         if self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace))
-            && self.eat_keyword(kw::Const)
+            && self.eat_keyword_case(kw::Const, case_insensitive)
         {
             Const::Yes(self.prev_token.uninterpolated_span())
         } else {
@@ -1431,8 +1445,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `extern string_literal?`.
-    fn parse_extern(&mut self) -> Extern {
-        if self.eat_keyword(kw::Extern) {
+    fn parse_extern(&mut self, case_insensitive: bool) -> Extern {
+        if self.eat_keyword_case(kw::Extern, case_insensitive) {
             let mut extern_span = self.prev_token.span;
             let abi = self.parse_abi();
             if let Some(abi) = abi {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 3a67c032b3bdd..3a5658ec9dbce 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -267,7 +267,7 @@ impl<'a> Parser<'a> {
         } else if self.eat_keyword(kw::Underscore) {
             // A type to be inferred `_`
             TyKind::Infer
-        } else if self.check_fn_front_matter(false) {
+        } else if self.check_fn_front_matter(false, false) {
             // Function pointer type
             self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)?
         } else if self.check_keyword(kw::For) {
@@ -275,7 +275,7 @@ impl<'a> Parser<'a> {
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
-            if self.check_fn_front_matter(false) {
+            if self.check_fn_front_matter(false, false) {
                 self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)?
             } else {
                 let path = self.parse_path(PathStyle::Type)?;
diff --git a/src/test/ui/parser/item-kw-case-mismatch.fixed b/src/test/ui/parser/item-kw-case-mismatch.fixed
index d99f89ccef5b4..1794268f260e1 100644
--- a/src/test/ui/parser/item-kw-case-mismatch.fixed
+++ b/src/test/ui/parser/item-kw-case-mismatch.fixed
@@ -1,7 +1,34 @@
 // run-rustfix
+// edition:2018
 #![allow(unused_imports)]
 
 fn main() {}
 
 use std::ptr::read;  //~ ERROR keyword `use` is written in a wrong case
 use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
+
+async fn _a() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+fn _b() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+async fn _c() {}
+//~^ ERROR keyword `async` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+async fn _d() {}
+//~^ ERROR keyword `async` is written in a wrong case
+
+const unsafe fn _e() {}
+//~^ ERROR keyword `const` is written in a wrong case
+//~| ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+unsafe extern fn _f() {}
+//~^ ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `extern` is written in a wrong case
+
+extern "C" fn _g() {}
+//~^ ERROR keyword `extern` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.rs b/src/test/ui/parser/item-kw-case-mismatch.rs
index 605552b5f147f..ac8390efdb9a3 100644
--- a/src/test/ui/parser/item-kw-case-mismatch.rs
+++ b/src/test/ui/parser/item-kw-case-mismatch.rs
@@ -1,7 +1,34 @@
 // run-rustfix
+// edition:2018
 #![allow(unused_imports)]
 
 fn main() {}
 
 Use std::ptr::read;  //~ ERROR keyword `use` is written in a wrong case
 USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
+
+async Fn _a() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+Fn _b() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+aSYNC fN _c() {}
+//~^ ERROR keyword `async` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+Async fn _d() {}
+//~^ ERROR keyword `async` is written in a wrong case
+
+CONST UNSAFE FN _e() {}
+//~^ ERROR keyword `const` is written in a wrong case
+//~| ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+unSAFE EXTern fn _f() {}
+//~^ ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `extern` is written in a wrong case
+
+EXTERN "C" FN _g() {}
+//~^ ERROR keyword `extern` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.stderr b/src/test/ui/parser/item-kw-case-mismatch.stderr
index aebbc9d558f27..e66dae825f9c4 100644
--- a/src/test/ui/parser/item-kw-case-mismatch.stderr
+++ b/src/test/ui/parser/item-kw-case-mismatch.stderr
@@ -1,14 +1,86 @@
 error: keyword `use` is written in a wrong case
-  --> $DIR/item-kw-case-mismatch.rs:6:1
+  --> $DIR/item-kw-case-mismatch.rs:7:1
    |
 LL | Use std::ptr::read;
    | ^^^ help: write it in the correct case (notice the capitalization): `use`
 
 error: keyword `use` is written in a wrong case
-  --> $DIR/item-kw-case-mismatch.rs:7:1
+  --> $DIR/item-kw-case-mismatch.rs:8:1
    |
 LL | USE std::ptr::write;
    | ^^^ help: write it in the correct case: `use`
 
-error: aborting due to 2 previous errors
+error: keyword `fn` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:10:7
+   |
+LL | async Fn _a() {}
+   |       ^^ help: write it in the correct case (notice the capitalization): `fn`
+
+error: keyword `fn` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:13:1
+   |
+LL | Fn _b() {}
+   | ^^ help: write it in the correct case (notice the capitalization): `fn`
+
+error: keyword `async` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:16:1
+   |
+LL | aSYNC fN _c() {}
+   | ^^^^^ help: write it in the correct case: `async`
+
+error: keyword `fn` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:16:7
+   |
+LL | aSYNC fN _c() {}
+   |       ^^ help: write it in the correct case: `fn`
+
+error: keyword `async` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:20:1
+   |
+LL | Async fn _d() {}
+   | ^^^^^ help: write it in the correct case: `async`
+
+error: keyword `const` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:23:1
+   |
+LL | CONST UNSAFE FN _e() {}
+   | ^^^^^ help: write it in the correct case: `const`
+
+error: keyword `unsafe` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:23:7
+   |
+LL | CONST UNSAFE FN _e() {}
+   |       ^^^^^^ help: write it in the correct case: `unsafe`
+
+error: keyword `fn` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:23:14
+   |
+LL | CONST UNSAFE FN _e() {}
+   |              ^^ help: write it in the correct case: `fn`
+
+error: keyword `unsafe` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:28:1
+   |
+LL | unSAFE EXTern fn _f() {}
+   | ^^^^^^ help: write it in the correct case: `unsafe`
+
+error: keyword `extern` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:28:8
+   |
+LL | unSAFE EXTern fn _f() {}
+   |        ^^^^^^ help: write it in the correct case: `extern`
+
+error: keyword `extern` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:32:1
+   |
+LL | EXTERN "C" FN _g() {}
+   | ^^^^^^ help: write it in the correct case: `extern`
+
+error: keyword `fn` is written in a wrong case
+  --> $DIR/item-kw-case-mismatch.rs:32:12
+   |
+LL | EXTERN "C" FN _g() {}
+   |            ^^ help: write it in the correct case: `fn`
+
+error: aborting due to 14 previous errors
 

From afa23d273d2266f611f7a5b72c0dccfa914e1992 Mon Sep 17 00:00:00 2001
From: Maybe Waffle 
Date: Thu, 15 Sep 2022 20:27:23 +0400
Subject: [PATCH 414/482] Replace some `bool` params with an enum

---
 compiler/rustc_ast/src/lib.rs           |  1 +
 compiler/rustc_ast/src/token.rs         |  7 +--
 compiler/rustc_ast/src/util/case.rs     |  6 +++
 compiler/rustc_parse/src/parser/expr.rs |  3 +-
 compiler/rustc_parse/src/parser/item.rs | 63 +++++++++++++------------
 compiler/rustc_parse/src/parser/mod.rs  | 25 +++++-----
 compiler/rustc_parse/src/parser/ty.rs   |  5 +-
 7 files changed, 63 insertions(+), 47 deletions(-)
 create mode 100644 compiler/rustc_ast/src/util/case.rs

diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index eeb7e56e2b124..9c1dfeb1a6142 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -29,6 +29,7 @@ extern crate rustc_macros;
 extern crate tracing;
 
 pub mod util {
+    pub mod case;
     pub mod classify;
     pub mod comments;
     pub mod literal;
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 7455a63c02e4d..f6aac0b55f1ab 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -5,6 +5,7 @@ pub use TokenKind::*;
 
 use crate::ast;
 use crate::ptr::P;
+use crate::util::case::Case;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
@@ -615,10 +616,10 @@ impl Token {
         self.is_non_raw_ident_where(|id| id.name == kw)
     }
 
-    /// Returns `true` if the token is a given keyword, `kw` or if `case_insensitive` is true and this token is an identifier equal to `kw` ignoring the case.
-    pub fn is_keyword_case(&self, kw: Symbol, case_insensitive: bool) -> bool {
+    /// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
+    pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool {
         self.is_keyword(kw)
-            || (case_insensitive
+            || (case == Case::Insensitive
                 && self.is_non_raw_ident_where(|id| {
                     id.name.as_str().to_lowercase() == kw.as_str().to_lowercase()
                 }))
diff --git a/compiler/rustc_ast/src/util/case.rs b/compiler/rustc_ast/src/util/case.rs
new file mode 100644
index 0000000000000..1afd7dea7408e
--- /dev/null
+++ b/compiler/rustc_ast/src/util/case.rs
@@ -0,0 +1,6 @@
+/// Whatever to ignore case (`fn` vs `Fn` vs `FN`) or not. Used for recovering.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Case {
+    Sensitive,
+    Insensitive,
+}
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f38ee5f655e6c..7355730c9ebf1 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -33,6 +33,7 @@ use core::mem;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::Spacing;
+use rustc_ast::util::case::Case;
 use rustc_ast::util::classify;
 use rustc_ast::util::literal::LitError;
 use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
@@ -2090,7 +2091,7 @@ impl<'a> Parser<'a> {
             if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
 
         let asyncness = if self.token.uninterpolated_span().rust_2018() {
-            self.parse_asyncness(false)
+            self.parse_asyncness(Case::Sensitive)
         } else {
             Async::No
         };
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 53afb39174e9a..494f0cf56a80f 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -8,6 +8,7 @@ use rustc_ast::ast::*;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
+use rustc_ast::util::case::Case;
 use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
 use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
 use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
@@ -34,7 +35,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a `mod  { ... }` or `mod ;` item.
     fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety(false);
+        let unsafety = self.parse_unsafety(Case::Sensitive);
         self.expect_keyword(kw::Mod)?;
         let id = self.parse_ident()?;
         let mod_kind = if self.eat(&token::Semi) {
@@ -150,7 +151,7 @@ impl<'a> Parser<'a> {
             &vis,
             &mut def,
             fn_parse_mode,
-            false,
+            Case::Sensitive,
         )?;
         if let Some((ident, kind)) = kind {
             self.error_on_unconsumed_default(def, &kind);
@@ -212,14 +213,14 @@ impl<'a> Parser<'a> {
         vis: &Visibility,
         def: &mut Defaultness,
         fn_parse_mode: FnParseMode,
-        kw_case_insensitive: bool,
+        case: Case,
     ) -> PResult<'a, Option> {
         let def_final = def == &Defaultness::Final;
         let mut def_ = || mem::replace(def, Defaultness::Final);
 
-        let info = if self.eat_keyword_case(kw::Use, kw_case_insensitive) {
+        let info = if self.eat_keyword_case(kw::Use, case) {
             self.parse_use_item()?
-        } else if self.check_fn_front_matter(def_final, kw_case_insensitive) {
+        } else if self.check_fn_front_matter(def_final, case) {
             // FUNCTION ITEM
             let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis)?;
             (ident, ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, body })))
@@ -233,7 +234,7 @@ impl<'a> Parser<'a> {
             }
         } else if self.is_unsafe_foreign_mod() {
             // EXTERN BLOCK
-            let unsafety = self.parse_unsafety(false);
+            let unsafety = self.parse_unsafety(Case::Sensitive);
             self.expect_keyword(kw::Extern)?;
             self.parse_item_foreign_mod(attrs, unsafety)?
         } else if self.is_static_global() {
@@ -242,7 +243,7 @@ impl<'a> Parser<'a> {
             let m = self.parse_mutability();
             let (ident, ty, expr) = self.parse_item_global(Some(m))?;
             (ident, ItemKind::Static(ty, m, expr))
-        } else if let Const::Yes(const_span) = self.parse_constness(false) {
+        } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
             // CONST ITEM
             if self.token.is_keyword(kw::Impl) {
                 // recover from `const impl`, suggest `impl const`
@@ -294,11 +295,19 @@ impl<'a> Parser<'a> {
         } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
             self.recover_missing_kw_before_item()?;
             return Ok(None);
-        } else if self.isnt_macro_invocation() && !kw_case_insensitive {
+        } else if self.isnt_macro_invocation() && case == Case::Sensitive {
             _ = def_;
 
             // Recover wrong cased keywords
-            return self.parse_item_kind(attrs, macros_allowed, lo, vis, def, fn_parse_mode, true);
+            return self.parse_item_kind(
+                attrs,
+                macros_allowed,
+                lo,
+                vis,
+                def,
+                fn_parse_mode,
+                Case::Insensitive,
+            );
         } else if macros_allowed && self.check_path() {
             // MACRO INVOCATION ITEM
             (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
@@ -551,7 +560,7 @@ impl<'a> Parser<'a> {
         attrs: &mut AttrVec,
         defaultness: Defaultness,
     ) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety(false);
+        let unsafety = self.parse_unsafety(Case::Sensitive);
         self.expect_keyword(kw::Impl)?;
 
         // First, parse generic parameters if necessary.
@@ -565,7 +574,7 @@ impl<'a> Parser<'a> {
             generics
         };
 
-        let constness = self.parse_constness(false);
+        let constness = self.parse_constness(Case::Sensitive);
         if let Const::Yes(span) = constness {
             self.sess.gated_spans.gate(sym::const_trait_impl, span);
         }
@@ -809,7 +818,7 @@ impl<'a> Parser<'a> {
 
     /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
     fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> {
-        let unsafety = self.parse_unsafety(false);
+        let unsafety = self.parse_unsafety(Case::Sensitive);
         // Parse optional `auto` prefix.
         let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
 
@@ -1775,7 +1784,7 @@ impl<'a> Parser<'a> {
         let (ident, is_raw) = self.ident_or_err()?;
         if !is_raw && ident.is_reserved() {
             let snapshot = self.create_snapshot_for_diagnostic();
-            let err = if self.check_fn_front_matter(false, false) {
+            let err = if self.check_fn_front_matter(false, Case::Sensitive) {
                 let inherited_vis = Visibility {
                     span: rustc_span::DUMMY_SP,
                     kind: VisibilityKind::Inherited,
@@ -2185,11 +2194,7 @@ impl<'a> Parser<'a> {
     ///
     /// `check_pub` adds additional `pub` to the checks in case users place it
     /// wrongly, can be used to ensure `pub` never comes after `default`.
-    pub(super) fn check_fn_front_matter(
-        &mut self,
-        check_pub: bool,
-        kw_case_insensitive: bool,
-    ) -> bool {
+    pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
         // We use an over-approximation here.
         // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
         // `pub` is added in case users got confused with the ordering like `async pub fn`,
@@ -2199,12 +2204,12 @@ impl<'a> Parser<'a> {
         } else {
             &[kw::Const, kw::Async, kw::Unsafe, kw::Extern]
         };
-        self.check_keyword_case(kw::Fn, kw_case_insensitive) // Definitely an `fn`.
+        self.check_keyword_case(kw::Fn, case) // Definitely an `fn`.
             // `$qual fn` or `$qual $qual`:
-            || quals.iter().any(|&kw| self.check_keyword_case(kw, kw_case_insensitive))
+            || quals.iter().any(|&kw| self.check_keyword_case(kw, case))
                 && self.look_ahead(1, |t| {
                     // `$qual fn`, e.g. `const fn` or `async fn`.
-                    t.is_keyword_case(kw::Fn, kw_case_insensitive)
+                    t.is_keyword_case(kw::Fn, case)
                     // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
                     || (
                         (
@@ -2213,16 +2218,16 @@ impl<'a> Parser<'a> {
                                     // Rule out 2015 `const async: T = val`.
                                     && i.is_reserved()
                             )
-                            || kw_case_insensitive
+                            || case == Case::Insensitive
                                 && t.is_non_raw_ident_where(|i| quals.iter().any(|qual| qual.as_str() == i.name.as_str().to_lowercase()))
                         )
                         // Rule out unsafe extern block.
                         && !self.is_unsafe_foreign_mod())
                 })
             // `extern ABI fn`
-            || self.check_keyword_case(kw::Extern, kw_case_insensitive)
+            || self.check_keyword_case(kw::Extern, case)
                 && self.look_ahead(1, |t| t.can_begin_literal_maybe_minus())
-                && self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, kw_case_insensitive))
+                && self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case))
     }
 
     /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
@@ -2238,22 +2243,22 @@ impl<'a> Parser<'a> {
     /// `Visibility::Inherited` when no visibility is known.
     pub(super) fn parse_fn_front_matter(&mut self, orig_vis: &Visibility) -> PResult<'a, FnHeader> {
         let sp_start = self.token.span;
-        let constness = self.parse_constness(true);
+        let constness = self.parse_constness(Case::Insensitive);
 
         let async_start_sp = self.token.span;
-        let asyncness = self.parse_asyncness(true);
+        let asyncness = self.parse_asyncness(Case::Insensitive);
 
         let unsafe_start_sp = self.token.span;
-        let unsafety = self.parse_unsafety(true);
+        let unsafety = self.parse_unsafety(Case::Insensitive);
 
         let ext_start_sp = self.token.span;
-        let ext = self.parse_extern(true);
+        let ext = self.parse_extern(Case::Insensitive);
 
         if let Async::Yes { span, .. } = asyncness {
             self.ban_async_in_2015(span);
         }
 
-        if !self.eat_keyword_case(kw::Fn, true) {
+        if !self.eat_keyword_case(kw::Fn, Case::Insensitive) {
             // It is possible for `expect_one_of` to recover given the contents of
             // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
             // account for this.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 2de68bb27b20b..14dc490fb0232 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -22,6 +22,7 @@ use rustc_ast::token::{self, Delimiter, Nonterminal, Token, TokenKind};
 use rustc_ast::tokenstream::AttributesData;
 use rustc_ast::tokenstream::{self, DelimSpan, Spacing};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
+use rustc_ast::util::case::Case;
 use rustc_ast::AttrId;
 use rustc_ast::DUMMY_NODE_ID;
 use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, Extern};
@@ -636,12 +637,12 @@ impl<'a> Parser<'a> {
         self.token.is_keyword(kw)
     }
 
-    fn check_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool {
+    fn check_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
         if self.check_keyword(kw) {
             return true;
         }
 
-        if case_insensitive
+        if case == Case::Insensitive
         && let Some((ident, /* is_raw */ false)) = self.token.ident()
         && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
             true
@@ -665,12 +666,12 @@ impl<'a> Parser<'a> {
     /// Eats a keyword, optionally ignoring the case.
     /// If the case differs (and is ignored) an error is issued.
     /// This is useful for recovery.
-    fn eat_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool {
+    fn eat_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
         if self.eat_keyword(kw) {
             return true;
         }
 
-        if case_insensitive
+        if case == Case::Insensitive
         && let Some((ident, /* is_raw */ false)) = self.token.ident()
         && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
             self
@@ -1168,8 +1169,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses asyncness: `async` or nothing.
-    fn parse_asyncness(&mut self, case_insensitive: bool) -> Async {
-        if self.eat_keyword_case(kw::Async, case_insensitive) {
+    fn parse_asyncness(&mut self, case: Case) -> Async {
+        if self.eat_keyword_case(kw::Async, case) {
             let span = self.prev_token.uninterpolated_span();
             Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
         } else {
@@ -1178,8 +1179,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses unsafety: `unsafe` or nothing.
-    fn parse_unsafety(&mut self, case_insensitive: bool) -> Unsafe {
-        if self.eat_keyword_case(kw::Unsafe, case_insensitive) {
+    fn parse_unsafety(&mut self, case: Case) -> Unsafe {
+        if self.eat_keyword_case(kw::Unsafe, case) {
             Unsafe::Yes(self.prev_token.uninterpolated_span())
         } else {
             Unsafe::No
@@ -1187,10 +1188,10 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses constness: `const` or nothing.
-    fn parse_constness(&mut self, case_insensitive: bool) -> Const {
+    fn parse_constness(&mut self, case: Case) -> Const {
         // Avoid const blocks to be parsed as const items
         if self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace))
-            && self.eat_keyword_case(kw::Const, case_insensitive)
+            && self.eat_keyword_case(kw::Const, case)
         {
             Const::Yes(self.prev_token.uninterpolated_span())
         } else {
@@ -1445,8 +1446,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `extern string_literal?`.
-    fn parse_extern(&mut self, case_insensitive: bool) -> Extern {
-        if self.eat_keyword_case(kw::Extern, case_insensitive) {
+    fn parse_extern(&mut self, case: Case) -> Extern {
+        if self.eat_keyword_case(kw::Extern, case) {
             let mut extern_span = self.prev_token.span;
             let abi = self.parse_abi();
             if let Some(abi) = abi {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 3a5658ec9dbce..4d78c5bd0e273 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -4,6 +4,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
+use rustc_ast::util::case::Case;
 use rustc_ast::{
     self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime,
     MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
@@ -267,7 +268,7 @@ impl<'a> Parser<'a> {
         } else if self.eat_keyword(kw::Underscore) {
             // A type to be inferred `_`
             TyKind::Infer
-        } else if self.check_fn_front_matter(false, false) {
+        } else if self.check_fn_front_matter(false, Case::Sensitive) {
             // Function pointer type
             self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)?
         } else if self.check_keyword(kw::For) {
@@ -275,7 +276,7 @@ impl<'a> Parser<'a> {
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
-            if self.check_fn_front_matter(false, false) {
+            if self.check_fn_front_matter(false, Case::Sensitive) {
                 self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)?
             } else {
                 let path = self.parse_path(PathStyle::Type)?;

From 9970aacdc89db23e5cdd61ddb249d6ab019357c6 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 21:39:57 +0200
Subject: [PATCH 415/482] Store `ErrorGuaranteed` in `ErrorReported`

---
 compiler/rustc_expand/src/mbe/macro_parser.rs | 7 ++++---
 compiler/rustc_expand/src/mbe/macro_rules.rs  | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index c8bdc39311c65..aa7a06f66d722 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -72,6 +72,7 @@
 
 pub(crate) use NamedMatch::*;
 pub(crate) use ParseResult::*;
+use rustc_errors::ErrorGuaranteed;
 
 use crate::mbe::{KleeneOp, TokenTree};
 
@@ -270,7 +271,7 @@ pub(crate) enum ParseResult {
     Failure(Token, &'static str),
     /// Fatal error (malformed macro?). Abort compilation.
     Error(rustc_span::Span, String),
-    ErrorReported,
+    ErrorReported(ErrorGuaranteed),
 }
 
 /// A `ParseResult` where the `Success` variant contains a mapping of
@@ -612,14 +613,14 @@ impl TtParser {
                         // edition-specific matching behavior for non-terminals.
                         let nt = match parser.to_mut().parse_nonterminal(kind) {
                             Err(mut err) => {
-                                err.span_label(
+                                let guarantee = err.span_label(
                                     span,
                                     format!(
                                         "while parsing argument for this `{kind}` macro fragment"
                                     ),
                                 )
                                 .emit();
-                                return ErrorReported;
+                                return ErrorReported(guarantee);
                             }
                             Ok(nt) => nt,
                         };
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index f6fe38174f7c5..3ddea80c84445 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -333,7 +333,7 @@ fn expand_macro<'cx>(
                 cx.struct_span_err(span, &msg).emit();
                 return DummyResult::any(span);
             }
-            ErrorReported => return DummyResult::any(sp),
+            ErrorReported(_) => return DummyResult::any(sp),
         }
 
         // The matcher was not `Success(..)`ful.
@@ -470,7 +470,7 @@ pub fn compile_declarative_macro(
                 .emit();
             return dummy_syn_ext();
         }
-        ErrorReported => {
+        ErrorReported(_) => {
             return dummy_syn_ext();
         }
     };

From 962e9e332ff1670275de435897b101d08a83d88f Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 21:43:48 +0200
Subject: [PATCH 416/482] Small parser cleanups

---
 compiler/rustc_expand/src/mbe/macro_parser.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index aa7a06f66d722..6513928e78c85 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -451,7 +451,7 @@ impl TtParser {
                         // Try zero matches of this sequence, by skipping over it.
                         self.cur_mps.push(MatcherPos {
                             idx: idx_first_after,
-                            matches: mp.matches.clone(), // a cheap clone
+                            matches: Lrc::clone(&mp.matches),
                         });
                     }
 
@@ -464,8 +464,8 @@ impl TtParser {
                     // sequence. If that's not possible, `ending_mp` will fail quietly when it is
                     // processed next time around the loop.
                     let ending_mp = MatcherPos {
-                        idx: mp.idx + 1,             // +1 skips the Kleene op
-                        matches: mp.matches.clone(), // a cheap clone
+                        idx: mp.idx + 1, // +1 skips the Kleene op
+                        matches: Lrc::clone(&mp.matches),
                     };
                     self.cur_mps.push(ending_mp);
 
@@ -480,8 +480,8 @@ impl TtParser {
                     // separator yet. Try ending the sequence. If that's not possible, `ending_mp`
                     // will fail quietly when it is processed next time around the loop.
                     let ending_mp = MatcherPos {
-                        idx: mp.idx + 2,             // +2 skips the separator and the Kleene op
-                        matches: mp.matches.clone(), // a cheap clone
+                        idx: mp.idx + 2, // +2 skips the separator and the Kleene op
+                        matches: Lrc::clone(&mp.matches),
                     };
                     self.cur_mps.push(ending_mp);
 

From f89e914dbf054c89627d7390c27ec02a8ecf1ad2 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 21:48:28 +0200
Subject: [PATCH 417/482] Add `Tracker` to track matching operations

This should allow us to collect detailed information without slowing
down the inital hot path.
---
 compiler/rustc_expand/src/mbe.rs              |  2 +-
 compiler/rustc_expand/src/mbe/macro_parser.rs | 32 +++++++++++--------
 compiler/rustc_expand/src/mbe/macro_rules.rs  | 31 ++++++++++++++++--
 3 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs
index f42576b16f520..63bafd7b046fb 100644
--- a/compiler/rustc_expand/src/mbe.rs
+++ b/compiler/rustc_expand/src/mbe.rs
@@ -52,7 +52,7 @@ impl KleeneToken {
 /// A Kleene-style [repetition operator](https://en.wikipedia.org/wiki/Kleene_star)
 /// for token sequences.
 #[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
-enum KleeneOp {
+pub(crate) enum KleeneOp {
     /// Kleene star (`*`) for zero or more repetitions
     ZeroOrMore,
     /// Kleene plus (`+`) for one or more repetitions
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 6513928e78c85..0402c51247af0 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -70,21 +70,20 @@
 //! eof: [a $( a )* a b ·]
 //! ```
 
+use rustc_errors::ErrorGuaranteed;
 pub(crate) use NamedMatch::*;
 pub(crate) use ParseResult::*;
-use rustc_errors::ErrorGuaranteed;
 
-use crate::mbe::{KleeneOp, TokenTree};
+use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree};
 
 use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lrc;
 use rustc_lint_defs::pluralize;
 use rustc_parse::parser::{NtOrTt, Parser};
+use rustc_span::symbol::Ident;
 use rustc_span::symbol::MacroRulesNormalizedIdent;
 use rustc_span::Span;
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
-use rustc_span::symbol::Ident;
 use std::borrow::Cow;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 
@@ -97,7 +96,8 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
 ///
 /// This means a matcher can be represented by `&[MatcherLoc]`, and traversal mostly involves
 /// simply incrementing the current matcher position index by one.
-pub(super) enum MatcherLoc {
+#[derive(Debug, Clone, PartialEq)]
+pub(crate) enum MatcherLoc {
     Token {
         token: Token,
     },
@@ -401,17 +401,21 @@ impl TtParser {
     ///
     /// `Some(result)` if everything is finished, `None` otherwise. Note that matches are kept
     /// track of through the mps generated.
-    fn parse_tt_inner(
+    fn parse_tt_inner<'matcher, T: Tracker<'matcher>>(
         &mut self,
-        matcher: &[MatcherLoc],
+        matcher: &'matcher [MatcherLoc],
         token: &Token,
+        track: &mut T,
     ) -> Option {
         // Matcher positions that would be valid if the macro invocation was over now. Only
         // modified if `token == Eof`.
         let mut eof_mps = EofMatcherPositions::None;
 
         while let Some(mut mp) = self.cur_mps.pop() {
-            match &matcher[mp.idx] {
+            let matcher_loc = &matcher[mp.idx];
+            track.before_match_loc(self, matcher_loc);
+
+            match matcher_loc {
                 MatcherLoc::Token { token: t } => {
                     // If it's a doc comment, we just ignore it and move on to the next tt in the
                     // matcher. This is a bug, but #95267 showed that existing programs rely on
@@ -553,10 +557,11 @@ impl TtParser {
     }
 
     /// Match the token stream from `parser` against `matcher`.
-    pub(super) fn parse_tt(
+    pub(super) fn parse_tt<'matcher, T: Tracker<'matcher>>(
         &mut self,
         parser: &mut Cow<'_, Parser<'_>>,
-        matcher: &[MatcherLoc],
+        matcher: &'matcher [MatcherLoc],
+        track: &mut T,
     ) -> NamedParseResult {
         // A queue of possible matcher positions. We initialize it with the matcher position in
         // which the "dot" is before the first token of the first token tree in `matcher`.
@@ -572,7 +577,8 @@ impl TtParser {
 
             // Process `cur_mps` until either we have finished the input or we need to get some
             // parsing from the black-box parser done.
-            if let Some(res) = self.parse_tt_inner(matcher, &parser.token) {
+            let res = self.parse_tt_inner(matcher, &parser.token, track);
+            if let Some(res) = res {
                 return res;
             }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 3ddea80c84445..9c676a41f3a88 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -33,6 +33,8 @@ use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 use std::{mem, slice};
 
+use super::macro_parser::NamedParseResult;
+
 pub(crate) struct ParserAnyMacro<'a> {
     parser: Parser<'a>,
 
@@ -205,6 +207,29 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap>, sp: Span
     cx_expansions.entry(sp).or_default().push(message);
 }
 
+pub(super) trait Tracker<'matcher> {
+    /// This is called before trying to match next MatcherLoc on the current token
+    fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc);
+
+    /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
+    /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`)
+    fn after_arm(&mut self, result: &NamedParseResult);
+
+    /// For tracing
+    fn description() -> &'static str;
+}
+
+/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization
+struct NoopTracker;
+
+impl<'matcher> Tracker<'matcher> for NoopTracker {
+    fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {}
+    fn after_arm(&mut self, _: &NamedParseResult) {}
+    fn description() -> &'static str {
+        "none"
+    }
+}
+
 /// Expands the rules based macro defined by `lhses` and `rhses` for a given
 /// input `arg`.
 fn expand_macro<'cx>(
@@ -262,7 +287,7 @@ fn expand_macro<'cx>(
         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
         let mut gated_spans_snapshot = mem::take(&mut *sess.gated_spans.spans.borrow_mut());
 
-        match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs) {
+        match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) {
             Success(named_matches) => {
                 // The matcher was `Success(..)`ful.
                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
@@ -354,7 +379,7 @@ fn expand_macro<'cx>(
     if let Some((arg, comma_span)) = arg.add_comma() {
         for lhs in lhses {
             let parser = parser_from_cx(sess, arg.clone());
-            if let Success(_) = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs) {
+            if let Success(_) = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) {
                 if comma_span.is_dummy() {
                     err.note("you might be missing a comma");
                 } else {
@@ -452,7 +477,7 @@ pub fn compile_declarative_macro(
     let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
     let mut tt_parser =
         TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro }));
-    let argument_map = match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram) {
+    let argument_map = match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram, &mut NoopTracker) {
         Success(m) => m,
         Failure(token, msg) => {
             let s = parse_failure_msg(&token);

From fa81bc466f4b56dac3f8f0037d2355e072e1965d Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 21:55:32 +0200
Subject: [PATCH 418/482] Factor out matching into `try_match_macro`

This moves out the matching part of expansion into a new function. This
function will try to match the macro and return an error if it failed to
match. A tracker can be used to get more information about the matching.
---
 compiler/rustc_expand/src/mbe/macro_parser.rs |   6 +-
 compiler/rustc_expand/src/mbe/macro_rules.rs  | 247 +++++++++---------
 2 files changed, 129 insertions(+), 124 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 0402c51247af0..d2dbd190c8ec2 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -277,7 +277,11 @@ pub(crate) enum ParseResult {
 /// A `ParseResult` where the `Success` variant contains a mapping of
 /// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping
 /// of metavars to the token trees they bind to.
-pub(crate) type NamedParseResult = ParseResult>;
+pub(crate) type NamedParseResult = ParseResult;
+
+/// Contains a mapping of `MacroRulesNormalizedIdent`s to `NamedMatch`es.
+/// This represents the mapping of metavars to the token trees they bind to.
+pub(crate) type NamedMatches = FxHashMap;
 
 /// Count how many metavars declarations are in `matcher`.
 pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 9c676a41f3a88..b35ec453145f3 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -14,7 +14,9 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, TransparencyError};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage};
+use rustc_errors::{
+    Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
+};
 use rustc_feature::Features;
 use rustc_lint_defs::builtin::{
     RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
@@ -33,7 +35,7 @@ use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 use std::{mem, slice};
 
-use super::macro_parser::NamedParseResult;
+use super::macro_parser::{NamedMatches, NamedParseResult};
 
 pub(crate) struct ParserAnyMacro<'a> {
     parser: Parser<'a>,
@@ -253,9 +255,87 @@ fn expand_macro<'cx>(
         trace_macros_note(&mut cx.expansions, sp, msg);
     }
 
-    // Which arm's failure should we report? (the one furthest along)
-    let mut best_failure: Option<(Token, &str)> = None;
+    // Track nothing for the best performance
+    let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut NoopTracker);
+
+    match try_success_result {
+        Ok((i, named_matches)) => {
+            let (rhs, rhs_span): (&mbe::Delimited, DelimSpan) = match &rhses[i] {
+                mbe::TokenTree::Delimited(span, delimited) => (&delimited, *span),
+                _ => cx.span_bug(sp, "malformed macro rhs"),
+            };
+            let arm_span = rhses[i].span();
+
+            let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::>();
+            // rhs has holes ( `$id` and `$(...)` that need filled)
+            let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
+                Ok(tts) => tts,
+                Err(mut err) => {
+                    err.emit();
+                    return DummyResult::any(arm_span);
+                }
+            };
+
+            // Replace all the tokens for the corresponding positions in the macro, to maintain
+            // proper positions in error reporting, while maintaining the macro_backtrace.
+            if rhs_spans.len() == tts.len() {
+                tts = tts.map_enumerated(|i, tt| {
+                    let mut tt = tt.clone();
+                    let mut sp = rhs_spans[i];
+                    sp = sp.with_ctxt(tt.span().ctxt());
+                    tt.set_span(sp);
+                    tt
+                });
+            }
+
+            if cx.trace_macros() {
+                let msg = format!("to `{}`", pprust::tts_to_string(&tts));
+                trace_macros_note(&mut cx.expansions, sp, msg);
+            }
+
+            let mut p = Parser::new(sess, tts, false, None);
+            p.last_type_ascription = cx.current_expansion.prior_type_ascription;
+
+            if is_local {
+                cx.resolver.record_macro_rule_usage(node_id, i);
+            }
+
+            // Let the context choose how to interpret the result.
+            // Weird, but useful for X-macros.
+            return Box::new(ParserAnyMacro {
+                parser: p,
+
+                // Pass along the original expansion site and the name of the macro
+                // so we can print a useful error message if the parse of the expanded
+                // macro leaves unparsed tokens.
+                site_span: sp,
+                macro_ident: name,
+                lint_node_id: cx.current_expansion.lint_node_id,
+                is_trailing_mac: cx.current_expansion.is_trailing_mac,
+                arm_span,
+                is_local,
+            });
+        }
+        Err(()) => {
+            todo!("Retry macro invocation while tracking diagnostics info and emit error");
+
+            return DummyResult::any(sp);
+        }
+    }
+
+    DummyResult::any(sp)
+}
 
+/// Try expanding the macro. Returns the index of the sucessful arm and its named_matches if it was successful,
+/// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors
+/// correctly.
+fn try_match_macro<'matcher, T: Tracker<'matcher>>(
+    sess: &ParseSess,
+    name: Ident,
+    arg: &TokenStream,
+    lhses: &'matcher [Vec],
+    track: &mut T,
+) -> Result<(usize, NamedMatches), ()> {
     // We create a base parser that can be used for the "black box" parts.
     // Every iteration needs a fresh copy of that parser. However, the parser
     // is not mutated on many of the iterations, particularly when dealing with
@@ -277,7 +357,6 @@ fn expand_macro<'cx>(
     // this situation.)
     // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
     let parser = parser_from_cx(sess, arg.clone());
-
     // Try each arm's matchers.
     let mut tt_parser = TtParser::new(name);
     for (i, lhs) in lhses.iter().enumerate() {
@@ -287,115 +366,36 @@ fn expand_macro<'cx>(
         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
         let mut gated_spans_snapshot = mem::take(&mut *sess.gated_spans.spans.borrow_mut());
 
-        match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) {
+        let result = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, track);
+
+        track.after_arm(&result);
+
+        match result {
             Success(named_matches) => {
                 // The matcher was `Success(..)`ful.
                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
                 sess.gated_spans.merge(gated_spans_snapshot);
 
-                let (rhs, rhs_span): (&mbe::Delimited, DelimSpan) = match &rhses[i] {
-                    mbe::TokenTree::Delimited(span, delimited) => (&delimited, *span),
-                    _ => cx.span_bug(sp, "malformed macro rhs"),
-                };
-                let arm_span = rhses[i].span();
-
-                let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::>();
-                // rhs has holes ( `$id` and `$(...)` that need filled)
-                let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
-                    Ok(tts) => tts,
-                    Err(mut err) => {
-                        err.emit();
-                        return DummyResult::any(arm_span);
-                    }
-                };
-
-                // Replace all the tokens for the corresponding positions in the macro, to maintain
-                // proper positions in error reporting, while maintaining the macro_backtrace.
-                if rhs_spans.len() == tts.len() {
-                    tts = tts.map_enumerated(|i, tt| {
-                        let mut tt = tt.clone();
-                        let mut sp = rhs_spans[i];
-                        sp = sp.with_ctxt(tt.span().ctxt());
-                        tt.set_span(sp);
-                        tt
-                    });
-                }
-
-                if cx.trace_macros() {
-                    let msg = format!("to `{}`", pprust::tts_to_string(&tts));
-                    trace_macros_note(&mut cx.expansions, sp, msg);
-                }
-
-                let mut p = Parser::new(sess, tts, false, None);
-                p.last_type_ascription = cx.current_expansion.prior_type_ascription;
-
-                if is_local {
-                    cx.resolver.record_macro_rule_usage(node_id, i);
-                }
-
-                // Let the context choose how to interpret the result.
-                // Weird, but useful for X-macros.
-                return Box::new(ParserAnyMacro {
-                    parser: p,
-
-                    // Pass along the original expansion site and the name of the macro
-                    // so we can print a useful error message if the parse of the expanded
-                    // macro leaves unparsed tokens.
-                    site_span: sp,
-                    macro_ident: name,
-                    lint_node_id: cx.current_expansion.lint_node_id,
-                    is_trailing_mac: cx.current_expansion.is_trailing_mac,
-                    arm_span,
-                    is_local,
-                });
+                return Ok((i, named_matches));
             }
-            Failure(token, msg) => match best_failure {
-                Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
-                _ => best_failure = Some((token, msg)),
-            },
-            Error(err_sp, ref msg) => {
-                let span = err_sp.substitute_dummy(sp);
-                cx.struct_span_err(span, &msg).emit();
-                return DummyResult::any(span);
+            Failure(_, _) => {
+                // Try the next arm
+            }
+            Error(_, _) => {
+                // We haven't emitted an error yet
+                return Err(());
+            }
+            ErrorReported(_) => {
+                return Err(());
             }
-            ErrorReported(_) => return DummyResult::any(sp),
         }
 
         // The matcher was not `Success(..)`ful.
         // Restore to the state before snapshotting and maybe try again.
         mem::swap(&mut gated_spans_snapshot, &mut sess.gated_spans.spans.borrow_mut());
     }
-    drop(parser);
-
-    let (token, label) = best_failure.expect("ran no matchers");
-    let span = token.span.substitute_dummy(sp);
-    let mut err = cx.struct_span_err(span, &parse_failure_msg(&token));
-    err.span_label(span, label);
-    if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
-        err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
-    }
-    annotate_doc_comment(&mut err, sess.source_map(), span);
-    // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
-    if let Some((arg, comma_span)) = arg.add_comma() {
-        for lhs in lhses {
-            let parser = parser_from_cx(sess, arg.clone());
-            if let Success(_) = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) {
-                if comma_span.is_dummy() {
-                    err.note("you might be missing a comma");
-                } else {
-                    err.span_suggestion_short(
-                        comma_span,
-                        "missing comma here",
-                        ", ",
-                        Applicability::MachineApplicable,
-                    );
-                }
-            }
-        }
-    }
-    err.emit();
-    cx.trace_macros_diag();
-    DummyResult::any(sp)
+
+    Err(())
 }
 
 // Note that macro-by-example's input is also matched against a token tree:
@@ -477,28 +477,29 @@ pub fn compile_declarative_macro(
     let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
     let mut tt_parser =
         TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro }));
-    let argument_map = match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram, &mut NoopTracker) {
-        Success(m) => m,
-        Failure(token, msg) => {
-            let s = parse_failure_msg(&token);
-            let sp = token.span.substitute_dummy(def.span);
-            let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
-            err.span_label(sp, msg);
-            annotate_doc_comment(&mut err, sess.source_map(), sp);
-            err.emit();
-            return dummy_syn_ext();
-        }
-        Error(sp, msg) => {
-            sess.parse_sess
-                .span_diagnostic
-                .struct_span_err(sp.substitute_dummy(def.span), &msg)
-                .emit();
-            return dummy_syn_ext();
-        }
-        ErrorReported(_) => {
-            return dummy_syn_ext();
-        }
-    };
+    let argument_map =
+        match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram, &mut NoopTracker) {
+            Success(m) => m,
+            Failure(token, msg) => {
+                let s = parse_failure_msg(&token);
+                let sp = token.span.substitute_dummy(def.span);
+                let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
+                err.span_label(sp, msg);
+                annotate_doc_comment(&mut err, sess.source_map(), sp);
+                err.emit();
+                return dummy_syn_ext();
+            }
+            Error(sp, msg) => {
+                sess.parse_sess
+                    .span_diagnostic
+                    .struct_span_err(sp.substitute_dummy(def.span), &msg)
+                    .emit();
+                return dummy_syn_ext();
+            }
+            ErrorReported(_) => {
+                return dummy_syn_ext();
+            }
+        };
 
     let mut valid = true;
 

From 5b2733111b0a01aaff3c44fc8ba599ebaba58bcb Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 21:59:09 +0200
Subject: [PATCH 419/482] Retry matching with tracking for diagnostics

For now, we only collect the small info for the `best_failure`, but
using this tracker, we can easily extend it in the future to track
things with more performance overhead.

We cannot retry cases where the macro failed with a parser error that
was emitted already, as that would cause us to emit the same error to
the user twice.
---
 compiler/rustc_expand/src/mbe/macro_rules.rs | 118 +++++++++++++++++--
 1 file changed, 109 insertions(+), 9 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index b35ec453145f3..b1214543e5db7 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -316,16 +316,116 @@ fn expand_macro<'cx>(
                 is_local,
             });
         }
-        Err(()) => {
-            todo!("Retry macro invocation while tracking diagnostics info and emit error");
-
+        Err(CanRetry::No(_)) => {
+            debug!("Will not retry matching as an error was emitted already");
             return DummyResult::any(sp);
         }
+        Err(CanRetry::Yes) => {
+            // Retry and emit a better error below.
+        }
+    }
+
+    // An error occured, try the expansion again, tracking the expansion closely for better diagnostics
+    let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
+
+    let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker);
+    assert!(try_success_result.is_err(), "Macro matching returned a success on the second try");
+
+    if let Some(result) = tracker.result {
+        // An irrecoverable error occured and has been emitted.
+        return result;
+    }
+
+    let Some((token, label)) = tracker.best_failure else {
+        return tracker.result.expect("must have encountered Error or ErrorReported");
+    };
+
+    let span = token.span.substitute_dummy(sp);
+
+    let mut err = cx.struct_span_err(span, &parse_failure_msg(&token));
+    err.span_label(span, label);
+    if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
+        err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
     }
 
+    annotate_doc_comment(&mut err, sess.source_map(), span);
+
+    // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
+    if let Some((arg, comma_span)) = arg.add_comma() {
+        for lhs in lhses {
+            let parser = parser_from_cx(sess, arg.clone());
+            let mut tt_parser = TtParser::new(name);
+
+            if let Success(_) =
+                tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker)
+            {
+                if comma_span.is_dummy() {
+                    err.note("you might be missing a comma");
+                } else {
+                    err.span_suggestion_short(
+                        comma_span,
+                        "missing comma here",
+                        ", ",
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
+        }
+    }
+    err.emit();
+    cx.trace_macros_diag();
     DummyResult::any(sp)
 }
 
+/// The tracker used for the slow error path that collects useful info for diagnostics
+struct CollectTrackerAndEmitter<'a, 'cx> {
+    cx: &'a mut ExtCtxt<'cx>,
+    /// Which arm's failure should we report? (the one furthest along)
+    best_failure: Option<(Token, &'static str)>,
+    root_span: Span,
+    result: Option>,
+}
+
+impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx> {
+    fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {
+        // Empty for now.
+    }
+
+    fn after_arm(&mut self, result: &NamedParseResult) {
+        match result {
+            Success(_) => {
+                unreachable!("should not collect detailed info for successful macro match");
+            }
+            Failure(token, msg) => match self.best_failure {
+                Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
+                _ => self.best_failure = Some((token.clone(), msg)),
+            },
+            Error(err_sp, msg) => {
+                let span = err_sp.substitute_dummy(self.root_span);
+                self.cx.struct_span_err(span, msg).emit();
+                self.result = Some(DummyResult::any(span));
+            }
+            ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)),
+        }
+    }
+
+    fn description() -> &'static str {
+        "detailed"
+    }
+}
+
+impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx> {
+    fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
+        Self { cx, best_failure: None, root_span, result: None }
+    }
+}
+
+enum CanRetry {
+    Yes,
+    /// We are not allowed to retry macro expansion as a fatal error has been emitted already.
+    No(ErrorGuaranteed),
+}
+
 /// Try expanding the macro. Returns the index of the sucessful arm and its named_matches if it was successful,
 /// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors
 /// correctly.
@@ -335,7 +435,7 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
     arg: &TokenStream,
     lhses: &'matcher [Vec],
     track: &mut T,
-) -> Result<(usize, NamedMatches), ()> {
+) -> Result<(usize, NamedMatches), CanRetry> {
     // We create a base parser that can be used for the "black box" parts.
     // Every iteration needs a fresh copy of that parser. However, the parser
     // is not mutated on many of the iterations, particularly when dealing with
@@ -383,10 +483,10 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
             }
             Error(_, _) => {
                 // We haven't emitted an error yet
-                return Err(());
+                return Err(CanRetry::Yes);
             }
-            ErrorReported(_) => {
-                return Err(());
+            ErrorReported(guarantee) => {
+                return Err(CanRetry::No(guarantee));
             }
         }
 
@@ -395,7 +495,7 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
         mem::swap(&mut gated_spans_snapshot, &mut sess.gated_spans.spans.borrow_mut());
     }
 
-    Err(())
+    Err(CanRetry::Yes)
 }
 
 // Note that macro-by-example's input is also matched against a token tree:
@@ -478,7 +578,7 @@ pub fn compile_declarative_macro(
     let mut tt_parser =
         TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro }));
     let argument_map =
-        match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram, &mut NoopTracker) {
+        match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) {
             Success(m) => m,
             Failure(token, msg) => {
                 let s = parse_failure_msg(&token);

From 66641aa51a72bf1609015b71c5087379bc7000cf Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 27 Oct 2022 22:03:34 +0200
Subject: [PATCH 420/482] Add some debug logs to macro matching

These were useful while debugging, so I'll leave them here.
---
 compiler/rustc_expand/src/mbe/macro_rules.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index b1214543e5db7..78b3fa337ae7b 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -234,6 +234,7 @@ impl<'matcher> Tracker<'matcher> for NoopTracker {
 
 /// Expands the rules based macro defined by `lhses` and `rhses` for a given
 /// input `arg`.
+#[instrument(skip(cx, transparency, arg, lhses, rhses))]
 fn expand_macro<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
@@ -429,6 +430,7 @@ enum CanRetry {
 /// Try expanding the macro. Returns the index of the sucessful arm and its named_matches if it was successful,
 /// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors
 /// correctly.
+#[instrument(level = "debug", skip(sess, arg, lhses, track), fields(tracking = %T::description()))]
 fn try_match_macro<'matcher, T: Tracker<'matcher>>(
     sess: &ParseSess,
     name: Ident,
@@ -460,6 +462,8 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
     // Try each arm's matchers.
     let mut tt_parser = TtParser::new(name);
     for (i, lhs) in lhses.iter().enumerate() {
+        let _tracing_span = trace_span!("Matching arm", %i);
+
         // Take a snapshot of the state of pre-expansion gating at this point.
         // This is used so that if a matcher is not `Success(..)`ful,
         // then the spans which became gated when parsing the unsuccessful matcher
@@ -472,6 +476,7 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
 
         match result {
             Success(named_matches) => {
+                debug!("Parsed arm successfully");
                 // The matcher was `Success(..)`ful.
                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
                 sess.gated_spans.merge(gated_spans_snapshot);
@@ -479,13 +484,16 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
                 return Ok((i, named_matches));
             }
             Failure(_, _) => {
+                trace!("Failed to match arm, trying the next one");
                 // Try the next arm
             }
             Error(_, _) => {
+                debug!("Fatal error occurred during matching");
                 // We haven't emitted an error yet
                 return Err(CanRetry::Yes);
             }
             ErrorReported(guarantee) => {
+                debug!("Fatal error occurred and was reported during matching");
                 return Err(CanRetry::No(guarantee));
             }
         }

From 75c22a189c7e8b4a3cae12e205914c701dcc69bb Mon Sep 17 00:00:00 2001
From: nils <48135649+Nilstrieb@users.noreply.github.com>
Date: Fri, 4 Nov 2022 09:44:59 +0100
Subject: [PATCH 421/482] Small style improvements

---
 compiler/rustc_expand/src/mbe/macro_parser.rs |  4 ++--
 compiler/rustc_expand/src/mbe/macro_rules.rs  | 21 ++++++++++---------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index d2dbd190c8ec2..95cec8d7ae299 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -70,7 +70,6 @@
 //! eof: [a $( a )* a b ·]
 //! ```
 
-use rustc_errors::ErrorGuaranteed;
 pub(crate) use NamedMatch::*;
 pub(crate) use ParseResult::*;
 
@@ -79,6 +78,7 @@ use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree};
 use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use rustc_errors::ErrorGuaranteed;
 use rustc_lint_defs::pluralize;
 use rustc_parse::parser::{NtOrTt, Parser};
 use rustc_span::symbol::Ident;
@@ -96,7 +96,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
 ///
 /// This means a matcher can be represented by `&[MatcherLoc]`, and traversal mostly involves
 /// simply incrementing the current matcher position index by one.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug)]
 pub(crate) enum MatcherLoc {
     Token {
         token: Token,
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 78b3fa337ae7b..99af91072882e 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -210,18 +210,18 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap>, sp: Span
 }
 
 pub(super) trait Tracker<'matcher> {
-    /// This is called before trying to match next MatcherLoc on the current token
+    /// This is called before trying to match next MatcherLoc on the current token.
     fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc);
 
     /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
-    /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`)
+    /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
     fn after_arm(&mut self, result: &NamedParseResult);
 
-    /// For tracing
+    /// For tracing.
     fn description() -> &'static str;
 }
 
-/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization
+/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization.
 struct NoopTracker;
 
 impl<'matcher> Tracker<'matcher> for NoopTracker {
@@ -256,7 +256,7 @@ fn expand_macro<'cx>(
         trace_macros_note(&mut cx.expansions, sp, msg);
     }
 
-    // Track nothing for the best performance
+    // Track nothing for the best performance.
     let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut NoopTracker);
 
     match try_success_result {
@@ -326,7 +326,7 @@ fn expand_macro<'cx>(
         }
     }
 
-    // An error occured, try the expansion again, tracking the expansion closely for better diagnostics
+    // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics.
     let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
 
     let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker);
@@ -378,7 +378,7 @@ fn expand_macro<'cx>(
     DummyResult::any(sp)
 }
 
-/// The tracker used for the slow error path that collects useful info for diagnostics
+/// The tracker used for the slow error path that collects useful info for diagnostics.
 struct CollectTrackerAndEmitter<'a, 'cx> {
     cx: &'a mut ExtCtxt<'cx>,
     /// Which arm's failure should we report? (the one furthest along)
@@ -427,7 +427,7 @@ enum CanRetry {
     No(ErrorGuaranteed),
 }
 
-/// Try expanding the macro. Returns the index of the sucessful arm and its named_matches if it was successful,
+/// Try expanding the macro. Returns the index of the successful arm and its named_matches if it was successful,
 /// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors
 /// correctly.
 #[instrument(level = "debug", skip(sess, arg, lhses, track), fields(tracking = %T::description()))]
@@ -485,15 +485,16 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
             }
             Failure(_, _) => {
                 trace!("Failed to match arm, trying the next one");
-                // Try the next arm
+                // Try the next arm.
             }
             Error(_, _) => {
                 debug!("Fatal error occurred during matching");
-                // We haven't emitted an error yet
+                // We haven't emitted an error yet, so we can retry.
                 return Err(CanRetry::Yes);
             }
             ErrorReported(guarantee) => {
                 debug!("Fatal error occurred and was reported during matching");
+                // An error has been reported already, we cannot retry as that would cause duplicate errors.
                 return Err(CanRetry::No(guarantee));
             }
         }

From 7a1288130a216ee3c1e06161127557a319489977 Mon Sep 17 00:00:00 2001
From: Michael Benfield 
Date: Mon, 10 Oct 2022 17:29:38 +0000
Subject: [PATCH 422/482] rustc_codegen_ssa: Better code generation for niche
 discriminants.

In some cases we can avoid arithmetic before checking whether a niche
represents an untagged variant.

This is relevant to #101872
---
 compiler/rustc_codegen_ssa/src/mir/place.rs | 194 +++++++++++++++-----
 src/test/codegen/enum-match.rs              | 112 +++++++++++
 src/test/ui/enum-discriminant/get_discr.rs  | 114 ++++++++++++
 3 files changed, 371 insertions(+), 49 deletions(-)
 create mode 100644 src/test/codegen/enum-match.rs
 create mode 100644 src/test/ui/enum-discriminant/get_discr.rs

diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 9c18df5643f1c..8c72d6d1fbe36 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -209,7 +209,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         cast_to: Ty<'tcx>,
     ) -> V {
-        let cast_to = bx.cx().immediate_backend_type(bx.cx().layout_of(cast_to));
+        let cast_to_layout = bx.cx().layout_of(cast_to);
+        let cast_to_size = cast_to_layout.layout.size();
+        let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
         if self.layout.abi.is_uninhabited() {
             return bx.cx().const_undef(cast_to);
         }
@@ -229,7 +231,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
 
         // Read the tag/niche-encoded discriminant from memory.
         let tag = self.project_field(bx, tag_field);
-        let tag = bx.load_operand(tag);
+        let tag_op = bx.load_operand(tag);
+        let tag_imm = tag_op.immediate();
 
         // Decode the discriminant (specifically if it's niche-encoded).
         match *tag_encoding {
@@ -242,68 +245,161 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
                     Int(_, signed) => !tag_scalar.is_bool() && signed,
                     _ => false,
                 };
-                bx.intcast(tag.immediate(), cast_to, signed)
+                bx.intcast(tag_imm, cast_to, signed)
             }
             TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
-                // Rebase from niche values to discriminants, and check
-                // whether the result is in range for the niche variants.
-                let niche_llty = bx.cx().immediate_backend_type(tag.layout);
-                let tag = tag.immediate();
-
-                // We first compute the "relative discriminant" (wrt `niche_variants`),
-                // that is, if `n = niche_variants.end() - niche_variants.start()`,
-                // we remap `niche_start..=niche_start + n` (which may wrap around)
-                // to (non-wrap-around) `0..=n`, to be able to check whether the
-                // discriminant corresponds to a niche variant with one comparison.
-                // We also can't go directly to the (variant index) discriminant
-                // and check that it is in the range `niche_variants`, because
-                // that might not fit in the same type, on top of needing an extra
-                // comparison (see also the comment on `let niche_discr`).
-                let relative_discr = if niche_start == 0 {
-                    // Avoid subtracting `0`, which wouldn't work for pointers.
-                    // FIXME(eddyb) check the actual primitive type here.
-                    tag
+                // Cast to an integer so we don't have to treat a pointer as a
+                // special case.
+                let (tag, tag_llty) = if tag_scalar.primitive().is_ptr() {
+                    let t = bx.type_isize();
+                    let tag = bx.ptrtoint(tag_imm, t);
+                    (tag, t)
                 } else {
-                    bx.sub(tag, bx.cx().const_uint_big(niche_llty, niche_start))
+                    (tag_imm, bx.cx().immediate_backend_type(tag_op.layout))
                 };
+
+                let tag_size = tag_scalar.size(bx.cx());
+                let max_unsigned = tag_size.unsigned_int_max();
+                let max_signed = tag_size.signed_int_max() as u128;
+                let min_signed = max_signed + 1;
                 let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
-                let is_niche = if relative_max == 0 {
-                    // Avoid calling `const_uint`, which wouldn't work for pointers.
-                    // Also use canonical == 0 instead of non-canonical u<= 0.
-                    // FIXME(eddyb) check the actual primitive type here.
-                    bx.icmp(IntPredicate::IntEQ, relative_discr, bx.cx().const_null(niche_llty))
+                let niche_end = niche_start.wrapping_add(relative_max as u128) & max_unsigned;
+                let range = tag_scalar.valid_range(bx.cx());
+
+                let sle = |lhs: u128, rhs: u128| -> bool {
+                    // Signed and unsigned comparisons give the same results,
+                    // except that in signed comparisons an integer with the
+                    // sign bit set is less than one with the sign bit clear.
+                    // Toggle the sign bit to do a signed comparison.
+                    (lhs ^ min_signed) <= (rhs ^ min_signed)
+                };
+
+                // We have a subrange `niche_start..=niche_end` inside `range`.
+                // If the value of the tag is inside this subrange, it's a
+                // "niche value", an increment of the discriminant. Otherwise it
+                // indicates the untagged variant.
+                // A general algorithm to extract the discriminant from the tag
+                // is:
+                // relative_tag = tag - niche_start
+                // is_niche = relative_tag <= (ule) relative_max
+                // discr = if is_niche {
+                //     cast(relative_tag) + niche_variants.start()
+                // } else {
+                //     untagged_variant
+                // }
+                // However, we will likely be able to emit simpler code.
+
+                // Find the least and greatest values in `range`, considered
+                // both as signed and unsigned.
+                let (low_unsigned, high_unsigned) = if range.start <= range.end {
+                    (range.start, range.end)
+                } else {
+                    (0, max_unsigned)
+                };
+                let (low_signed, high_signed) = if sle(range.start, range.end) {
+                    (range.start, range.end)
                 } else {
-                    let relative_max = bx.cx().const_uint(niche_llty, relative_max as u64);
-                    bx.icmp(IntPredicate::IntULE, relative_discr, relative_max)
+                    (min_signed, max_signed)
+                };
+
+                let niches_ule = niche_start <= niche_end;
+                let niches_sle = sle(niche_start, niche_end);
+                let cast_smaller = cast_to_size <= tag_size;
+
+                // In the algorithm above, we can change
+                // cast(relative_tag) + niche_variants.start()
+                // into
+                // cast(tag) + (niche_variants.start() - niche_start)
+                // if either the casted type is no larger than the original
+                // type, or if the niche values are contiguous (in either the
+                // signed or unsigned sense).
+                let can_incr_after_cast = cast_smaller || niches_ule || niches_sle;
+
+                let data_for_boundary_niche = || -> Option<(IntPredicate, u128)> {
+                    if !can_incr_after_cast {
+                        None
+                    } else if niche_start == low_unsigned {
+                        Some((IntPredicate::IntULE, niche_end))
+                    } else if niche_end == high_unsigned {
+                        Some((IntPredicate::IntUGE, niche_start))
+                    } else if niche_start == low_signed {
+                        Some((IntPredicate::IntSLE, niche_end))
+                    } else if niche_end == high_signed {
+                        Some((IntPredicate::IntSGE, niche_start))
+                    } else {
+                        None
+                    }
                 };
 
-                // NOTE(eddyb) this addition needs to be performed on the final
-                // type, in case the niche itself can't represent all variant
-                // indices (e.g. `u8` niche with more than `256` variants,
-                // but enough uninhabited variants so that the remaining variants
-                // fit in the niche).
-                // In other words, `niche_variants.end - niche_variants.start`
-                // is representable in the niche, but `niche_variants.end`
-                // might not be, in extreme cases.
-                let niche_discr = {
-                    let relative_discr = if relative_max == 0 {
-                        // HACK(eddyb) since we have only one niche, we know which
-                        // one it is, and we can avoid having a dynamic value here.
-                        bx.cx().const_uint(cast_to, 0)
+                let (is_niche, tagged_discr, delta) = if relative_max == 0 {
+                    // Best case scenario: only one tagged variant. This will
+                    // likely become just a comparison and a jump.
+                    // The algorithm is:
+                    // is_niche = tag == niche_start
+                    // discr = if is_niche {
+                    //     niche_start
+                    // } else {
+                    //     untagged_variant
+                    // }
+                    let niche_start = bx.cx().const_uint_big(tag_llty, niche_start);
+                    let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start);
+                    let tagged_discr =
+                        bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
+                    (is_niche, tagged_discr, 0)
+                } else if let Some((predicate, constant)) = data_for_boundary_niche() {
+                    // The niche values are either the lowest or the highest in
+                    // `range`. We can avoid the first subtraction in the
+                    // algorithm.
+                    // The algorithm is now this:
+                    // is_niche = tag <= niche_end
+                    // discr = if is_niche {
+                    //     cast(tag) + (niche_variants.start() - niche_start)
+                    // } else {
+                    //     untagged_variant
+                    // }
+                    // (the first line may instead be tag >= niche_start,
+                    // and may be a signed or unsigned comparison)
+                    let is_niche =
+                        bx.icmp(predicate, tag, bx.cx().const_uint_big(tag_llty, constant));
+                    let cast_tag = if cast_smaller {
+                        bx.intcast(tag, cast_to, false)
+                    } else if niches_ule {
+                        bx.zext(tag, cast_to)
                     } else {
-                        bx.intcast(relative_discr, cast_to, false)
+                        bx.sext(tag, cast_to)
                     };
-                    bx.add(
+
+                    let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start);
+                    (is_niche, cast_tag, delta)
+                } else {
+                    // The special cases don't apply, so we'll have to go with
+                    // the general algorithm.
+                    let relative_discr = bx.sub(tag, bx.cx().const_uint_big(tag_llty, niche_start));
+                    let cast_tag = bx.intcast(relative_discr, cast_to, false);
+                    let is_niche = bx.icmp(
+                        IntPredicate::IntULE,
                         relative_discr,
-                        bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64),
-                    )
+                        bx.cx().const_uint(tag_llty, relative_max as u64),
+                    );
+                    (is_niche, cast_tag, niche_variants.start().as_u32() as u128)
                 };
 
-                bx.select(
+                let tagged_discr = if delta == 0 {
+                    tagged_discr
+                } else {
+                    bx.add(tagged_discr, bx.cx().const_uint_big(cast_to, delta))
+                };
+
+                let discr = bx.select(
                     is_niche,
-                    niche_discr,
+                    tagged_discr,
                     bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
-                )
+                );
+
+                // In principle we could insert assumes on the possible range of `discr`, but
+                // currently in LLVM this seems to be a pessimization.
+
+                discr
             }
         }
     }
diff --git a/src/test/codegen/enum-match.rs b/src/test/codegen/enum-match.rs
new file mode 100644
index 0000000000000..efab189fd7b8f
--- /dev/null
+++ b/src/test/codegen/enum-match.rs
@@ -0,0 +1,112 @@
+// compile-flags: -Copt-level=1
+// only-x86_64
+
+#![crate_type = "lib"]
+
+// Check each of the 3 cases for `codegen_get_discr`.
+
+// Case 0: One tagged variant.
+pub enum Enum0 {
+    A(bool),
+    B,
+}
+
+// CHECK: define i8 @match0{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = icmp eq i8 %0, 2
+// CHECK-NEXT: %2 = and i8 %0, 1
+// CHECK-NEXT: %.0 = select i1 %1, i8 13, i8 %2
+#[no_mangle]
+pub fn match0(e: Enum0) -> u8 {
+    use Enum0::*;
+    match e {
+        A(b) => b as u8,
+        B => 13,
+    }
+}
+
+// Case 1: Niche values are on a boundary for `range`.
+pub enum Enum1 {
+    A(bool),
+    B,
+    C,
+}
+
+// CHECK: define i8 @match1{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = icmp ugt i8 %0, 1
+// CHECK-NEXT: %2 = zext i8 %0 to i64
+// CHECK-NEXT: %3 = add nsw i64 %2, -1
+// CHECK-NEXT: %_2 = select i1 %1, i64 %3, i64 0
+// CHECK-NEXT: switch i64 %_2, label {{.*}} [
+#[no_mangle]
+pub fn match1(e: Enum1) -> u8 {
+    use Enum1::*;
+    match e {
+        A(b) => b as u8,
+        B => 13,
+        C => 100,
+    }
+}
+
+// Case 2: Special cases don't apply.
+pub enum X {
+    _2=2, _3, _4, _5, _6, _7, _8, _9, _10, _11,
+    _12, _13, _14, _15, _16, _17, _18, _19, _20,
+    _21, _22, _23, _24, _25, _26, _27, _28, _29,
+    _30, _31, _32, _33, _34, _35, _36, _37, _38,
+    _39, _40, _41, _42, _43, _44, _45, _46, _47,
+    _48, _49, _50, _51, _52, _53, _54, _55, _56,
+    _57, _58, _59, _60, _61, _62, _63, _64, _65,
+    _66, _67, _68, _69, _70, _71, _72, _73, _74,
+    _75, _76, _77, _78, _79, _80, _81, _82, _83,
+    _84, _85, _86, _87, _88, _89, _90, _91, _92,
+    _93, _94, _95, _96, _97, _98, _99, _100, _101,
+    _102, _103, _104, _105, _106, _107, _108, _109,
+    _110, _111, _112, _113, _114, _115, _116, _117,
+    _118, _119, _120, _121, _122, _123, _124, _125,
+    _126, _127, _128, _129, _130, _131, _132, _133,
+    _134, _135, _136, _137, _138, _139, _140, _141,
+    _142, _143, _144, _145, _146, _147, _148, _149,
+    _150, _151, _152, _153, _154, _155, _156, _157,
+    _158, _159, _160, _161, _162, _163, _164, _165,
+    _166, _167, _168, _169, _170, _171, _172, _173,
+    _174, _175, _176, _177, _178, _179, _180, _181,
+    _182, _183, _184, _185, _186, _187, _188, _189,
+    _190, _191, _192, _193, _194, _195, _196, _197,
+    _198, _199, _200, _201, _202, _203, _204, _205,
+    _206, _207, _208, _209, _210, _211, _212, _213,
+    _214, _215, _216, _217, _218, _219, _220, _221,
+    _222, _223, _224, _225, _226, _227, _228, _229,
+    _230, _231, _232, _233, _234, _235, _236, _237,
+    _238, _239, _240, _241, _242, _243, _244, _245,
+    _246, _247, _248, _249, _250, _251, _252, _253,
+}
+
+pub enum Enum2 {
+    A(X),
+    B,
+    C,
+    D,
+    E,
+}
+
+// CHECK: define i8 @match2{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = add i8 %0, 2
+// CHECK-NEXT: %2 = zext i8 %1 to i64
+// CHECK-NEXT: %3 = icmp ult i8 %1, 4
+// CHECK-NEXT: %4 = add nuw nsw i64 %2, 1
+// CHECK-NEXT: %_2 = select i1 %3, i64 %4, i64 0
+// CHECK-NEXT: switch i64 %_2, label {{.*}} [
+#[no_mangle]
+pub fn match2(e: Enum2) -> u8 {
+    use Enum2::*;
+    match e {
+        A(b) => b as u8,
+        B => 13,
+        C => 100,
+        D => 200,
+        E => 250,
+    }
+}
diff --git a/src/test/ui/enum-discriminant/get_discr.rs b/src/test/ui/enum-discriminant/get_discr.rs
new file mode 100644
index 0000000000000..71eea4e0f78af
--- /dev/null
+++ b/src/test/ui/enum-discriminant/get_discr.rs
@@ -0,0 +1,114 @@
+// run-pass
+
+// Now that there are several variations on the code generated in
+// `codegen_get_discr`, let's make sure the various cases yield the correct
+// result.
+
+// To get the discriminant of an E value, there are no shortcuts - we must
+// do the full algorithm.
+#[repr(u8)]
+pub enum X1 {
+    _1 = 1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+    _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+    _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+    _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+    _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+    _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+    _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+    _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+    _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+    _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+    _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+    _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+    _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+    _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+    _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+    _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+#[repr(i8)]
+pub enum X2 {
+    _1 = -1, _2 = 0, _3 = 1,
+}
+
+#[repr(i8)]
+pub enum X3 {
+    _1 = -128, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+    _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+    _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+    _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+    _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+    _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+    _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+    _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+    _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+    _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+    _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+    _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+    _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+    _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+    _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+    _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+#[repr(i8)]
+pub enum X4 {
+    _1 = -126, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+    _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+    _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+    _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+    _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+    _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+    _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+    _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+    _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+    _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+    _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+    _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+    _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+    _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+    _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+    _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+pub enum E {
+    A(X),
+    B,
+    C,
+}
+
+pub fn match_e(e: E) -> u8 {
+    use E::*;
+    match e {
+        A(_) => 0,
+        B => 1,
+        C => 2,
+    }
+}
+
+fn main() {
+    assert_eq!(match_e(E::A(X1::_1)), 0);
+    assert_eq!(match_e(E::A(X1::_2)), 0);
+    assert_eq!(match_e(E::A(X1::_254)), 0);
+    assert_eq!(match_e(E::::B), 1);
+    assert_eq!(match_e(E::::C), 2);
+    assert_eq!(match_e(E::A(X2::_1)), 0);
+    assert_eq!(match_e(E::A(X2::_2)), 0);
+    assert_eq!(match_e(E::A(X2::_3)), 0);
+    assert_eq!(match_e(E::::B), 1);
+    assert_eq!(match_e(E::::C), 2);
+    assert_eq!(match_e(E::A(X3::_1)), 0);
+    assert_eq!(match_e(E::A(X3::_2)), 0);
+    assert_eq!(match_e(E::A(X3::_254)), 0);
+    assert_eq!(match_e(E::::B), 1);
+    assert_eq!(match_e(E::::C), 2);
+    assert_eq!(match_e(E::A(X4::_1)), 0);
+    assert_eq!(match_e(E::A(X4::_2)), 0);
+    assert_eq!(match_e(E::A(X4::_254)), 0);
+    assert_eq!(match_e(E::::B), 1);
+    assert_eq!(match_e(E::::C), 2);
+    assert_eq!(match_e(E::A(false)), 0);
+    assert_eq!(match_e(E::A(true)), 0);
+    assert_eq!(match_e(E::::B), 1);
+    assert_eq!(match_e(E::::C), 2);
+}

From 8958c18b31fb657ad13d26c9849b9baabf4ff9a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Tue, 16 Aug 2022 07:46:33 -0700
Subject: [PATCH 423/482] Tweak span for `#[must_use]`

Do not point at whole statement, only at the expression (skip pointing at `;`)
---
 compiler/rustc_lint/src/unused.rs                  |  9 +++------
 .../2229_closure_analysis/match/issue-87097.stderr |  4 ++--
 .../cfg-attr-multi-true.stderr                     |  2 +-
 src/test/ui/generator/issue-52398.stderr           |  4 ++--
 src/test/ui/generator/issue-57084.stderr           |  2 +-
 src/test/ui/generator/match-bindings.stderr        |  2 +-
 src/test/ui/generator/reborrow-mut-upvar.stderr    |  2 +-
 .../too-live-local-in-immovable-gen.stderr         |  2 +-
 src/test/ui/generator/yield-in-args-rev.stderr     |  2 +-
 src/test/ui/generator/yield-in-box.stderr          |  2 +-
 src/test/ui/generator/yield-in-initializer.stderr  |  2 +-
 src/test/ui/generator/yield-subtype.stderr         |  2 +-
 src/test/ui/issues/issue-1460.stderr               |  2 +-
 src/test/ui/issues/issue-16256.stderr              |  2 +-
 src/test/ui/lint/fn_must_use.stderr                | 12 ++++++------
 .../ui/lint/unused/must-use-box-from-raw.stderr    |  2 +-
 src/test/ui/lint/unused/must_use-array.stderr      |  8 ++++----
 .../lint/unused/must_use-in-stdlib-traits.stderr   | 10 +++++-----
 src/test/ui/lint/unused/must_use-trait.stderr      |  6 +++---
 src/test/ui/lint/unused/must_use-unit.stderr       |  4 ++--
 src/test/ui/lint/unused/unused-closure.stderr      | 14 +++++++-------
 src/test/ui/lint/unused/unused-result.stderr       |  8 ++++----
 .../lint/unused/unused_attributes-must_use.stderr  | 14 +++++++-------
 src/test/ui/nll/issue-48623-generator.stderr       |  2 +-
 24 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 46706e4984451..3e8bd7a374dea 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -87,17 +87,14 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
 
 impl<'tcx> LateLintPass<'tcx> for UnusedResults {
     fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
-        let expr = match s.kind {
-            hir::StmtKind::Semi(ref expr) => &**expr,
-            _ => return,
-        };
+        let hir::StmtKind::Semi(expr) = s.kind else { return; };
 
         if let hir::ExprKind::Ret(..) = expr.kind {
             return;
         }
 
         let ty = cx.typeck_results().expr_ty(&expr);
-        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1);
+        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1);
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -119,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
             _ => None,
         };
         if let Some(def_id) = maybe_def_id {
-            fn_warned = check_must_use_def(cx, def_id, s.span, "return value of ", "");
+            fn_warned = check_must_use_def(cx, def_id, expr.span, "return value of ", "");
         } else if type_permits_lack_of_use {
             // We don't warn about unused unit or uninhabited types.
             // (See https://github.com/rust-lang/rust/issues/43806 for details.)
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
index 3840108597131..39ec71ba22a18 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
@@ -16,7 +16,7 @@ LL | /     || match out_ref {
 LL | |         Variant::A => (),
 LL | |         Variant::B => (),
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: closures are lazy and do nothing unless called
    = note: `#[warn(unused_must_use)]` on by default
@@ -28,7 +28,7 @@ LL | /     || match here.field {
 LL | |         Variant::A => (),
 LL | |         Variant::B => (),
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: closures are lazy and do nothing unless called
 
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
index 5f278f94b93bd..fbfcd45652f19 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
@@ -28,7 +28,7 @@ warning: unused `MustUseDeprecated` that must be used
   --> $DIR/cfg-attr-multi-true.rs:19:5
    |
 LL |     MustUseDeprecated::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/cfg-attr-multi-true.rs:7:9
diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr
index 30a6732f75956..539343275df60 100644
--- a/src/test/ui/generator/issue-52398.stderr
+++ b/src/test/ui/generator/issue-52398.stderr
@@ -4,7 +4,7 @@ warning: unused generator that must be used
 LL | /     move || {
 LL | |         A.test(yield);
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
@@ -16,7 +16,7 @@ LL | /     static move || {
 LL | |         yield *y.borrow();
 LL | |         return "Done";
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
 
diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr
index 29aca94408a82..8f1fc5e803194 100644
--- a/src/test/ui/generator/issue-57084.stderr
+++ b/src/test/ui/generator/issue-57084.stderr
@@ -7,7 +7,7 @@ LL | |         loop {
 LL | |             yield
 LL | |         }
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr
index b911b6661909a..3dd2d595445aa 100644
--- a/src/test/ui/generator/match-bindings.stderr
+++ b/src/test/ui/generator/match-bindings.stderr
@@ -8,7 +8,7 @@ LL | |                 match Enum::A(String::new()) {
 ...  |
 LL | |         }
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr
index e83dbf833bfa7..2e1fec35eaf52 100644
--- a/src/test/ui/generator/reborrow-mut-upvar.stderr
+++ b/src/test/ui/generator/reborrow-mut-upvar.stderr
@@ -8,7 +8,7 @@ LL | |             yield;
 ...  |
 LL | |         *bar = 2;
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
index 5cb43067fee6b..e262f213f63d2 100644
--- a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
+++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
@@ -8,7 +8,7 @@ LL | |             // and it should also find out that `a` is not live.
 ...  |
 LL | |             let _ = &a;
 LL | |         };
-   | |__________^
+   | |_________^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr
index c9e1ab722d47f..a87248f662100 100644
--- a/src/test/ui/generator/yield-in-args-rev.stderr
+++ b/src/test/ui/generator/yield-in-args-rev.stderr
@@ -5,7 +5,7 @@ LL | /     || {
 LL | |         let b = true;
 LL | |         foo(yield, &b);
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr
index 8587e1dc663bc..9d03ee00800c8 100644
--- a/src/test/ui/generator/yield-in-box.stderr
+++ b/src/test/ui/generator/yield-in-box.stderr
@@ -8,7 +8,7 @@ LL | |             let _t = box (&x, yield 0, &y);
 ...  |
 LL | |         }
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr
index 07de24662cf2e..ed14a2e3273af 100644
--- a/src/test/ui/generator/yield-in-initializer.stderr
+++ b/src/test/ui/generator/yield-in-initializer.stderr
@@ -8,7 +8,7 @@ LL | |             // See https://github.com/rust-lang/rust/issues/52792
 ...  |
 LL | |         }
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr
index fe10477bf7380..97862e91cd4a0 100644
--- a/src/test/ui/generator/yield-subtype.stderr
+++ b/src/test/ui/generator/yield-subtype.stderr
@@ -5,7 +5,7 @@ LL | /     || {
 LL | |         yield a;
 LL | |         yield b;
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr
index f0ff2cafd4466..eb7661fad56db 100644
--- a/src/test/ui/issues/issue-1460.stderr
+++ b/src/test/ui/issues/issue-1460.stderr
@@ -2,7 +2,7 @@ warning: unused closure that must be used
   --> $DIR/issue-1460.rs:6:5
    |
 LL |     {|i: u32| if 1 == i { }};
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr
index ca8e9a1bed337..d920530b57c69 100644
--- a/src/test/ui/issues/issue-16256.stderr
+++ b/src/test/ui/issues/issue-16256.stderr
@@ -2,7 +2,7 @@ warning: unused closure that must be used
   --> $DIR/issue-16256.rs:6:5
    |
 LL |     |c: u8| buf.push(c);
-   |     ^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
    = note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
index 2805720f035b8..657f23c60856f 100644
--- a/src/test/ui/lint/fn_must_use.stderr
+++ b/src/test/ui/lint/fn_must_use.stderr
@@ -2,7 +2,7 @@ warning: unused return value of `need_to_use_this_value` that must be used
   --> $DIR/fn_must_use.rs:55:5
    |
 LL |     need_to_use_this_value();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: it's important
 note: the lint level is defined here
@@ -15,13 +15,13 @@ warning: unused return value of `MyStruct::need_to_use_this_method_value` that m
   --> $DIR/fn_must_use.rs:60:5
    |
 LL |     m.need_to_use_this_method_value();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused return value of `EvenNature::is_even` that must be used
   --> $DIR/fn_must_use.rs:61:5
    |
 LL |     m.is_even(); // trait method!
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^
    |
    = note: no side effects
 
@@ -29,19 +29,19 @@ warning: unused return value of `MyStruct::need_to_use_this_associated_function_
   --> $DIR/fn_must_use.rs:64:5
    |
 LL |     MyStruct::need_to_use_this_associated_function_value();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused return value of `std::cmp::PartialEq::eq` that must be used
   --> $DIR/fn_must_use.rs:70:5
    |
 LL |     2.eq(&3);
-   |     ^^^^^^^^^
+   |     ^^^^^^^^
 
 warning: unused return value of `std::cmp::PartialEq::eq` that must be used
   --> $DIR/fn_must_use.rs:71:5
    |
 LL |     m.eq(&n);
-   |     ^^^^^^^^^
+   |     ^^^^^^^^
 
 warning: unused comparison that must be used
   --> $DIR/fn_must_use.rs:74:5
diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
index 011acc3bf5d6e..72118275774d1 100644
--- a/src/test/ui/lint/unused/must-use-box-from-raw.stderr
+++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
@@ -2,7 +2,7 @@ warning: unused return value of `Box::::from_raw` that must be used
   --> $DIR/must-use-box-from-raw.rs:8:5
    |
 LL |     Box::from_raw(ptr);
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = note: call `drop(from_raw(ptr))` if you intend to drop the `Box`
 note: the lint level is defined here
diff --git a/src/test/ui/lint/unused/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr
index 45a5317fccc6e..bba2b1ba078c6 100644
--- a/src/test/ui/lint/unused/must_use-array.stderr
+++ b/src/test/ui/lint/unused/must_use-array.stderr
@@ -2,7 +2,7 @@ error: unused array of `S` that must be used
   --> $DIR/must_use-array.rs:39:5
    |
 LL |     singleton();
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/must_use-array.rs:1:9
@@ -14,7 +14,7 @@ error: unused array of `S` that must be used
   --> $DIR/must_use-array.rs:40:5
    |
 LL |     many();
-   |     ^^^^^^^
+   |     ^^^^^^
 
 error: unused array of `S` in tuple element 0 that must be used
   --> $DIR/must_use-array.rs:41:6
@@ -26,7 +26,7 @@ error: unused array of implementers of `T` that must be used
   --> $DIR/must_use-array.rs:42:5
    |
 LL |     array_of_impl_trait();
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: unused array of boxed `T` trait objects in tuple element 1 that must be used
   --> $DIR/must_use-array.rs:43:5
@@ -38,7 +38,7 @@ error: unused array of arrays of arrays of `S` that must be used
   --> $DIR/must_use-array.rs:45:5
    |
 LL |     array_of_arrays_of_arrays();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
index f5199f43c74bd..ef738708d5f4e 100644
--- a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
+++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:42:4
    |
 LL |    iterator();
-   |    ^^^^^^^^^^^
+   |    ^^^^^^^^^^
    |
    = note: iterators are lazy and do nothing unless consumed
 note: the lint level is defined here
@@ -15,7 +15,7 @@ error: unused implementer of `Future` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:43:4
    |
 LL |    future();
-   |    ^^^^^^^^^
+   |    ^^^^^^^^
    |
    = note: futures do nothing unless you `.await` or poll them
 
@@ -23,7 +23,7 @@ error: unused implementer of `FnOnce` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:44:4
    |
 LL |    square_fn_once();
-   |    ^^^^^^^^^^^^^^^^^
+   |    ^^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -31,7 +31,7 @@ error: unused implementer of `FnMut` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:45:4
    |
 LL |    square_fn_mut();
-   |    ^^^^^^^^^^^^^^^^
+   |    ^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -39,7 +39,7 @@ error: unused implementer of `Fn` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:46:4
    |
 LL |    square_fn();
-   |    ^^^^^^^^^^^^
+   |    ^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
diff --git a/src/test/ui/lint/unused/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr
index a42eb8841789d..2f54964848359 100644
--- a/src/test/ui/lint/unused/must_use-trait.stderr
+++ b/src/test/ui/lint/unused/must_use-trait.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Critical` that must be used
   --> $DIR/must_use-trait.rs:33:5
    |
 LL |     get_critical();
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/must_use-trait.rs:1:9
@@ -14,13 +14,13 @@ error: unused boxed `Critical` trait object that must be used
   --> $DIR/must_use-trait.rs:34:5
    |
 LL |     get_boxed_critical();
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^
 
 error: unused boxed boxed `Critical` trait object that must be used
   --> $DIR/must_use-trait.rs:35:5
    |
 LL |     get_nested_boxed_critical();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unused boxed `Critical` trait object in tuple element 1 that must be used
   --> $DIR/must_use-trait.rs:37:5
diff --git a/src/test/ui/lint/unused/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr
index 7f25a19350862..9fcbc5074ea80 100644
--- a/src/test/ui/lint/unused/must_use-unit.stderr
+++ b/src/test/ui/lint/unused/must_use-unit.stderr
@@ -2,7 +2,7 @@ error: unused return value of `foo` that must be used
   --> $DIR/must_use-unit.rs:13:5
    |
 LL |     foo();
-   |     ^^^^^^
+   |     ^^^^^
    |
 note: the lint level is defined here
   --> $DIR/must_use-unit.rs:2:9
@@ -14,7 +14,7 @@ error: unused return value of `bar` that must be used
   --> $DIR/must_use-unit.rs:15:5
    |
 LL |     bar();
-   |     ^^^^^^
+   |     ^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr
index 4362abd2037ff..c3a82402e0a2e 100644
--- a/src/test/ui/lint/unused/unused-closure.stderr
+++ b/src/test/ui/lint/unused/unused-closure.stderr
@@ -4,7 +4,7 @@ error: unused closure that must be used
 LL | /     || {
 LL | |         println!("Hello!");
 LL | |     };
-   | |______^
+   | |_____^
    |
    = note: closures are lazy and do nothing unless called
 note: the lint level is defined here
@@ -17,7 +17,7 @@ error: unused implementer of `Future` that must be used
   --> $DIR/unused-closure.rs:13:5
    |
 LL |     async {};
-   |     ^^^^^^^^^
+   |     ^^^^^^^^
    |
    = note: futures do nothing unless you `.await` or poll them
 
@@ -25,7 +25,7 @@ error: unused closure that must be used
   --> $DIR/unused-closure.rs:14:5
    |
 LL |     || async {};
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -33,7 +33,7 @@ error: unused closure that must be used
   --> $DIR/unused-closure.rs:15:5
    |
 LL |     async || {};
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -41,7 +41,7 @@ error: unused array of boxed arrays of closures that must be used
   --> $DIR/unused-closure.rs:18:5
    |
 LL |     [Box::new([|| {}; 10]); 1];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -49,7 +49,7 @@ error: unused closure that must be used
   --> $DIR/unused-closure.rs:20:5
    |
 LL |     vec![|| "a"].pop().unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
@@ -57,7 +57,7 @@ error: unused closure that must be used
   --> $DIR/unused-closure.rs:23:9
    |
 LL |         || true;
-   |         ^^^^^^^^
+   |         ^^^^^^^
    |
    = note: closures are lazy and do nothing unless called
 
diff --git a/src/test/ui/lint/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr
index 087e06341cdde..4e1ba1fd9595f 100644
--- a/src/test/ui/lint/unused/unused-result.stderr
+++ b/src/test/ui/lint/unused/unused-result.stderr
@@ -2,7 +2,7 @@ error: unused `MustUse` that must be used
   --> $DIR/unused-result.rs:21:5
    |
 LL |     foo::();
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/unused-result.rs:2:25
@@ -14,7 +14,7 @@ error: unused `MustUseMsg` that must be used
   --> $DIR/unused-result.rs:22:5
    |
 LL |     foo::();
-   |     ^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^
    |
    = note: some message
 
@@ -34,13 +34,13 @@ error: unused `MustUse` that must be used
   --> $DIR/unused-result.rs:35:5
    |
 LL |     foo::();
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^
 
 error: unused `MustUseMsg` that must be used
   --> $DIR/unused-result.rs:36:5
    |
 LL |     foo::();
-   |     ^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^
    |
    = note: some message
 
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
index ce959ddbc4697..0f699429e0243 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -139,7 +139,7 @@ error: unused `X` that must be used
   --> $DIR/unused_attributes-must_use.rs:103:5
    |
 LL |     X;
-   |     ^^
+   |     ^
    |
 note: the lint level is defined here
   --> $DIR/unused_attributes-must_use.rs:2:28
@@ -151,37 +151,37 @@ error: unused `Y` that must be used
   --> $DIR/unused_attributes-must_use.rs:104:5
    |
 LL |     Y::Z;
-   |     ^^^^^
+   |     ^^^^
 
 error: unused `U` that must be used
   --> $DIR/unused_attributes-must_use.rs:105:5
    |
 LL |     U { unit: () };
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^
 
 error: unused return value of `U::method` that must be used
   --> $DIR/unused_attributes-must_use.rs:106:5
    |
 LL |     U::method();
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^
 
 error: unused return value of `foo` that must be used
   --> $DIR/unused_attributes-must_use.rs:107:5
    |
 LL |     foo();
-   |     ^^^^^^
+   |     ^^^^^
 
 error: unused return value of `foreign_foo` that must be used
   --> $DIR/unused_attributes-must_use.rs:110:9
    |
 LL |         foreign_foo();
-   |         ^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^
 
 error: unused return value of `Use::get_four` that must be used
   --> $DIR/unused_attributes-must_use.rs:118:5
    |
 LL |     ().get_four();
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 28 previous errors
 
diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr
index 1b35165db45dc..bfdfca2100406 100644
--- a/src/test/ui/nll/issue-48623-generator.stderr
+++ b/src/test/ui/nll/issue-48623-generator.stderr
@@ -2,7 +2,7 @@ warning: unused generator that must be used
   --> $DIR/issue-48623-generator.rs:15:5
    |
 LL |     move || { d; yield; &mut *r };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: generators are lazy and do nothing unless resumed
    = note: `#[warn(unused_must_use)]` on by default

From d7f7a1819400c422e2c2a2f7234d26b3dd676ba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Tue, 16 Aug 2022 07:56:42 -0700
Subject: [PATCH 424/482] Consider `#[must_use]` annotation on `async fn` as
 also affecting the `Future::Output`

No longer lint against `#[must_use] async fn foo()`.

When encountering a statement that awaits on a `Future`, check if the
`Future`'s parent item is annotated with `#[must_use]` and emit a lint
if so. This effectively makes `must_use` an annotation on the
`Future::Output` instead of only the `Future` itself.

Fix #78149.
---
 compiler/rustc_lint/src/unused.rs           | 14 +++-
 compiler/rustc_passes/src/check_attr.rs     | 14 +---
 src/test/ui/lint/unused/unused-async.rs     | 29 ++++++--
 src/test/ui/lint/unused/unused-async.stderr | 79 ++++++++++++++-------
 4 files changed, 93 insertions(+), 43 deletions(-)

diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 3e8bd7a374dea..1a5515530ae9f 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::util::elaborate_predicates_with_span;
 use rustc_middle::ty::adjustment;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, DefIdTree, Ty};
 use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::{BytePos, Span};
@@ -93,6 +93,18 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
             return;
         }
 
+        if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
+            && let ty = cx.typeck_results().expr_ty(&await_expr)
+            && let ty::Opaque(def_id, _) = ty.kind()
+            && cx.tcx.ty_is_opaque_future(ty)
+            && let parent = cx.tcx.parent(*def_id)
+            && check_must_use_def(cx, parent, expr.span, "awaited future returned by ", "")
+        {
+            // We have a bare `foo().await;` on an opaque type from an async function that was
+            // annotated with `#[must_use]`.
+            return;
+        }
+
         let ty = cx.typeck_results().expr_ty(&expr);
         let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1);
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 27a57adf964a3..e0da0096c4e1e 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -139,7 +139,7 @@ impl CheckAttrVisitor<'_> {
                 sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
                 sym::const_trait => self.check_const_trait(attr, span, target),
                 sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
-                sym::must_use => self.check_must_use(hir_id, &attr, span, target),
+                sym::must_use => self.check_must_use(hir_id, &attr, target),
                 sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target),
                 sym::rustc_allow_incoherent_impl => {
                     self.check_allow_incoherent_impl(&attr, span, target)
@@ -1163,17 +1163,7 @@ impl CheckAttrVisitor<'_> {
     }
 
     /// Warns against some misuses of `#[must_use]`
-    fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
-        let node = self.tcx.hir().get(hir_id);
-        if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() {
-            self.tcx.emit_spanned_lint(
-                UNUSED_ATTRIBUTES,
-                hir_id,
-                attr.span,
-                errors::MustUseAsync { span }
-            );
-        }
-
+    fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) -> bool {
         if !matches!(
             target,
             Target::Fn
diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs
index 7d17af1157379..eda28dab27fac 100644
--- a/src/test/ui/lint/unused/unused-async.rs
+++ b/src/test/ui/lint/unused/unused-async.rs
@@ -1,24 +1,43 @@
 // edition:2018
-// run-pass
-#![allow(dead_code)]
+#![deny(unused_must_use)]
+
 
 #[must_use]
-//~^ WARNING `must_use`
-async fn test() -> i32 {
+async fn foo() -> i32 {
     1
 }
 
+#[must_use]
+fn bar() -> impl std::future::Future {
+    async {
+        42
+    }
+}
+
+async fn baz() -> i32 {
+    0
+}
 
 struct Wowee {}
 
 impl Wowee {
     #[must_use]
-    //~^ WARNING `must_use`
     async fn test_method() -> i32 {
         1
     }
 }
 
+async fn test() {
+    foo(); //~ ERROR unused return value of `foo` that must be used
+    //~^ ERROR unused implementer of `Future` that must be used
+    foo().await; //~ ERROR unused awaited future returned by `foo` that must be used
+    bar(); //~ ERROR unused return value of `bar` that must be used
+    //~^ ERROR unused implementer of `Future` that must be used
+    bar().await; //~ ERROR unused awaited future returned by `bar` that must be used
+    baz(); //~ ERROR unused implementer of `Future` that must be used
+    baz().await; // ok
+}
+
 /* FIXME(guswynn) update this test when async-fn-in-traits works
 trait Doer {
     #[must_use]
diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr
index 6bbc9e2bf0088..ae284681720af 100644
--- a/src/test/ui/lint/unused/unused-async.stderr
+++ b/src/test/ui/lint/unused/unused-async.stderr
@@ -1,26 +1,55 @@
-warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
-  --> $DIR/unused-async.rs:5:1
-   |
-LL |   #[must_use]
-   |   ^^^^^^^^^^^
-LL |
-LL | / async fn test() -> i32 {
-LL | |     1
-LL | | }
-   | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-   |
-   = note: `#[warn(unused_attributes)]` on by default
-
-warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
-  --> $DIR/unused-async.rs:15:5
-   |
-LL |       #[must_use]
-   |       ^^^^^^^^^^^
-LL |
-LL | /     async fn test_method() -> i32 {
-LL | |         1
-LL | |     }
-   | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-
-warning: 2 warnings emitted
+error: unused implementer of `Future` that must be used
+  --> $DIR/unused-async.rs:31:5
+   |
+LL |     foo();
+   |     ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-async.rs:2:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+   = note: futures do nothing unless you `.await` or poll them
+
+error: unused return value of `foo` that must be used
+  --> $DIR/unused-async.rs:31:5
+   |
+LL |     foo();
+   |     ^^^^^
+
+error: unused awaited future returned by `foo` that must be used
+  --> $DIR/unused-async.rs:33:5
+   |
+LL |     foo().await;
+   |     ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+  --> $DIR/unused-async.rs:34:5
+   |
+LL |     bar();
+   |     ^^^^^
+   |
+   = note: futures do nothing unless you `.await` or poll them
+
+error: unused return value of `bar` that must be used
+  --> $DIR/unused-async.rs:34:5
+   |
+LL |     bar();
+   |     ^^^^^
+
+error: unused awaited future returned by `bar` that must be used
+  --> $DIR/unused-async.rs:36:5
+   |
+LL |     bar().await;
+   |     ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+  --> $DIR/unused-async.rs:37:5
+   |
+LL |     baz();
+   |     ^^^^^
+   |
+   = note: futures do nothing unless you `.await` or poll them
+
+error: aborting due to 7 previous errors
 

From 4614e7eef6240ab0cc588bc74a76dae151dd22f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Wed, 17 Aug 2022 08:21:43 -0700
Subject: [PATCH 425/482] review comments

---
 compiler/rustc_lint/src/unused.rs           | 13 ++++++++++---
 src/test/ui/lint/unused/unused-async.rs     |  4 ++--
 src/test/ui/lint/unused/unused-async.stderr |  4 ++--
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 1a5515530ae9f..045d76cac62b8 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -95,10 +95,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
 
         if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
             && let ty = cx.typeck_results().expr_ty(&await_expr)
-            && let ty::Opaque(def_id, _) = ty.kind()
+            && let ty::Opaque(future_def_id, _) = ty.kind()
             && cx.tcx.ty_is_opaque_future(ty)
-            && let parent = cx.tcx.parent(*def_id)
-            && check_must_use_def(cx, parent, expr.span, "awaited future returned by ", "")
+            // FIXME: This also includes non-async fns that return `impl Future`.
+            && let async_fn_def_id = cx.tcx.parent(*future_def_id)
+            && check_must_use_def(
+                cx,
+                async_fn_def_id,
+                expr.span,
+                "output of future returned by ",
+                "",
+            )
         {
             // We have a bare `foo().await;` on an opaque type from an async function that was
             // annotated with `#[must_use]`.
diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs
index eda28dab27fac..4be93aa155ad9 100644
--- a/src/test/ui/lint/unused/unused-async.rs
+++ b/src/test/ui/lint/unused/unused-async.rs
@@ -30,10 +30,10 @@ impl Wowee {
 async fn test() {
     foo(); //~ ERROR unused return value of `foo` that must be used
     //~^ ERROR unused implementer of `Future` that must be used
-    foo().await; //~ ERROR unused awaited future returned by `foo` that must be used
+    foo().await; //~ ERROR unused output of future returned by `foo` that must be used
     bar(); //~ ERROR unused return value of `bar` that must be used
     //~^ ERROR unused implementer of `Future` that must be used
-    bar().await; //~ ERROR unused awaited future returned by `bar` that must be used
+    bar().await; //~ ERROR unused output of future returned by `bar` that must be used
     baz(); //~ ERROR unused implementer of `Future` that must be used
     baz().await; // ok
 }
diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr
index ae284681720af..abc49599309ca 100644
--- a/src/test/ui/lint/unused/unused-async.stderr
+++ b/src/test/ui/lint/unused/unused-async.stderr
@@ -17,7 +17,7 @@ error: unused return value of `foo` that must be used
 LL |     foo();
    |     ^^^^^
 
-error: unused awaited future returned by `foo` that must be used
+error: unused output of future returned by `foo` that must be used
   --> $DIR/unused-async.rs:33:5
    |
 LL |     foo().await;
@@ -37,7 +37,7 @@ error: unused return value of `bar` that must be used
 LL |     bar();
    |     ^^^^^
 
-error: unused awaited future returned by `bar` that must be used
+error: unused output of future returned by `bar` that must be used
   --> $DIR/unused-async.rs:36:5
    |
 LL |     bar().await;

From 327ac9ec0bb5f728d8deedd4db28da50214bf811 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
Date: Thu, 10 Nov 2022 19:01:33 -0800
Subject: [PATCH 426/482] Fix tests after rebase

---
 src/test/ui/lint/unused/unused-async.stderr      | 2 +-
 src/test/ui/lint/unused/unused-supertrait.stderr | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr
index abc49599309ca..4bcb26dc16586 100644
--- a/src/test/ui/lint/unused/unused-async.stderr
+++ b/src/test/ui/lint/unused/unused-async.stderr
@@ -4,12 +4,12 @@ error: unused implementer of `Future` that must be used
 LL |     foo();
    |     ^^^^^
    |
+   = note: futures do nothing unless you `.await` or poll them
 note: the lint level is defined here
   --> $DIR/unused-async.rs:2:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: futures do nothing unless you `.await` or poll them
 
 error: unused return value of `foo` that must be used
   --> $DIR/unused-async.rs:31:5
diff --git a/src/test/ui/lint/unused/unused-supertrait.stderr b/src/test/ui/lint/unused/unused-supertrait.stderr
index d2f8c00784817..cb45add9c2b1b 100644
--- a/src/test/ui/lint/unused/unused-supertrait.stderr
+++ b/src/test/ui/lint/unused/unused-supertrait.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used
   --> $DIR/unused-supertrait.rs:9:5
    |
 LL |     it();
-   |     ^^^^^
+   |     ^^^^
    |
    = note: iterators are lazy and do nothing unless consumed
 note: the lint level is defined here

From 2666f0ce02718e9e5703f3ed632ae98b793d8099 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?=
 
Date: Sun, 23 Oct 2022 19:12:23 +0200
Subject: [PATCH 427/482] test attr: point at return type if Termination bound
 unsatisfied

---
 compiler/rustc_builtin_macros/src/test.rs      | 18 ++++++++++++------
 .../termination-trait-test-wrong-type.stderr   | 12 +++++-------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index fee5d04cdae85..b62840d4bc822 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -112,7 +112,7 @@ pub fn expand_test_or_bench(
     };
 
     // Note: non-associated fn items are already handled by `expand_test_or_bench`
-    if !matches!(item.kind, ast::ItemKind::Fn(_)) {
+    let ast::ItemKind::Fn(fn_) = &item.kind else {
         let diag = &cx.sess.parse_sess.span_diagnostic;
         let msg = "the `#[test]` attribute may only be used on a non-associated function";
         let mut err = match item.kind {
@@ -130,7 +130,7 @@ pub fn expand_test_or_bench(
             .emit();
 
         return vec![Annotatable::Item(item)];
-    }
+    };
 
     // has_*_signature will report any errors in the type so compilation
     // will fail. We shouldn't try to expand in this case because the errors
@@ -141,12 +141,14 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp));
+    let sp = cx.with_def_site_ctxt(item.span);
+    let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
+    let attr_sp = cx.with_def_site_ctxt(attr_sp);
 
     let test_id = Ident::new(sym::test, attr_sp);
 
     // creates test::$name
-    let test_path = |name| cx.path(sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
+    let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]);
 
     // creates test::ShouldPanic::$name
     let should_panic_path = |name| {
@@ -192,7 +194,7 @@ pub fn expand_test_or_bench(
                         vec![
                             // super::$test_fn(b)
                             cx.expr_call(
-                                sp,
+                                ret_ty_sp,
                                 cx.expr_path(cx.path(sp, vec![item.ident])),
                                 vec![cx.expr_ident(sp, b)],
                             ),
@@ -216,7 +218,11 @@ pub fn expand_test_or_bench(
                         cx.expr_path(test_path("assert_test_result")),
                         vec![
                             // $test_fn()
-                            cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![]), // )
+                            cx.expr_call(
+                                ret_ty_sp,
+                                cx.expr_path(cx.path(sp, vec![item.ident])),
+                                vec![],
+                            ), // )
                         ],
                     ), // }
                 ), // )
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6ee32314607ad..9577952119adb 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,12 +1,10 @@
 error[E0277]: the trait bound `f32: Termination` is not satisfied
-  --> $DIR/termination-trait-test-wrong-type.rs:6:1
+  --> $DIR/termination-trait-test-wrong-type.rs:6:31
    |
-LL |   #[test]
-   |   ------- in this procedural macro expansion
-LL | / fn can_parse_zero_as_f32() -> Result {
-LL | |     "0".parse()
-LL | | }
-   | |_^ the trait `Termination` is not implemented for `f32`
+LL | #[test]
+   | ------- in this procedural macro expansion
+LL | fn can_parse_zero_as_f32() -> Result {
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Termination` is not implemented for `f32`
    |
    = note: required for `Result` to implement `Termination`
 note: required by a bound in `assert_test_result`

From e4327ff9c92e9e45b8e150913c5805bbff81a082 Mon Sep 17 00:00:00 2001
From: Pete 
Date: Thu, 3 Nov 2022 14:15:32 +0100
Subject: [PATCH 428/482] Fix broken link in error code E0706 docs

Corresponding subsection in async book is not `07.05` not `07.06`.

The information on the linked page is the same so it may be reasonable to remove the whole sentence.
---
 compiler/rustc_error_codes/src/error_codes/E0706.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_error_codes/src/error_codes/E0706.md b/compiler/rustc_error_codes/src/error_codes/E0706.md
index d379b8a2384c6..fabd855a222f0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0706.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0706.md
@@ -56,4 +56,4 @@ You might be interested in visiting the [async book] for further information.
 [`async-trait` crate]: https://crates.io/crates/async-trait
 [async-is-hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
 [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
-[async book]: https://rust-lang.github.io/async-book/07_workarounds/06_async_in_traits.html
+[async book]: https://rust-lang.github.io/async-book/07_workarounds/05_async_in_traits.html

From 4352440188793ddac1b96123ef3b0cfaba200e59 Mon Sep 17 00:00:00 2001
From: Ayush Singh 
Date: Tue, 8 Nov 2022 17:22:44 +0530
Subject: [PATCH 429/482] Add retry flag to remote-test-server

This allows retrying binding TCP Socket multiple times. This is useful
when using emulators as network might not be available in the beginning.
This was orignally implemented in https://github.com/rust-lang/rust/pull/100316

Signed-off-by: Ayush Singh 
---
 src/tools/remote-test-server/src/main.rs | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs
index ec992da681219..8e7c39e72b68b 100644
--- a/src/tools/remote-test-server/src/main.rs
+++ b/src/tools/remote-test-server/src/main.rs
@@ -39,6 +39,8 @@ macro_rules! t {
 }
 
 static TEST: AtomicUsize = AtomicUsize::new(0);
+const RETRY_INTERVAL: u64 = 1;
+const NUMBER_OF_RETRIES: usize = 5;
 
 #[derive(Copy, Clone)]
 struct Config {
@@ -115,7 +117,7 @@ fn main() {
     let config = Config::parse_args();
     println!("starting test server");
 
-    let listener = t!(TcpListener::bind(config.bind));
+    let listener = bind_socket(config.bind);
     let (work, tmp): (PathBuf, PathBuf) = if cfg!(target_os = "android") {
         ("/data/local/tmp/work".into(), "/data/local/tmp/work/tmp".into())
     } else {
@@ -159,6 +161,16 @@ fn main() {
     }
 }
 
+fn bind_socket(addr: SocketAddr) -> TcpListener {
+    for _ in 0..(NUMBER_OF_RETRIES - 1) {
+        if let Ok(x) = TcpListener::bind(addr) {
+            return x;
+        }
+        std::thread::sleep(std::time::Duration::from_secs(RETRY_INTERVAL));
+    }
+    TcpListener::bind(addr).unwrap()
+}
+
 fn handle_push(socket: TcpStream, work: &Path, config: Config) {
     let mut reader = BufReader::new(socket);
     let dst = recv(&work, &mut reader);

From 16f79935d03b254185d97a20919ac3c5c9ef15b3 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Tue, 8 Nov 2022 21:12:17 +0100
Subject: [PATCH 430/482] Migrate :target rules to use CSS variables

---
 src/librustdoc/html/static/css/rustdoc.css      | 2 ++
 src/librustdoc/html/static/css/themes/ayu.css   | 7 ++-----
 src/librustdoc/html/static/css/themes/dark.css  | 7 ++-----
 src/librustdoc/html/static/css/themes/light.css | 7 ++-----
 4 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 86a5b0b303f39..972ceb67e7648 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1269,6 +1269,8 @@ h3.variant {
 
 :target {
 	padding-right: 3px;
+	background-color: var(--target-background-color);
+	border-right: 3px solid var(--target-border-color);
 }
 
 .notable-traits-tooltip {
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 129ef6e10e7e7..2fa1fa39d63ab 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -63,6 +63,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--test-arrow-background-color: rgba(57, 175, 215, 0.09);
 	--test-arrow-hover-color: #c5c5c5;
 	--test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
+	--target-background-color: rgba(255, 236, 164, 0.06);
+	--target-border-color: rgba(255, 180, 76, 0.85);
 	--rust-logo-filter: drop-shadow(1px 0 0px #fff)
 		drop-shadow(0 1px 0 #fff)
 		drop-shadow(-1px 0 0 #fff)
@@ -168,11 +170,6 @@ details.rustdoc-toggle > summary::before {
 	color: #788797;
 }
 
-:target {
-	background: rgba(255, 236, 164, 0.06);
-	border-right: 3px solid rgba(255, 180, 76, 0.85);
-}
-
 .search-failed a {
 	color: #39AFD7;
 }
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 7cd2d7817d59d..43f8dd42ab347 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -58,6 +58,8 @@
 	--test-arrow-background-color: rgba(78, 139, 202, 0.2);
 	--test-arrow-hover-color: #dedede;
 	--test-arrow-hover-background-color: #4e8bca;
+	--target-background-color: #494a3d;
+	--target-border-color: #bb7410;
 	--rust-logo-filter: drop-shadow(1px 0 0px #fff)
 		drop-shadow(0 1px 0 #fff)
 		drop-shadow(-1px 0 0 #fff)
@@ -90,11 +92,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(100%);
 }
 
-:target {
-	background-color: #494a3d;
-	border-right: 3px solid #bb7410;
-}
-
 .search-failed a {
 	color: #0089ff;
 }
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index c41ec24884127..c8c5289ab540c 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -58,6 +58,8 @@
 	--test-arrow-background-color: rgba(78, 139, 202, 0.2);
 	--test-arrow-hover-color: #f5f5f5;
 	--test-arrow-hover-background-color: #4e8bca;
+	--target-background-color: #fdFfd3;
+	--target-border-color: #ad7c37;
 	--rust-logo-filter: initial;
 	/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
 	--crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg)
@@ -83,11 +85,6 @@ body.source .example-wrap pre.rust a {
 	background: #eee;
 }
 
-:target {
-	background: #FDFFD3;
-	border-right: 3px solid #AD7C37;
-}
-
 .search-failed a {
 	color: #3873AD;
 }

From 5dff73da03c9fe0813ba84637c23874184fedc90 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Tue, 8 Nov 2022 21:12:41 +0100
Subject: [PATCH 431/482] Add GUI test for :target

---
 src/test/rustdoc-gui/target.goml | 35 ++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 src/test/rustdoc-gui/target.goml

diff --git a/src/test/rustdoc-gui/target.goml b/src/test/rustdoc-gui/target.goml
new file mode 100644
index 0000000000000..3e5c30dc7eafe
--- /dev/null
+++ b/src/test/rustdoc-gui/target.goml
@@ -0,0 +1,35 @@
+// Check that the targetted element has the expected styles.
+goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
+show-text: true
+
+// Confirming that the method is the target.
+assert: "#method\.a_method:target"
+
+define-function: (
+    "check-style",
+    (theme, background, border),
+    [
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        ("reload"),
+        ("assert-css", ("#method\.a_method:target", {
+            "background-color": |background|,
+            "border-right": "3px solid " + |border|,
+        })),
+    ],
+)
+
+call-function: ("check-style", {
+    "theme": "ayu",
+    "background": "rgba(255, 236, 164, 0.06)",
+    "border": "rgba(255, 180, 76, 0.85)",
+})
+call-function: ("check-style", {
+    "theme": "dark",
+    "background": "rgb(73, 74, 61)",
+    "border": "rgb(187, 116, 16)",
+})
+call-function: ("check-style", {
+    "theme": "light",
+    "background": "rgb(253, 255, 211)",
+    "border": "rgb(173, 124, 55)",
+})

From d1ed5c74a8a022fe8c2f4f31c1d08db7f8c5db33 Mon Sep 17 00:00:00 2001
From: Cameron Steffen 
Date: Wed, 9 Nov 2022 10:05:38 -0600
Subject: [PATCH 432/482] Add domain size check to fix ICE

---
 compiler/rustc_middle/src/values.rs           |  3 +-
 .../parser/issue-103748-ICE-wrong-braces.rs   |  8 +++
 .../issue-103748-ICE-wrong-braces.stderr      | 51 +++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/parser/issue-103748-ICE-wrong-braces.rs
 create mode 100644 src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr

diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index f4b4c3fb05a7c..f4562cdfb88dc 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -185,7 +185,8 @@ fn find_item_ty_spans(
                 });
                 if check_params && let Some(args) = path.segments.last().unwrap().args {
                     let params_in_repr = tcx.params_in_repr(def_id);
-                    for (i, arg) in args.args.iter().enumerate() {
+                    // the domain size check is needed because the HIR may not be well-formed at this point
+                    for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) {
                         if let hir::GenericArg::Type(ty) = arg && params_in_repr.contains(i as u32) {
                             find_item_ty_spans(tcx, ty, needle, spans, seen_representable);
                         }
diff --git a/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs b/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs
new file mode 100644
index 0000000000000..8012cb652bd88
--- /dev/null
+++ b/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs
@@ -0,0 +1,8 @@
+#![crate_type = "lib"]
+
+struct Apple((Apple, Option(Banana ? Citron)));
+//~^ ERROR invalid `?` in type
+//~| ERROR expected one of `)` or `,`, found `Citron`
+//~| ERROR cannot find type `Citron` in this scope [E0412]
+//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
+//~| ERROR recursive type `Apple` has infinite size [E0072]
diff --git a/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr b/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr
new file mode 100644
index 0000000000000..b0d8b03ae08c3
--- /dev/null
+++ b/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr
@@ -0,0 +1,51 @@
+error: invalid `?` in type
+  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:36
+   |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+   |                                    ^ `?` is only allowed on expressions, not types
+   |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+   |
+LL | struct Apple((Apple, Option(Option Citron)));
+   |                             +++++++       ~
+
+error: expected one of `)` or `,`, found `Citron`
+  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
+   |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+   |                                     -^^^^^^ expected one of `)` or `,`
+   |                                     |
+   |                                     help: missing `,`
+
+error[E0412]: cannot find type `Citron` in this scope
+  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
+   |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+   |                                      ^^^^^^ not found in this scope
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
+   |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL | struct Apple((Apple, Option));
+   |                            ~               ~
+
+error[E0072]: recursive type `Apple` has infinite size
+  --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
+   |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+   | ^^^^^^^^^^^^  ----- recursive without indirection
+   |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+   |
+LL | struct Apple((Box, Option(Banana ? Citron)));
+   |               ++++     +
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0072, E0214, E0412.
+For more information about an error, try `rustc --explain E0072`.

From 75252f22bf2739876c8191142769c06a618df1c7 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Wed, 9 Nov 2022 22:00:13 +0100
Subject: [PATCH 433/482] Don't ICE on operator trait methods with generic
 methods

Emit a fatal error instead.
---
 .../locales/en-US/hir_analysis.ftl            |  3 +++
 compiler/rustc_hir_typeck/src/errors.rs       |  8 +++++++
 compiler/rustc_hir_typeck/src/method/mod.rs   |  9 +++++++-
 src/test/ui/traits/invalid_operator_trait.rs  | 23 +++++++++++++++++++
 .../ui/traits/invalid_operator_trait.stderr   |  8 +++++++
 5 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/traits/invalid_operator_trait.rs
 create mode 100644 src/test/ui/traits/invalid_operator_trait.stderr

diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
index 74088f4dfbe70..d27edd47470e8 100644
--- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
@@ -150,3 +150,6 @@ hir_analysis_const_bound_for_non_const_trait =
 hir_analysis_self_in_impl_self =
     `Self` is not valid in the self type of an impl block
     .note = replace `Self` with a different type
+
+hir_analysis_op_trait_generic_params =
+    `{$method_name}` must not have any generic parameters
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index cfb408396da05..afac6e7d94a81 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -125,3 +125,11 @@ pub struct AddMissingParenthesesInRange {
     #[suggestion_part(code = ")")]
     pub right: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_op_trait_generic_params)]
+pub struct OpMethodGenericParams {
+    #[primary_span]
+    pub span: Span,
+    pub method_name: String,
+}
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 2c7b3bbf31c20..4a8b774936543 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -10,6 +10,7 @@ mod suggest;
 pub use self::suggest::SelfSource;
 pub use self::MethodError::*;
 
+use crate::errors::OpMethodGenericParams;
 use crate::{Expectation, FnCtxt};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, Diagnostic};
@@ -443,7 +444,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let def_id = method_item.def_id;
         let generics = tcx.generics_of(def_id);
-        assert_eq!(generics.params.len(), 0);
+
+        if generics.params.len() != 0 {
+            tcx.sess.emit_fatal(OpMethodGenericParams {
+                span: tcx.def_span(method_item.def_id),
+                method_name: m_name.to_string(),
+            });
+        }
 
         debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
         let mut obligations = vec![];
diff --git a/src/test/ui/traits/invalid_operator_trait.rs b/src/test/ui/traits/invalid_operator_trait.rs
new file mode 100644
index 0000000000000..7ea3b0d5bac76
--- /dev/null
+++ b/src/test/ui/traits/invalid_operator_trait.rs
@@ -0,0 +1,23 @@
+#![crate_type = "lib"]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![no_core]
+
+#[lang="sized"]
+pub trait Sized {
+    // Empty.
+}
+
+#[lang = "add"]
+trait Add {
+    type Output;
+
+    fn add(self, _: RHS) -> Self::Output;
+    //~^ ERROR `add` must not have any generic parameters
+}
+
+#[allow(unreachable_code)]
+fn ice(a: usize) {
+    let r = loop {};
+    r = r + a;
+}
diff --git a/src/test/ui/traits/invalid_operator_trait.stderr b/src/test/ui/traits/invalid_operator_trait.stderr
new file mode 100644
index 0000000000000..8c6e3695905ee
--- /dev/null
+++ b/src/test/ui/traits/invalid_operator_trait.stderr
@@ -0,0 +1,8 @@
+error: `add` must not have any generic parameters
+  --> $DIR/invalid_operator_trait.rs:15:5
+   |
+LL |     fn add(self, _: RHS) -> Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+

From 362b4bd41c38efbbe7a8e80ccf5e8e0bfb937b20 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Wed, 9 Nov 2022 22:37:17 +0100
Subject: [PATCH 434/482] Display help message when fluent arg was referenced
 incorrectly

The fluent argument syntax is a little special and easy to get wrong, so
we emit a small help message when someone gets it wrong.

Example:
```
parser_mismatched_closing_delimiter = mismatched closing delimiter: `${delimiter}`
```
panics with
```
thread 'rustc' panicked at 'Encountered errors while formatting message for `parser_mismatched_closing_delimiter`
help: Argument `delimiter` exists but was not referenced correctly. Try using `{$delimiter}` instead
attr: `None`
args: `FluentArgs([("delimiter", String("}"))])`
errors: `[ResolverError(Reference(Message { id: "delimiter", attribute: None }))]`', compiler/rustc_errors/src/translation.rs:123:21
```
---
 compiler/rustc_error_messages/src/lib.rs |  3 +-
 compiler/rustc_errors/src/translation.rs | 38 ++++++++++++++++++------
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index e34acba105776..0b1b75471a661 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -30,7 +30,8 @@ use intl_memoizer::concurrent::IntlLangMemoizer;
 #[cfg(not(parallel_compiler))]
 use intl_memoizer::IntlLangMemoizer;
 
-pub use fluent_bundle::{FluentArgs, FluentError, FluentValue};
+pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
+
 pub use unic_langid::{langid, LanguageIdentifier};
 
 // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index a7737b467b75b..a452fac074787 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -1,7 +1,10 @@
 use crate::snippet::Style;
 use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
 use rustc_data_structures::sync::Lrc;
-use rustc_error_messages::FluentArgs;
+use rustc_error_messages::{
+    fluent_bundle::resolver::errors::{ReferenceKind, ResolverError},
+    FluentArgs, FluentError,
+};
 use std::borrow::Cow;
 
 /// Convert diagnostic arguments (a rustc internal type that exists to implement
@@ -102,14 +105,31 @@ pub trait Translate {
             .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
             .map(|(translated, errs)| {
                 // Always bail out for errors with the fallback bundle.
-                assert!(
-                    errs.is_empty(),
-                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
-                    identifier,
-                    attr,
-                    args,
-                    errs
-                );
+
+                let mut help_messages = vec![];
+
+                if !errs.is_empty() {
+                    for error in &errs {
+                        match error {
+                            FluentError::ResolverError(ResolverError::Reference(
+                                ReferenceKind::Message { id, .. },
+                            )) if args.iter().any(|(arg_id, _)| arg_id == id) => {
+                                help_messages.push(format!("Argument `{id}` exists but was not referenced correctly. Try using `{{${id}}}` instead"));
+                            }
+                            _ => {}
+                        }
+                    }
+
+                    panic!(
+                        "Encountered errors while formatting message for `{identifier}`\n\
+                        help: {}\n\
+                        attr: `{attr:?}`\n\
+                        args: `{args:?}`\n\
+                        errors: `{errs:?}`",
+                        help_messages.join("\nhelp: ")
+                    );
+                }
+
                 translated
             })
             .expect("failed to find message in primary or fallback fluent bundles")

From 09495e5e08f56a3615191325d7c4954da1ef0896 Mon Sep 17 00:00:00 2001
From: kubycsolutions 
Date: Wed, 9 Nov 2022 17:26:25 -0500
Subject: [PATCH 435/482] Avoid runtime dependency on static libstdc++

Usually, we do want to use the static C++ library when building rustc_llvm, but do not want to have that dependency at compiler runtime. Change the defaults to Make It So.
---
 config.toml.example     | 7 ++++---
 src/bootstrap/config.rs | 2 +-
 src/ci/run.sh           | 4 ++++
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/config.toml.example b/config.toml.example
index 2373fb2ec4fb0..c94a27b12a3a7 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -87,9 +87,10 @@ changelog-seen = 2
 # this flag will indicate that this version check should not be done.
 #version-check = true
 
-# Link libstdc++ statically into the rustc_llvm instead of relying on a
-# dynamic version to be available.
-#static-libstdcpp = true
+# When true, link libstdc++ statically into the rustc_llvm.
+# This is useful if you don't want to use the dynamic version of that
+# library provided by LLVM.
+#static-libstdcpp = false
 
 # Whether to use Ninja to build LLVM. This runs much faster than make.
 #ninja = true
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index ba50ce9ec2426..2afce4fac42f8 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -781,7 +781,7 @@ impl Config {
         config.llvm_optimize = true;
         config.ninja_in_file = true;
         config.llvm_version_check = true;
-        config.llvm_static_stdcpp = true;
+        config.llvm_static_stdcpp = false;
         config.backtrace = true;
         config.rust_optimize = true;
         config.rust_optimize_tests = true;
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 9a247fb60a8ee..7de06ec35c36b 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -123,6 +123,10 @@ else
   # (And PGO is its own can of worms).
   if [ "$NO_DOWNLOAD_CI_LLVM" = "" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.download-ci-llvm=if-available"
+  else
+    # When building for CI we want to use the static C++ Standard library
+    # included with LLVM, since a dynamic libstdcpp may not be available.
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.static-libstdcpp"
   fi
 fi
 

From c7c4492088a9bf36f5e7f4dc7803270fc81daa9a Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Thu, 24 Mar 2022 19:24:40 -0500
Subject: [PATCH 436/482] Allow specialized const trait impls.

Fixes #95186.
Fixes #95187.
---
 .../src/impl_wf_check/min_specialization.rs   | 65 +++++++++++++------
 .../const-default-const-specialized.rs        | 38 +++++++++++
 .../const-default-non-const-specialized.rs    | 37 +++++++++++
 ...const-default-non-const-specialized.stderr | 37 +++++++++++
 .../specialization/default-keyword.rs         | 14 ++++
 .../issue-95186-specialize-on-tilde-const.rs  | 34 ++++++++++
 ...87-same-trait-bound-different-constness.rs | 28 ++++++++
 .../non-const-default-const-specialized.rs    | 34 ++++++++++
 ...non-const-default-const-specialized.stderr | 20 ++++++
 9 files changed, 286 insertions(+), 21 deletions(-)
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr

diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 267077cdab4e6..f65760b9c98ca 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -80,6 +80,7 @@ use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
+use tracing::instrument;
 
 pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
     if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
@@ -103,13 +104,11 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
 }
 
 /// Check that `impl1` is a sound specialization
+#[instrument(level = "debug", skip(tcx))]
 fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
     if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
         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
-        );
+        debug!(?impl2_def_id, ?impl2_substs);
 
         let parent_substs = if impl2_node.is_from_trait() {
             impl2_substs.to_vec()
@@ -280,13 +279,13 @@ fn check_static_lifetimes<'tcx>(
 ///
 /// Each predicate `P` must be:
 ///
-/// * global (not reference any parameters)
-/// * `T: Tr` predicate where `Tr` is an always-applicable trait
-/// * on the base `impl impl2`
-///     * Currently this check is done using syntactic equality, which is
-///       conservative but generally sufficient.
-/// * a well-formed predicate of a type argument of the trait being implemented,
+/// * Global (not reference any parameters).
+/// * A `T: Tr` predicate where `Tr` is an always-applicable trait.
+/// * Present on the base impl `impl2`.
+///     * This check is done using the `trait_predicates_eq` function below.
+/// * A well-formed predicate of a type argument of the trait being implemented,
 ///   including the `Self`-type.
+#[instrument(level = "debug", skip(tcx))]
 fn check_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl1_def_id: LocalDefId,
@@ -322,10 +321,7 @@ fn check_predicates<'tcx>(
         .map(|obligation| obligation.predicate)
         .collect()
     };
-    debug!(
-        "check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)",
-        impl1_predicates, impl2_predicates,
-    );
+    debug!(?impl1_predicates, ?impl2_predicates);
 
     // Since impls of always applicable traits don't get to assume anything, we
     // can also assume their supertraits apply.
@@ -373,25 +369,52 @@ fn check_predicates<'tcx>(
     );
 
     for (predicate, span) in impl1_predicates {
-        if !impl2_predicates.contains(&predicate) {
+        if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(predicate, *pred2)) {
             check_specialization_on(tcx, predicate, span)
         }
     }
 }
 
+/// Checks whether two predicates are the same for the purposes of specialization.
+///
+/// This is slightly more complicated than simple syntactic equivalence, since
+/// we want to equate `T: Tr` with `T: ~const Tr` so this can work:
+///
+/// #[rustc_specialization_trait]
+/// trait Specialize { }
+///
+/// impl const Tr for T { }
+/// impl Tr for T { }
+fn trait_predicates_eq<'tcx>(
+    predicate1: ty::Predicate<'tcx>,
+    predicate2: ty::Predicate<'tcx>,
+) -> bool {
+    let predicate_kind_without_constness = |kind: ty::PredicateKind<'tcx>| match kind {
+        ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity }) => {
+            ty::PredicateKind::Trait(ty::TraitPredicate {
+                trait_ref,
+                constness: ty::BoundConstness::NotConst,
+                polarity,
+            })
+        }
+        _ => kind,
+    };
+
+    let pred1_kind_not_const = predicate1.kind().map_bound(predicate_kind_without_constness);
+    let pred2_kind_not_const = predicate2.kind().map_bound(predicate_kind_without_constness);
+
+    pred1_kind_not_const == pred2_kind_not_const
+}
+
+#[instrument(level = "debug", skip(tcx))]
 fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
-    debug!("can_specialize_on(predicate = {:?})", predicate);
     match predicate.kind().skip_binder() {
         // Global predicates are either always true or always false, so we
         // are fine to specialize on.
         _ if predicate.is_global() => (),
         // We allow specializing on explicitly marked traits with no associated
         // items.
-        ty::PredicateKind::Trait(ty::TraitPredicate {
-            trait_ref,
-            constness: ty::BoundConstness::NotConst,
-            polarity: _,
-        }) => {
+        ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => {
             if !matches!(
                 trait_predicate_kind(tcx, predicate),
                 Some(TraitSpecializationKind::Marker)
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
new file mode 100644
index 0000000000000..1eddfbf50f386
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
@@ -0,0 +1,38 @@
+// Tests that a const default trait impl can be specialized by another const
+// trait impl and that the specializing impl will be used during const-eval.
+
+// run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value() -> u32 {
+    T::value()
+}
+
+impl const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+const ZERO: u32 = get_value::<()>();
+
+const FORTY_TWO: u32 = get_value::();
+
+fn main() {
+    assert_eq!(ZERO, 0);
+    assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
new file mode 100644
index 0000000000000..31de6fadeb7a2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
@@ -0,0 +1,37 @@
+// Tests that a const default trait impl can be specialized by a non-const trait
+// impl, but that the specializing impl cannot be used in a const context.
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value() -> u32 {
+    T::value()
+    //~^ ERROR any use of this value will cause an error [const_err]
+    //~| WARNING this was previously accepted
+}
+
+impl const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl Value for FortyTwo {
+    fn value() -> u32 {
+        println!("You can't do that (constly)");
+        42
+    }
+}
+
+const ZERO: u32 = get_value::<()>();
+
+const FORTY_TWO: u32 =
+    get_value::(); // This is the line that causes the error, but it gets reported above
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
new file mode 100644
index 0000000000000..7dfd489ea65c6
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
@@ -0,0 +1,37 @@
+error: any use of this value will cause an error
+  --> $DIR/const-default-non-const-specialized.rs:12:5
+   |
+LL |     T::value()
+   |     ^^^^^^^^^^
+   |     |
+   |     calling non-const function `::value`
+   |     inside `get_value::` at $DIR/const-default-non-const-specialized.rs:12:5
+   |     inside `FORTY_TWO` at $DIR/const-default-non-const-specialized.rs:35:5
+...
+LL | const FORTY_TWO: u32 =
+   | --------------------
+   |
+   = note: `#[deny(const_err)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 
+
+error: aborting due to previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+  --> $DIR/const-default-non-const-specialized.rs:12:5
+   |
+LL |     T::value()
+   |     ^^^^^^^^^^
+   |     |
+   |     calling non-const function `::value`
+   |     inside `get_value::` at $DIR/const-default-non-const-specialized.rs:12:5
+   |     inside `FORTY_TWO` at $DIR/const-default-non-const-specialized.rs:35:5
+...
+LL | const FORTY_TWO: u32 =
+   | --------------------
+   |
+   = note: `#[deny(const_err)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
new file mode 100644
index 0000000000000..c03b0a0d19ca5
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+trait Foo {
+    fn foo();
+}
+
+impl const Foo for u32 {
+    default fn foo() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
new file mode 100644
index 0000000000000..1f7f47879d78b
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -0,0 +1,34 @@
+// Tests that `~const` trait bounds can be used to specialize const trait impls.
+
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+trait Foo {}
+
+impl const Foo for T {}
+
+impl const Foo for T
+where
+    T: ~const Specialize,
+{}
+
+trait Bar {}
+
+impl const Bar for T
+where
+    T: ~const Foo,
+{}
+
+impl const Bar for T
+where
+    T: ~const Foo,
+    T: ~const Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
new file mode 100644
index 0000000000000..f6daba5595a8d
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -0,0 +1,28 @@
+// Tests that `T: ~const Foo` and `T: Foo` are treated as equivalent for the
+// purposes of min_specialization.
+
+// check-pass
+
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+trait Foo {}
+
+trait Bar {}
+
+impl const Bar for T
+where
+    T: ~const Foo,
+{}
+
+impl Bar for T
+where
+    T: Foo,
+    T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
new file mode 100644
index 0000000000000..cf6c292e8a465
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -0,0 +1,34 @@
+// Tests that a non-const default impl can be specialized by a const trait impl,
+// but that the default impl cannot be used in a const context.
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value() -> u32 {
+    T::value()
+}
+
+impl Value for T {
+    default fn value() -> u32 {
+        println!("You can't do that (constly)");
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+const ZERO: u32 = get_value::<()>(); //~ ERROR the trait bound `(): ~const Value` is not satisfied
+
+const FORTY_TWO: u32 = get_value::();
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
new file mode 100644
index 0000000000000..1065009c8910e
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `(): ~const Value` is not satisfied
+  --> $DIR/non-const-default-const-specialized.rs:30:31
+   |
+LL | const ZERO: u32 = get_value::<()>();
+   |                               ^^ the trait `~const Value` is not implemented for `()`
+   |
+note: the trait `Value` is implemented for `()`, but that implementation is not `const`
+  --> $DIR/non-const-default-const-specialized.rs:30:31
+   |
+LL | const ZERO: u32 = get_value::<()>();
+   |                               ^^
+note: required by a bound in `get_value`
+  --> $DIR/non-const-default-const-specialized.rs:11:23
+   |
+LL | const fn get_value() -> u32 {
+   |                       ^^^^^^^^^^^^ required by this bound in `get_value`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.

From 493014f933d5f4655f00adf58d9ad90baccd7a4e Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Tue, 13 Sep 2022 22:18:14 -0500
Subject: [PATCH 437/482] Disallow specializing on const impls with non-const
 impls.

---
 .../src/impl_wf_check/min_specialization.rs   | 35 ++++++++++++++++--
 .../const-default-non-const-specialized.rs    | 17 ++-------
 ...const-default-non-const-specialized.stderr | 37 ++-----------------
 ...87-same-trait-bound-different-constness.rs | 10 ++---
 .../non-const-default-const-specialized.rs    | 12 ++++--
 ...non-const-default-const-specialized.stderr | 20 ----------
 6 files changed, 51 insertions(+), 80 deletions(-)
 delete mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr

diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index f65760b9c98ca..9c7150b79240a 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -69,6 +69,7 @@ use crate::constrained_generic_params as cgp;
 use crate::errors::SubstsOnOverriddenImpl;
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::TyCtxtInferExt;
@@ -117,12 +118,33 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
         };
 
         let span = tcx.def_span(impl1_def_id);
+        check_constness(tcx, impl1_def_id, impl2_node, span);
         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);
     }
 }
 
+/// Check that the specializing impl `impl1` is at least as const as the base
+/// impl `impl2`
+fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
+    if impl2_node.is_from_trait() {
+        // This isn't a specialization
+        return;
+    }
+
+    let impl1_constness = tcx.constness(impl1_def_id.to_def_id());
+    let impl2_constness = tcx.constness(impl2_node.def_id());
+
+    if let hir::Constness::Const = impl2_constness {
+        if let hir::Constness::NotConst = impl1_constness {
+            tcx.sess
+                .struct_span_err(span, "cannot specialize on const impl with non-const impl")
+                .emit();
+        }
+    }
+}
+
 /// Given a specializing impl `impl1`, and the base impl `impl2`, returns two
 /// substitutions `(S1, S2)` that equate their trait references. The returned
 /// types are expressed in terms of the generics of `impl1`.
@@ -277,7 +299,7 @@ fn check_static_lifetimes<'tcx>(
 
 /// Check whether predicates on the specializing impl (`impl1`) are allowed.
 ///
-/// Each predicate `P` must be:
+/// Each predicate `P` must be one of:
 ///
 /// * Global (not reference any parameters).
 /// * A `T: Tr` predicate where `Tr` is an always-applicable trait.
@@ -375,16 +397,19 @@ fn check_predicates<'tcx>(
     }
 }
 
-/// Checks whether two predicates are the same for the purposes of specialization.
+/// Checks if some predicate on the specializing impl (`predicate1`) is the same
+/// as some predicate on the base impl (`predicate2`).
 ///
 /// This is slightly more complicated than simple syntactic equivalence, since
 /// we want to equate `T: Tr` with `T: ~const Tr` so this can work:
 ///
+/// ```ignore (illustrative)
 /// #[rustc_specialization_trait]
 /// trait Specialize { }
 ///
-/// impl const Tr for T { }
-/// impl Tr for T { }
+/// impl Tr for T { }
+/// impl const Tr for T { }
+/// ```
 fn trait_predicates_eq<'tcx>(
     predicate1: ty::Predicate<'tcx>,
     predicate2: ty::Predicate<'tcx>,
@@ -400,6 +425,8 @@ fn trait_predicates_eq<'tcx>(
         _ => kind,
     };
 
+    // We rely on `check_constness` above to ensure that pred1 is const if pred2
+    // is const.
     let pred1_kind_not_const = predicate1.kind().map_bound(predicate_kind_without_constness);
     let pred2_kind_not_const = predicate2.kind().map_bound(predicate_kind_without_constness);
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
index 31de6fadeb7a2..a25329ba388d2 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
@@ -1,5 +1,5 @@
-// Tests that a const default trait impl can be specialized by a non-const trait
-// impl, but that the specializing impl cannot be used in a const context.
+// Tests that a const default trait impl cannot be specialized by a non-const
+// trait impl.
 
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
@@ -8,12 +8,6 @@ trait Value {
     fn value() -> u32;
 }
 
-const fn get_value() -> u32 {
-    T::value()
-    //~^ ERROR any use of this value will cause an error [const_err]
-    //~| WARNING this was previously accepted
-}
-
 impl const Value for T {
     default fn value() -> u32 {
         0
@@ -22,16 +16,11 @@ impl const Value for T {
 
 struct FortyTwo;
 
-impl Value for FortyTwo {
+impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl
     fn value() -> u32 {
         println!("You can't do that (constly)");
         42
     }
 }
 
-const ZERO: u32 = get_value::<()>();
-
-const FORTY_TWO: u32 =
-    get_value::(); // This is the line that causes the error, but it gets reported above
-
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
index 7dfd489ea65c6..b0b76e7eca8ac 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
@@ -1,37 +1,8 @@
-error: any use of this value will cause an error
-  --> $DIR/const-default-non-const-specialized.rs:12:5
+error: cannot specialize on const impl with non-const impl
+  --> $DIR/const-default-non-const-specialized.rs:19:1
    |
-LL |     T::value()
-   |     ^^^^^^^^^^
-   |     |
-   |     calling non-const function `::value`
-   |     inside `get_value::` at $DIR/const-default-non-const-specialized.rs:12:5
-   |     inside `FORTY_TWO` at $DIR/const-default-non-const-specialized.rs:35:5
-...
-LL | const FORTY_TWO: u32 =
-   | --------------------
-   |
-   = note: `#[deny(const_err)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 
+LL | impl Value for FortyTwo {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-Future incompatibility report: Future breakage diagnostic:
-error: any use of this value will cause an error
-  --> $DIR/const-default-non-const-specialized.rs:12:5
-   |
-LL |     T::value()
-   |     ^^^^^^^^^^
-   |     |
-   |     calling non-const function `::value`
-   |     inside `get_value::` at $DIR/const-default-non-const-specialized.rs:12:5
-   |     inside `FORTY_TWO` at $DIR/const-default-non-const-specialized.rs:35:5
-...
-LL | const FORTY_TWO: u32 =
-   | --------------------
-   |
-   = note: `#[deny(const_err)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 
-
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
index f6daba5595a8d..da6df064d4fd1 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -1,4 +1,4 @@
-// Tests that `T: ~const Foo` and `T: Foo` are treated as equivalent for the
+// Tests that `T: Foo` and `T: ~const Foo` are treated as equivalent for the
 // purposes of min_specialization.
 
 // check-pass
@@ -14,14 +14,14 @@ trait Foo {}
 
 trait Bar {}
 
-impl const Bar for T
+impl Bar for T
 where
-    T: ~const Foo,
+    T: Foo,
 {}
 
-impl Bar for T
+impl const Bar for T
 where
-    T: Foo,
+    T: ~const Foo,
     T: Specialize,
 {}
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
index cf6c292e8a465..84614f5459d63 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -1,6 +1,8 @@
 // Tests that a non-const default impl can be specialized by a const trait impl,
 // but that the default impl cannot be used in a const context.
 
+// run-pass
+
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
 
@@ -27,8 +29,10 @@ impl const Value for FortyTwo {
     }
 }
 
-const ZERO: u32 = get_value::<()>(); //~ ERROR the trait bound `(): ~const Value` is not satisfied
-
-const FORTY_TWO: u32 = get_value::();
+fn main() {
+    let zero = get_value::<()>();
+    assert_eq!(zero, 0);
 
-fn main() {}
+    const FORTY_TWO: u32 = get_value::();
+    assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
deleted file mode 100644
index 1065009c8910e..0000000000000
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0277]: the trait bound `(): ~const Value` is not satisfied
-  --> $DIR/non-const-default-const-specialized.rs:30:31
-   |
-LL | const ZERO: u32 = get_value::<()>();
-   |                               ^^ the trait `~const Value` is not implemented for `()`
-   |
-note: the trait `Value` is implemented for `()`, but that implementation is not `const`
-  --> $DIR/non-const-default-const-specialized.rs:30:31
-   |
-LL | const ZERO: u32 = get_value::<()>();
-   |                               ^^
-note: required by a bound in `get_value`
-  --> $DIR/non-const-default-const-specialized.rs:11:23
-   |
-LL | const fn get_value() -> u32 {
-   |                       ^^^^^^^^^^^^ required by this bound in `get_value`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.

From 6795da63a3e236c718dd161d071949405b329f0e Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Sat, 5 Nov 2022 23:12:57 -0500
Subject: [PATCH 438/482] Add #[const_trait] where needed in tests.

---
 .../specialization/const-default-const-specialized.rs          | 1 +
 .../specialization/const-default-non-const-specialized.rs      | 1 +
 .../specialization/const-default-non-const-specialized.stderr  | 2 +-
 .../specialization/default-keyword.rs                          | 1 +
 .../specialization/issue-95186-specialize-on-tilde-const.rs    | 3 +++
 .../issue-95187-same-trait-bound-different-constness.rs        | 2 ++
 .../specialization/non-const-default-const-specialized.rs      | 1 +
 7 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
index 1eddfbf50f386..9ddea427cfd80 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
@@ -6,6 +6,7 @@
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
 
+#[const_trait]
 trait Value {
     fn value() -> u32;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
index a25329ba388d2..79dd4950af32a 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
@@ -4,6 +4,7 @@
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
 
+#[const_trait]
 trait Value {
     fn value() -> u32;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
index b0b76e7eca8ac..5232a8609cd80 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
@@ -1,5 +1,5 @@
 error: cannot specialize on const impl with non-const impl
-  --> $DIR/const-default-non-const-specialized.rs:19:1
+  --> $DIR/const-default-non-const-specialized.rs:20:1
    |
 LL | impl Value for FortyTwo {
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
index c03b0a0d19ca5..2aac0a2b4d111 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
@@ -3,6 +3,7 @@
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
 
+#[const_trait]
 trait Foo {
     fn foo();
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
index 1f7f47879d78b..9c2c2cf1610a2 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -6,9 +6,11 @@
 #![feature(rustc_attrs)]
 #![feature(min_specialization)]
 
+#[const_trait]
 #[rustc_specialization_trait]
 trait Specialize {}
 
+#[const_trait]
 trait Foo {}
 
 impl const Foo for T {}
@@ -18,6 +20,7 @@ where
     T: ~const Specialize,
 {}
 
+#[const_trait]
 trait Bar {}
 
 impl const Bar for T
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
index da6df064d4fd1..3370aebf0634a 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -10,8 +10,10 @@
 #[rustc_specialization_trait]
 trait Specialize {}
 
+#[const_trait]
 trait Foo {}
 
+#[const_trait]
 trait Bar {}
 
 impl Bar for T
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
index 84614f5459d63..35aa52fbd4ed2 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -6,6 +6,7 @@
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
 
+#[const_trait]
 trait Value {
     fn value() -> u32;
 }

From e22bfd5aa66a51e9e97fa444d8d0cbd6b5e82844 Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Sun, 6 Nov 2022 01:07:06 -0500
Subject: [PATCH 439/482] Require `~const` qualifier on trait bounds in
 specializing impls if present in base impl.

---
 .../src/impl_wf_check/min_specialization.rs   | 59 ++++++++++++++-----
 ...fault-bound-non-const-specialized-bound.rs | 46 +++++++++++++++
 ...t-bound-non-const-specialized-bound.stderr | 18 ++++++
 ...efault-impl-non-const-specialized-impl.rs} |  3 +-
 ...lt-impl-non-const-specialized-impl.stderr} |  2 +-
 ...87-same-trait-bound-different-constness.rs | 19 +++++-
 .../specializing-constness.rs                 |  4 +-
 .../specializing-constness.stderr             | 10 +++-
 8 files changed, 137 insertions(+), 24 deletions(-)
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
 rename src/test/ui/rfc-2632-const-trait-impl/specialization/{const-default-non-const-specialized.rs => const-default-impl-non-const-specialized-impl.rs} (81%)
 rename src/test/ui/rfc-2632-const-trait-impl/specialization/{const-default-non-const-specialized.stderr => const-default-impl-non-const-specialized-impl.stderr} (71%)

diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 9c7150b79240a..f3cb558ef7093 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -391,7 +391,7 @@ fn check_predicates<'tcx>(
     );
 
     for (predicate, span) in impl1_predicates {
-        if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(predicate, *pred2)) {
+        if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(tcx, predicate, *pred2, span)) {
             check_specialization_on(tcx, predicate, span)
         }
     }
@@ -400,8 +400,8 @@ fn check_predicates<'tcx>(
 /// Checks if some predicate on the specializing impl (`predicate1`) is the same
 /// as some predicate on the base impl (`predicate2`).
 ///
-/// This is slightly more complicated than simple syntactic equivalence, since
-/// we want to equate `T: Tr` with `T: ~const Tr` so this can work:
+/// This basically just checks syntactic equivalence, but is a little more
+/// forgiving since we want to equate `T: Tr` with `T: ~const Tr` so this can work:
 ///
 /// ```ignore (illustrative)
 /// #[rustc_specialization_trait]
@@ -410,27 +410,54 @@ fn check_predicates<'tcx>(
 /// impl Tr for T { }
 /// impl const Tr for T { }
 /// ```
+///
+/// However, we *don't* want to allow the reverse, i.e., when the bound on the
+/// specializing impl is not as const as the bound on the base impl:
+///
+/// ```ignore (illustrative)
+/// impl const Tr for T { }
+/// impl const Tr for T { } // should be T: ~const Bound
+/// ```
+///
+/// So we make that check in this function and try to raise a helpful error message.
 fn trait_predicates_eq<'tcx>(
+    tcx: TyCtxt<'tcx>,
     predicate1: ty::Predicate<'tcx>,
     predicate2: ty::Predicate<'tcx>,
+    span: Span,
 ) -> bool {
-    let predicate_kind_without_constness = |kind: ty::PredicateKind<'tcx>| match kind {
-        ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity }) => {
-            ty::PredicateKind::Trait(ty::TraitPredicate {
-                trait_ref,
-                constness: ty::BoundConstness::NotConst,
-                polarity,
-            })
+    let pred1_kind = predicate1.kind().no_bound_vars();
+    let pred2_kind = predicate2.kind().no_bound_vars();
+    let (trait_pred1, trait_pred2) = match (pred1_kind, pred2_kind) {
+        (Some(ty::PredicateKind::Trait(pred1)), Some(ty::PredicateKind::Trait(pred2))) => {
+            (pred1, pred2)
         }
-        _ => kind,
+        // Just use plain syntactic equivalence if either of the predicates aren't
+        // trait predicates or have bound vars.
+        _ => return pred1_kind == pred2_kind,
+    };
+
+    let predicates_equal_modulo_constness = {
+        let pred1_unconsted =
+            ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred1 };
+        let pred2_unconsted =
+            ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred2 };
+        pred1_unconsted == pred2_unconsted
     };
 
-    // We rely on `check_constness` above to ensure that pred1 is const if pred2
-    // is const.
-    let pred1_kind_not_const = predicate1.kind().map_bound(predicate_kind_without_constness);
-    let pred2_kind_not_const = predicate2.kind().map_bound(predicate_kind_without_constness);
+    if !predicates_equal_modulo_constness {
+        return false;
+    }
+
+    // Check that the predicate on the specializing impl is at least as const as
+    // the one on the base.
+    if trait_pred2.constness == ty::BoundConstness::ConstIfConst
+        && trait_pred1.constness == ty::BoundConstness::NotConst
+    {
+        tcx.sess.struct_span_err(span, "missing `~const` qualifier").emit();
+    }
 
-    pred1_kind_not_const == pred2_kind_not_const
+    true
 }
 
 #[instrument(level = "debug", skip(tcx))]
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
new file mode 100644
index 0000000000000..3ac909924864d
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -0,0 +1,46 @@
+// Tests that trait bounds on specializing trait impls must be `~const` if the
+// same bound is present on the default impl and is `~const` there.
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {}
+
+// bgr360: I was only able to exercise the code path that raises the
+// "missing ~const qualifier" error by making this base impl non-const, even
+// though that doesn't really make sense to do. As seen below, if the base impl
+// is made const, rustc fails earlier with an overlapping impl failure.
+impl Bar for T
+where
+    T: ~const Foo,
+{}
+
+impl Bar for T
+where
+    T: Foo, //~ ERROR missing `~const` qualifier
+    T: Specialize,
+{}
+
+#[const_trait]
+trait Baz {}
+
+impl const Baz for T
+where
+    T: ~const Foo,
+{}
+
+impl const Baz for T //~ ERROR conflicting implementations of trait `Baz`
+where
+    T: Foo,
+    T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
new file mode 100644
index 0000000000000..583c4cec77fb6
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -0,0 +1,18 @@
+error: missing `~const` qualifier
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
+   |
+LL |     T: Foo,
+   |        ^^^
+
+error[E0119]: conflicting implementations of trait `Baz`
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1
+   |
+LL | impl const Baz for T
+   | ----------------------- first implementation here
+...
+LL | impl const Baz for T
+   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
similarity index 81%
rename from src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
rename to src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
index 79dd4950af32a..a3bb9b3f93eda 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -1,5 +1,4 @@
-// Tests that a const default trait impl cannot be specialized by a non-const
-// trait impl.
+// Tests that specializing trait impls must be at least as const as the default impl.
 
 #![feature(const_trait_impl)]
 #![feature(min_specialization)]
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
similarity index 71%
rename from src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
rename to src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
index 5232a8609cd80..24766804708a3 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-non-const-specialized.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
@@ -1,5 +1,5 @@
 error: cannot specialize on const impl with non-const impl
-  --> $DIR/const-default-non-const-specialized.rs:20:1
+  --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
    |
 LL | impl Value for FortyTwo {
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
index 3370aebf0634a..1e6b1c6513b39 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -1,5 +1,6 @@
-// Tests that `T: Foo` and `T: ~const Foo` are treated as equivalent for the
-// purposes of min_specialization.
+// Tests that `T: ~const Foo` in a specializing impl is treated as equivalent to
+// `T: Foo` in the default impl for the purposes of specialization (i.e., it
+// does not think that the user is attempting to specialize on trait `Foo`).
 
 // check-pass
 
@@ -27,4 +28,18 @@ where
     T: Specialize,
 {}
 
+#[const_trait]
+trait Baz {}
+
+impl const Baz for T
+where
+    T: Foo,
+{}
+
+impl const Baz for T
+where
+    T: ~const Foo,
+    T: Specialize,
+{}
+
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
index ff0cd489d4744..9ab170f092006 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -17,7 +17,9 @@ impl const A for T {
     }
 }
 
-impl A for T { //~ ERROR: cannot specialize
+impl A for T {
+//~^ ERROR: cannot specialize
+//~| ERROR: missing `~const` qualifier
     fn a() -> u32 {
         3
     }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
index 3296c109c4e73..281ba82d64429 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
@@ -1,8 +1,14 @@
-error: cannot specialize on trait `Default`
+error: cannot specialize on const impl with non-const impl
+  --> $DIR/specializing-constness.rs:20:1
+   |
+LL | impl A for T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing `~const` qualifier
   --> $DIR/specializing-constness.rs:20:9
    |
 LL | impl A for T {
    |         ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 

From 6418271d3f3ffc4faab8e8357b7b57cf29d7883a Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Thu, 10 Nov 2022 12:56:09 -0600
Subject: [PATCH 440/482] Apply PR feedback.

---
 .../src/impl_wf_check/min_specialization.rs   | 19 +++++++++----------
 ...t-bound-non-const-specialized-bound.stderr |  2 +-
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index f3cb558ef7093..55cca0cd2d7b5 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -426,15 +426,13 @@ fn trait_predicates_eq<'tcx>(
     predicate2: ty::Predicate<'tcx>,
     span: Span,
 ) -> bool {
-    let pred1_kind = predicate1.kind().no_bound_vars();
-    let pred2_kind = predicate2.kind().no_bound_vars();
+    let pred1_kind = predicate1.kind().skip_binder();
+    let pred2_kind = predicate2.kind().skip_binder();
     let (trait_pred1, trait_pred2) = match (pred1_kind, pred2_kind) {
-        (Some(ty::PredicateKind::Trait(pred1)), Some(ty::PredicateKind::Trait(pred2))) => {
-            (pred1, pred2)
-        }
+        (ty::PredicateKind::Trait(pred1), ty::PredicateKind::Trait(pred2)) => (pred1, pred2),
         // Just use plain syntactic equivalence if either of the predicates aren't
         // trait predicates or have bound vars.
-        _ => return pred1_kind == pred2_kind,
+        _ => return predicate1 == predicate2,
     };
 
     let predicates_equal_modulo_constness = {
@@ -451,10 +449,11 @@ fn trait_predicates_eq<'tcx>(
 
     // Check that the predicate on the specializing impl is at least as const as
     // the one on the base.
-    if trait_pred2.constness == ty::BoundConstness::ConstIfConst
-        && trait_pred1.constness == ty::BoundConstness::NotConst
-    {
-        tcx.sess.struct_span_err(span, "missing `~const` qualifier").emit();
+    match (trait_pred2.constness, trait_pred1.constness) {
+        (ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
+            tcx.sess.struct_span_err(span, "missing `~const` qualifier for specialization").emit();
+        }
+        _ => {}
     }
 
     true
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
index 583c4cec77fb6..4aea1979421c3 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -1,4 +1,4 @@
-error: missing `~const` qualifier
+error: missing `~const` qualifier for specialization
   --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
    |
 LL |     T: Foo,

From 0fb056188f8d13994bbd187d79e4ac08bfbb9c5e Mon Sep 17 00:00:00 2001
From: Ben Reeves 
Date: Thu, 10 Nov 2022 22:14:08 -0600
Subject: [PATCH 441/482] Oops, bless this test.

---
 .../ui/rfc-2632-const-trait-impl/specializing-constness.stderr  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
index 281ba82d64429..843fc6ce84d45 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
@@ -4,7 +4,7 @@ error: cannot specialize on const impl with non-const impl
 LL | impl A for T {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: missing `~const` qualifier
+error: missing `~const` qualifier for specialization
   --> $DIR/specializing-constness.rs:20:9
    |
 LL | impl A for T {

From 025118a5bdd23476ca0435792158cdbd5312e8bf Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 29 Mar 2021 17:32:20 +0200
Subject: [PATCH 442/482] make `Sized` coinductive

---
 .../src/traits/select/mod.rs                  |  5 +++-
 src/test/ui/sized/coinductive-1.rs            | 14 ++++++++++
 src/test/ui/sized/coinductive-2.rs            | 28 +++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/sized/coinductive-1.rs
 create mode 100644 src/test/ui/sized/coinductive-2.rs

diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index de158a15d54b8..49bb3d03621f3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -959,7 +959,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
         let result = match predicate.kind().skip_binder() {
-            ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()),
+            ty::PredicateKind::Trait(ref data) => {
+                self.tcx().trait_is_auto(data.def_id())
+                    || self.tcx().lang_items().sized_trait() == Some(data.def_id())
+            }
             ty::PredicateKind::WellFormed(_) => true,
             _ => false,
         };
diff --git a/src/test/ui/sized/coinductive-1.rs b/src/test/ui/sized/coinductive-1.rs
new file mode 100644
index 0000000000000..7bcd0f1fdaf6d
--- /dev/null
+++ b/src/test/ui/sized/coinductive-1.rs
@@ -0,0 +1,14 @@
+// check-pass
+struct Node>(C::Assoc);
+
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for Vec<()> {
+    type Assoc = Vec;
+}
+
+fn main() {
+    let _ = Node::>(Vec::new());
+}
diff --git a/src/test/ui/sized/coinductive-2.rs b/src/test/ui/sized/coinductive-2.rs
new file mode 100644
index 0000000000000..212274d2e4b6c
--- /dev/null
+++ b/src/test/ui/sized/coinductive-2.rs
@@ -0,0 +1,28 @@
+// run-pass
+struct Node> {
+    _children: C::Collection,
+}
+
+trait CollectionFactory {
+    type Collection;
+}
+
+impl CollectionFactory for Vec<()> {
+    type Collection = Vec;
+}
+
+trait Collection: Sized {
+    fn push(&mut self, v: T);
+}
+
+impl Collection for Vec {
+    fn push(&mut self, v: T) {
+        self.push(v)
+    }
+}
+
+fn main() {
+    let _ = Node::> {
+        _children: Vec::new(),
+    };
+}

From 9b7f53483002b6b3548c4f2444997cbee8d28d3d Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Tue, 27 Apr 2021 14:24:19 +0200
Subject: [PATCH 443/482] add some more tests

---
 src/test/ui/sized/recursive-type-1.rs     | 10 ++++++++++
 src/test/ui/sized/recursive-type-2.rs     | 13 +++++++++++++
 src/test/ui/sized/recursive-type-2.stderr | 12 ++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 src/test/ui/sized/recursive-type-1.rs
 create mode 100644 src/test/ui/sized/recursive-type-2.rs
 create mode 100644 src/test/ui/sized/recursive-type-2.stderr

diff --git a/src/test/ui/sized/recursive-type-1.rs b/src/test/ui/sized/recursive-type-1.rs
new file mode 100644
index 0000000000000..cd6805967e524
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-1.rs
@@ -0,0 +1,10 @@
+// check-pass
+trait A { type Assoc; }
+
+impl A for () {
+    // FIXME: it would be nice for this to at least cause a warning.
+    type Assoc = Foo<()>;
+}
+struct Foo(T::Assoc);
+
+fn main() {}
diff --git a/src/test/ui/sized/recursive-type-2.rs b/src/test/ui/sized/recursive-type-2.rs
new file mode 100644
index 0000000000000..7d95417a6ffd9
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-2.rs
@@ -0,0 +1,13 @@
+// build-fail
+//~^ ERROR cycle detected when computing layout of `Foo<()>`
+
+trait A { type Assoc: ?Sized; }
+
+impl A for () {
+    type Assoc = Foo<()>;
+}
+struct Foo(T::Assoc);
+
+fn main() {
+    let x: Foo<()>;
+}
diff --git a/src/test/ui/sized/recursive-type-2.stderr b/src/test/ui/sized/recursive-type-2.stderr
new file mode 100644
index 0000000000000..2102c934da36f
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-2.stderr
@@ -0,0 +1,12 @@
+error[E0391]: cycle detected when computing layout of `Foo<()>`
+   |
+   = note: ...which again requires computing layout of `Foo<()>`, completing the cycle
+note: cycle used when optimizing MIR for `main`
+  --> $DIR/recursive-type-2.rs:11:1
+   |
+LL | fn main() {
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.

From 13b4e85c624db6eae9ca60ef76e9dcc121d96692 Mon Sep 17 00:00:00 2001
From: Michael Goulet 
Date: Wed, 10 Aug 2022 16:47:26 +0000
Subject: [PATCH 444/482] bless tests

---
 .../generic-associated-types/bugs/issue-80626.rs  |  7 ++-----
 .../bugs/issue-80626.stderr                       | 15 ---------------
 .../ui/generic-associated-types/issue-87750.rs    |  8 ++++++--
 .../generic-associated-types/issue-87750.stderr   |  9 ---------
 .../projection-bound-cycle-generic.rs             |  2 +-
 .../projection-bound-cycle-generic.stderr         | 14 ++++----------
 .../projection-bound-cycle.rs                     |  2 +-
 .../projection-bound-cycle.stderr                 | 14 ++++----------
 src/test/ui/sized/recursive-type-2.stderr         |  3 ++-
 src/test/ui/traits/issue-82830.rs                 |  4 +++-
 src/test/ui/traits/issue-82830.stderr             | 15 ---------------
 11 files changed, 23 insertions(+), 70 deletions(-)
 delete mode 100644 src/test/ui/generic-associated-types/bugs/issue-80626.stderr
 delete mode 100644 src/test/ui/generic-associated-types/issue-87750.stderr
 delete mode 100644 src/test/ui/traits/issue-82830.stderr

diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
index f6aa6b36e13dc..d6e18010f3b27 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -1,7 +1,4 @@
-// check-fail
-// known-bug: #80626
-
-// This should pass, but it requires `Sized` to be coinductive.
+// check-pass
 
 trait Allocator {
     type Allocated;
@@ -9,7 +6,7 @@ trait Allocator {
 
 enum LinkedList {
     Head,
-    Next(A::Allocated)
+    Next(A::Allocated),
 }
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
deleted file mode 100644
index 9a0f332ed4736..0000000000000
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0275]: overflow evaluating the requirement `LinkedList: Sized`
-  --> $DIR/issue-80626.rs:12:10
-   |
-LL |     Next(A::Allocated)
-   |          ^^^^^^^^^^^^^^^^^^
-   |
-note: required by a bound in `Allocator::Allocated`
-  --> $DIR/issue-80626.rs:7:20
-   |
-LL |     type Allocated;
-   |                    ^ required by this bound in `Allocator::Allocated`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/issue-87750.rs b/src/test/ui/generic-associated-types/issue-87750.rs
index 0a11a0f3ae0e4..b35657989efb9 100644
--- a/src/test/ui/generic-associated-types/issue-87750.rs
+++ b/src/test/ui/generic-associated-types/issue-87750.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 trait PointerFamily {
     type Pointer;
 }
@@ -10,11 +12,13 @@ impl PointerFamily for RcFamily {
 }
 
 #[allow(dead_code)]
-enum Node where P::Pointer>: Sized {
+enum Node
+where
+    P::Pointer>: Sized,
+{
     Cons(P::Pointer>),
 }
 
 fn main() {
     let _list: ::Pointer>;
-    //~^ ERROR overflow evaluating the requirement `Node: Sized`
 }
diff --git a/src/test/ui/generic-associated-types/issue-87750.stderr b/src/test/ui/generic-associated-types/issue-87750.stderr
deleted file mode 100644
index b358ca273ca79..0000000000000
--- a/src/test/ui/generic-associated-types/issue-87750.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0275]: overflow evaluating the requirement `Node: Sized`
-  --> $DIR/issue-87750.rs:18:16
-   |
-LL |     let _list: ::Pointer>;
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
index 58d57df63c1bd..ecf6f69c9fa7e 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
@@ -21,6 +21,7 @@ impl Foo for Number {
     // ```
     // which it is :)
     type Item = [T] where [T]: Sized;
+    //~^ ERROR overflow evaluating the requirement ` as Foo>::Item == _`
 }
 
 struct OnlySized where T: Sized { f: T }
@@ -40,7 +41,6 @@ impl Bar for T where T: Foo {
     // can use the bound on `Foo::Item` for this, but that requires
     // `wf(::Item)`, which is an invalid cycle.
     type Assoc = OnlySized<::Item>;
-    //~^ ERROR overflow evaluating the requirement `::Item: Sized`
 }
 
 fn foo() {
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
index 27c1a82994a53..aae9a56bb6128 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
@@ -1,14 +1,8 @@
-error[E0275]: overflow evaluating the requirement `::Item: Sized`
-  --> $DIR/projection-bound-cycle-generic.rs:42:18
+error[E0275]: overflow evaluating the requirement ` as Foo>::Item == _`
+  --> $DIR/projection-bound-cycle-generic.rs:23:5
    |
-LL |     type Assoc = OnlySized<::Item>;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by a bound in `OnlySized`
-  --> $DIR/projection-bound-cycle-generic.rs:26:18
-   |
-LL | struct OnlySized where T: Sized { f: T }
-   |                  ^ required by this bound in `OnlySized`
+LL |     type Item = [T] where [T]: Sized;
+   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.rs b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
index 4cad1f61319ef..b51ae7ef20186 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
@@ -24,6 +24,7 @@ impl Foo for Number {
     // ```
     // which it is :)
     type Item = str where str: Sized;
+    //~^ ERROR overflow evaluating the requirement `::Item == _`
 }
 
 struct OnlySized where T: Sized { f: T }
@@ -43,7 +44,6 @@ impl Bar for T where T: Foo {
     // can use the bound on `Foo::Item` for this, but that requires
     // `wf(::Item)`, which is an invalid cycle.
     type Assoc = OnlySized<::Item>;
-    //~^ ERROR overflow evaluating the requirement `::Item: Sized`
 }
 
 fn foo() {
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
index a46518c80da76..b1b8afeecd02f 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -1,14 +1,8 @@
-error[E0275]: overflow evaluating the requirement `::Item: Sized`
-  --> $DIR/projection-bound-cycle.rs:45:18
+error[E0275]: overflow evaluating the requirement `::Item == _`
+  --> $DIR/projection-bound-cycle.rs:26:5
    |
-LL |     type Assoc = OnlySized<::Item>;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by a bound in `OnlySized`
-  --> $DIR/projection-bound-cycle.rs:29:18
-   |
-LL | struct OnlySized where T: Sized { f: T }
-   |                  ^ required by this bound in `OnlySized`
+LL |     type Item = str where str: Sized;
+   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/sized/recursive-type-2.stderr b/src/test/ui/sized/recursive-type-2.stderr
index 2102c934da36f..d0e6e9db07e9b 100644
--- a/src/test/ui/sized/recursive-type-2.stderr
+++ b/src/test/ui/sized/recursive-type-2.stderr
@@ -1,7 +1,8 @@
 error[E0391]: cycle detected when computing layout of `Foo<()>`
    |
+   = note: ...which requires computing layout of `<() as A>::Assoc`...
    = note: ...which again requires computing layout of `Foo<()>`, completing the cycle
-note: cycle used when optimizing MIR for `main`
+note: cycle used when elaborating drops for `main`
   --> $DIR/recursive-type-2.rs:11:1
    |
 LL | fn main() {
diff --git a/src/test/ui/traits/issue-82830.rs b/src/test/ui/traits/issue-82830.rs
index c8289b2e30b4d..37bae2e90a595 100644
--- a/src/test/ui/traits/issue-82830.rs
+++ b/src/test/ui/traits/issue-82830.rs
@@ -1,10 +1,12 @@
+// check-pass
+
 trait A {
     type B;
 }
 
 type MaybeBox = >>::B;
 struct P {
-    t: MaybeBox

, //~ ERROR: overflow evaluating the requirement `P: Sized` + t: MaybeBox

, } impl A for P { diff --git a/src/test/ui/traits/issue-82830.stderr b/src/test/ui/traits/issue-82830.stderr deleted file mode 100644 index 6a597a402156f..0000000000000 --- a/src/test/ui/traits/issue-82830.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0275]: overflow evaluating the requirement `P: Sized` - --> $DIR/issue-82830.rs:7:8 - | -LL | t: MaybeBox

, - | ^^^^^^^^^^^ - | -note: required for `P` to implement `A>` - --> $DIR/issue-82830.rs:10:12 - | -LL | impl A for P { - | ^^^^^^^ ^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0275`. From 2bc12120f9f6347bf2f129a70812dfc29ed27cad Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 10 Nov 2022 21:29:20 +0000 Subject: [PATCH 445/482] More nits --- compiler/rustc_middle/src/ty/mod.rs | 4 ++++ .../rustc_trait_selection/src/traits/select/mod.rs | 5 +---- src/test/ui/sized/coinductive-1-gat.rs | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/sized/coinductive-1-gat.rs diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b509ae6dd3b85..18eb06b83c9df 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2506,6 +2506,10 @@ impl<'tcx> TyCtxt<'tcx> { self.trait_def(trait_def_id).has_auto_impl } + pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { + self.trait_is_auto(trait_def_id) || self.lang_items().sized_trait() == Some(trait_def_id) + } + /// Returns layout of a generator. Layout might be unavailable if the /// generator is tainted by errors. pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 49bb3d03621f3..a12f67125bbc0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -959,10 +959,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool { let result = match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ref data) => { - self.tcx().trait_is_auto(data.def_id()) - || self.tcx().lang_items().sized_trait() == Some(data.def_id()) - } + ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_coinductive(data.def_id()), ty::PredicateKind::WellFormed(_) => true, _ => false, }; diff --git a/src/test/ui/sized/coinductive-1-gat.rs b/src/test/ui/sized/coinductive-1-gat.rs new file mode 100644 index 0000000000000..cdf70920f0095 --- /dev/null +++ b/src/test/ui/sized/coinductive-1-gat.rs @@ -0,0 +1,14 @@ +// check-pass +struct Node(C::Assoc::); + +trait Trait { + type Assoc; +} + +impl Trait for Vec<()> { + type Assoc = Vec; +} + +fn main() { + let _ = Node::>(Vec::new()); +} From 4f4780f01f0c429644f8f61dd3c671528de61150 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 23 Sep 2022 17:06:28 -0700 Subject: [PATCH 446/482] Implement the `+whole-archive` modifier for `wasm-ld` This implements the `Linker::{link_whole_staticlib,link_whole_rlib}` methods for the `WasmLd` linker used on wasm targets. Previously these methods were noops since I think historically `wasm-ld` did not have support for `--whole-archive` but nowadays it does, so the flags are passed through. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index c49b19bdf0094..7f0c2861f7e29 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1260,11 +1260,11 @@ impl<'a> Linker for WasmLd<'a> { } fn link_whole_staticlib(&mut self, lib: &str, _verbatim: bool, _search_path: &[PathBuf]) { - self.cmd.arg("-l").arg(lib); + self.cmd.arg("--whole-archive").arg("-l").arg(lib).arg("--no-whole-archive"); } fn link_whole_rlib(&mut self, lib: &Path) { - self.cmd.arg(lib); + self.cmd.arg("--whole-archive").arg(lib).arg("--no-whole-archive"); } fn gc_sections(&mut self, _keep_metadata: bool) { From 67a4a3969487319d37991d62e8f2927042490ae2 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 24 Oct 2022 16:48:28 +0800 Subject: [PATCH 447/482] fix #103435, unused lint won't produce invalid code --- compiler/rustc_lint/src/unused.rs | 44 +++++++++++++------ .../lint/issue-103435-extra-parentheses.fixed | 16 +++++++ .../ui/lint/issue-103435-extra-parentheses.rs | 16 +++++++ .../issue-103435-extra-parentheses.stderr | 43 ++++++++++++++++++ 4 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/lint/issue-103435-extra-parentheses.fixed create mode 100644 src/test/ui/lint/issue-103435-extra-parentheses.rs create mode 100644 src/test/ui/lint/issue-103435-extra-parentheses.stderr diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 045d76cac62b8..f9458ddd35032 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -581,10 +581,26 @@ trait UnusedDelimLint { lint.set_arg("delim", Self::DELIM_STR); lint.set_arg("item", msg); if let Some((lo, hi)) = spans { - let replacement = vec![ - (lo, if keep_space.0 { " ".into() } else { "".into() }), - (hi, if keep_space.1 { " ".into() } else { "".into() }), - ]; + let sm = cx.sess().source_map(); + let lo_replace = + if keep_space.0 && + let Ok(snip) = sm.span_to_snippet(lo.with_lo(lo.lo() - BytePos(1))) && + !snip.starts_with(" ") { + " ".to_string() + } else { + "".to_string() + }; + + let hi_replace = + if keep_space.1 && + let Ok(snip) = sm.span_to_snippet(sm.next_point(hi)) && + !snip.starts_with(" ") { + " ".to_string() + } else { + "".to_string() + }; + + let replacement = vec![(lo, lo_replace), (hi, hi_replace)]; lint.multipart_suggestion( fluent::suggestion, replacement, @@ -781,6 +797,7 @@ impl UnusedParens { value: &ast::Pat, avoid_or: bool, avoid_mut: bool, + keep_space: (bool, bool), ) { use ast::{BindingAnnotation, PatKind}; @@ -805,7 +822,7 @@ impl UnusedParens { } else { None }; - self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false)); + self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space); } } } @@ -814,7 +831,7 @@ impl EarlyLintPass for UnusedParens { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { match e.kind { ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => { - self.check_unused_parens_pat(cx, pat, false, false); + self.check_unused_parens_pat(cx, pat, false, false, (true, true)); } // We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already // handle a hard error for them during AST lowering in `lower_expr_mut`, but we still @@ -858,6 +875,7 @@ impl EarlyLintPass for UnusedParens { fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { use ast::{Mutability, PatKind::*}; + let keep_space = (false, false); match &p.kind { // Do not lint on `(..)` as that will result in the other arms being useless. Paren(_) @@ -865,33 +883,33 @@ impl EarlyLintPass for UnusedParens { | Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {}, // These are list-like patterns; parens can always be removed. TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps { - self.check_unused_parens_pat(cx, p, false, false); + self.check_unused_parens_pat(cx, p, false, false, keep_space); }, Struct(_, _, fps, _) => for f in fps { - self.check_unused_parens_pat(cx, &f.pat, false, false); + self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space); }, // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106. - Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false), + Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space), // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342. // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106. - Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not), + Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space), } } fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { if let StmtKind::Local(ref local) = s.kind { - self.check_unused_parens_pat(cx, &local.pat, true, false); + self.check_unused_parens_pat(cx, &local.pat, true, false, (false, false)); } ::check_stmt(self, cx, s) } fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) { - self.check_unused_parens_pat(cx, ¶m.pat, true, false); + self.check_unused_parens_pat(cx, ¶m.pat, true, false, (false, false)); } fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) { - self.check_unused_parens_pat(cx, &arm.pat, false, false); + self.check_unused_parens_pat(cx, &arm.pat, false, false, (false, false)); } fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) { diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.fixed b/src/test/ui/lint/issue-103435-extra-parentheses.fixed new file mode 100644 index 0000000000000..dbbcaa441ddd6 --- /dev/null +++ b/src/test/ui/lint/issue-103435-extra-parentheses.fixed @@ -0,0 +1,16 @@ +// run-rustfix +#![deny(unused_parens)] + +fn main() { + if let Some(_) = Some(1) {} + //~^ ERROR unnecessary parentheses around pattern + + for _x in 1..10 {} + //~^ ERROR unnecessary parentheses around pattern + + if 2 == 1 {} + //~^ ERROR unnecessary parentheses around `if` condition + + // FIXME, auto recover from this one? + // for(_x in 1..10) {} +} diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.rs b/src/test/ui/lint/issue-103435-extra-parentheses.rs new file mode 100644 index 0000000000000..f5c2a6664ede4 --- /dev/null +++ b/src/test/ui/lint/issue-103435-extra-parentheses.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![deny(unused_parens)] + +fn main() { + if let(Some(_))= Some(1) {} + //~^ ERROR unnecessary parentheses around pattern + + for(_x)in 1..10 {} + //~^ ERROR unnecessary parentheses around pattern + + if(2 == 1){} + //~^ ERROR unnecessary parentheses around `if` condition + + // FIXME, auto recover from this one? + // for(_x in 1..10) {} +} diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.stderr b/src/test/ui/lint/issue-103435-extra-parentheses.stderr new file mode 100644 index 0000000000000..a3f2fbc51ab29 --- /dev/null +++ b/src/test/ui/lint/issue-103435-extra-parentheses.stderr @@ -0,0 +1,43 @@ +error: unnecessary parentheses around pattern + --> $DIR/issue-103435-extra-parentheses.rs:5:11 + | +LL | if let(Some(_))= Some(1) {} + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-103435-extra-parentheses.rs:2:9 + | +LL | #![deny(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - if let(Some(_))= Some(1) {} +LL + if let Some(_) = Some(1) {} + | + +error: unnecessary parentheses around pattern + --> $DIR/issue-103435-extra-parentheses.rs:8:8 + | +LL | for(_x)in 1..10 {} + | ^ ^ + | +help: remove these parentheses + | +LL - for(_x)in 1..10 {} +LL + for _x in 1..10 {} + | + +error: unnecessary parentheses around `if` condition + --> $DIR/issue-103435-extra-parentheses.rs:11:7 + | +LL | if(2 == 1){} + | ^ ^ + | +help: remove these parentheses + | +LL - if(2 == 1){} +LL + if 2 == 1 {} + | + +error: aborting due to 3 previous errors + From 4bed47e137ce9756ca29e5d0779b125ae3fbeb02 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 24 Oct 2022 18:24:10 +0800 Subject: [PATCH 448/482] fix parentheses surrounding spacing issue in parser --- compiler/rustc_lint/src/unused.rs | 6 ++--- compiler/rustc_parse/src/errors.rs | 6 +++-- .../rustc_parse/src/parser/diagnostics.rs | 24 +++++++++++++++---- .../lint/issue-103435-extra-parentheses.fixed | 6 +++-- .../ui/lint/issue-103435-extra-parentheses.rs | 6 +++-- .../issue-103435-extra-parentheses.stderr | 20 +++++++++++++++- 6 files changed, 52 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index f9458ddd35032..ff0fb9bae9232 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -584,8 +584,7 @@ trait UnusedDelimLint { let sm = cx.sess().source_map(); let lo_replace = if keep_space.0 && - let Ok(snip) = sm.span_to_snippet(lo.with_lo(lo.lo() - BytePos(1))) && - !snip.starts_with(" ") { + let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") { " ".to_string() } else { "".to_string() @@ -593,8 +592,7 @@ trait UnusedDelimLint { let hi_replace = if keep_space.1 && - let Ok(snip) = sm.span_to_snippet(sm.next_point(hi)) && - !snip.starts_with(" ") { + let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") { " ".to_string() } else { "".to_string() diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index e3acc11811f42..d59982f7063f3 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1165,10 +1165,12 @@ pub(crate) struct ParenthesesInForHead { #[derive(Subdiagnostic)] #[multipart_suggestion(suggestion, applicability = "machine-applicable")] pub(crate) struct ParenthesesInForHeadSugg { - #[suggestion_part(code = "")] + #[suggestion_part(code = "{left_snippet}")] pub left: Span, - #[suggestion_part(code = "")] + pub left_snippet: String, + #[suggestion_part(code = "{right_snippet}")] pub right: Span, + pub right_snippet: String, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c609aa93da3a7..0bbe073fe2af4 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1653,15 +1653,29 @@ impl<'a> Parser<'a> { (token::CloseDelim(Delimiter::Parenthesis), Some(begin_par_sp)) => { self.bump(); + let sm = self.sess.source_map(); + let left = begin_par_sp; + let right = self.prev_token.span; + let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) && + !snip.ends_with(" ") { + " ".to_string() + } else { + "".to_string() + }; + + let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) && + !snip.starts_with(" ") { + " ".to_string() + } else { + "".to_string() + }; + self.sess.emit_err(ParenthesesInForHead { - span: vec![begin_par_sp, self.prev_token.span], + span: vec![left, right], // With e.g. `for (x) in y)` this would replace `(x) in y)` // with `x) in y)` which is syntactically invalid. // However, this is prevented before we get here. - sugg: ParenthesesInForHeadSugg { - left: begin_par_sp, - right: self.prev_token.span, - }, + sugg: ParenthesesInForHeadSugg { left, right, left_snippet, right_snippet }, }); // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint. diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.fixed b/src/test/ui/lint/issue-103435-extra-parentheses.fixed index dbbcaa441ddd6..2b01b414baa6e 100644 --- a/src/test/ui/lint/issue-103435-extra-parentheses.fixed +++ b/src/test/ui/lint/issue-103435-extra-parentheses.fixed @@ -11,6 +11,8 @@ fn main() { if 2 == 1 {} //~^ ERROR unnecessary parentheses around `if` condition - // FIXME, auto recover from this one? - // for(_x in 1..10) {} + // reported by parser + for _x in 1..10 {} + //~^ ERROR expected one of + //~| ERROR unexpected parentheses surrounding } diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.rs b/src/test/ui/lint/issue-103435-extra-parentheses.rs index f5c2a6664ede4..8261610cf5646 100644 --- a/src/test/ui/lint/issue-103435-extra-parentheses.rs +++ b/src/test/ui/lint/issue-103435-extra-parentheses.rs @@ -11,6 +11,8 @@ fn main() { if(2 == 1){} //~^ ERROR unnecessary parentheses around `if` condition - // FIXME, auto recover from this one? - // for(_x in 1..10) {} + // reported by parser + for(_x in 1..10){} + //~^ ERROR expected one of + //~| ERROR unexpected parentheses surrounding } diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.stderr b/src/test/ui/lint/issue-103435-extra-parentheses.stderr index a3f2fbc51ab29..29c41c91050b9 100644 --- a/src/test/ui/lint/issue-103435-extra-parentheses.stderr +++ b/src/test/ui/lint/issue-103435-extra-parentheses.stderr @@ -1,3 +1,21 @@ +error: expected one of `)`, `,`, `@`, or `|`, found keyword `in` + --> $DIR/issue-103435-extra-parentheses.rs:15:12 + | +LL | for(_x in 1..10){} + | ^^ expected one of `)`, `,`, `@`, or `|` + +error: unexpected parentheses surrounding `for` loop head + --> $DIR/issue-103435-extra-parentheses.rs:15:8 + | +LL | for(_x in 1..10){} + | ^ ^ + | +help: remove parentheses in `for` loop + | +LL - for(_x in 1..10){} +LL + for _x in 1..10 {} + | + error: unnecessary parentheses around pattern --> $DIR/issue-103435-extra-parentheses.rs:5:11 | @@ -39,5 +57,5 @@ LL - if(2 == 1){} LL + if 2 == 1 {} | -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors From 7cccd3b0c0875e84fd43c2caefdb64c28aab3808 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 26 Oct 2022 00:15:47 +0800 Subject: [PATCH 449/482] suggest calling the method of the same name when method not found --- .../rustc_resolve/src/late/diagnostics.rs | 24 +++++++++---------- src/test/ui/resolve/issue-103474.rs | 16 +++++++++++++ src/test/ui/resolve/issue-103474.stderr | 20 ++++++++++++++++ src/test/ui/resolve/issue-2356.stderr | 4 ++-- src/test/ui/self/class-missing-self.stderr | 4 ++++ .../suggestions/assoc_fn_without_self.stderr | 9 +++++-- 6 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/resolve/issue-103474.rs create mode 100644 src/test/ui/resolve/issue-103474.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2587a9c4b3498..f2bfec5a2a38a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -219,26 +219,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let (mod_prefix, mod_str, suggestion) = if path.len() == 1 { debug!(?self.diagnostic_metadata.current_impl_items); debug!(?self.diagnostic_metadata.current_function); - let suggestion = if let Some(items) = self.diagnostic_metadata.current_impl_items + let suggestion = if self.current_trait_ref.is_none() && let Some((fn_kind, _)) = self.diagnostic_metadata.current_function - && self.current_trait_ref.is_none() && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt() + && let Some(items) = self.diagnostic_metadata.current_impl_items && let Some(item) = items.iter().find(|i| { - if let AssocItemKind::Fn(fn_) = &i.kind - && !fn_.sig.decl.has_self() - && i.ident.name == item_str.name + if let AssocItemKind::Fn(_) = &i.kind && i.ident.name == item_str.name { debug!(?item_str.name); - debug!(?fn_.sig.decl.inputs); return true } false }) + && let AssocItemKind::Fn(fn_) = &item.kind { + debug!(?fn_); + let self_sugg = if fn_.sig.decl.has_self() { "self." } else { "Self::" }; Some(( - item_span, + item_span.shrink_to_lo(), "consider using the associated function", - format!("Self::{}", item.ident) + self_sugg.to_string() )) } else { None @@ -396,11 +396,13 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) { - let is_assoc_fn = self.self_type_is_available(); + if !self.self_type_is_available() { + return; + } let Some(path_last_segment) = path.last() else { return }; let item_str = path_last_segment.ident; // Emit help message for fake-self from other languages (e.g., `this` in Javascript). - if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn { + if ["this", "my"].contains(&item_str.as_str()) { err.span_suggestion_short( span, "you might have meant to use `self` here instead", @@ -451,7 +453,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); let path_str = Segment::names_to_string(path); let ident_span = path.last().map_or(span, |ident| ident.ident.span); - let mut candidates = self .r .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected) @@ -1542,7 +1543,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { _ => None, } } - // Fields are generally expected in the same contexts as locals. if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) { if let Some(node_id) = diff --git a/src/test/ui/resolve/issue-103474.rs b/src/test/ui/resolve/issue-103474.rs new file mode 100644 index 0000000000000..408139ca0111e --- /dev/null +++ b/src/test/ui/resolve/issue-103474.rs @@ -0,0 +1,16 @@ +struct S {} +impl S { + fn first(&self) {} + + fn second(&self) { + first() + //~^ ERROR cannot find function `first` in this scope + } + + fn third(&self) { + no_method_err() + //~^ ERROR cannot find function `no_method_err` in this scope + } +} + +fn main() {} diff --git a/src/test/ui/resolve/issue-103474.stderr b/src/test/ui/resolve/issue-103474.stderr new file mode 100644 index 0000000000000..78fa13fbd2e24 --- /dev/null +++ b/src/test/ui/resolve/issue-103474.stderr @@ -0,0 +1,20 @@ +error[E0425]: cannot find function `first` in this scope + --> $DIR/issue-103474.rs:6:9 + | +LL | first() + | ^^^^^ not found in this scope + | +help: consider using the associated function + | +LL | self.first() + | +++++ + +error[E0425]: cannot find function `no_method_err` in this scope + --> $DIR/issue-103474.rs:11:9 + | +LL | no_method_err() + | ^^^^^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr index e7c53ff44e6fe..36f3da7c95537 100644 --- a/src/test/ui/resolve/issue-2356.stderr +++ b/src/test/ui/resolve/issue-2356.stderr @@ -85,7 +85,7 @@ LL | static_method(); help: consider using the associated function | LL | Self::static_method(); - | ~~~~~~~~~~~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:54:9 @@ -114,7 +114,7 @@ LL | grow_older(); help: consider using the associated function | LL | Self::grow_older(); - | ~~~~~~~~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:74:5 diff --git a/src/test/ui/self/class-missing-self.stderr b/src/test/ui/self/class-missing-self.stderr index d501200d73cec..063c3f013c539 100644 --- a/src/test/ui/self/class-missing-self.stderr +++ b/src/test/ui/self/class-missing-self.stderr @@ -10,6 +10,10 @@ error[E0425]: cannot find function `sleep` in this scope LL | sleep(); | ^^^^^ not found in this scope | +help: consider using the associated function + | +LL | self.sleep(); + | +++++ help: consider importing this function | LL | use std::thread::sleep; diff --git a/src/test/ui/suggestions/assoc_fn_without_self.stderr b/src/test/ui/suggestions/assoc_fn_without_self.stderr index 88920b852905b..febdd67338c99 100644 --- a/src/test/ui/suggestions/assoc_fn_without_self.stderr +++ b/src/test/ui/suggestions/assoc_fn_without_self.stderr @@ -7,13 +7,18 @@ LL | foo(); help: consider using the associated function | LL | Self::foo(); - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:17:9 | LL | bar(); | ^^^ not found in this scope + | +help: consider using the associated function + | +LL | self.bar(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/assoc_fn_without_self.rs:18:9 @@ -24,7 +29,7 @@ LL | baz(2, 3); help: consider using the associated function | LL | Self::baz(2, 3); - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `foo` in this scope --> $DIR/assoc_fn_without_self.rs:14:13 From f33c24550f9245f315cc2c5c7c6b73d1536a7c12 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 26 Oct 2022 05:32:19 +0800 Subject: [PATCH 450/482] add testcase for suggest self --- src/test/ui/resolve/issue-103474.rs | 12 ++++++++++++ src/test/ui/resolve/issue-103474.stderr | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/test/ui/resolve/issue-103474.rs b/src/test/ui/resolve/issue-103474.rs index 408139ca0111e..14f2259e1d4e8 100644 --- a/src/test/ui/resolve/issue-103474.rs +++ b/src/test/ui/resolve/issue-103474.rs @@ -13,4 +13,16 @@ impl S { } } +// https://github.com/rust-lang/rust/pull/103531#discussion_r1004728080 +struct Foo { + i: i32, +} + +impl Foo { + fn needs_self() { + this.i + //~^ ERROR cannot find value `this` in this scope + } +} + fn main() {} diff --git a/src/test/ui/resolve/issue-103474.stderr b/src/test/ui/resolve/issue-103474.stderr index 78fa13fbd2e24..415d231552a03 100644 --- a/src/test/ui/resolve/issue-103474.stderr +++ b/src/test/ui/resolve/issue-103474.stderr @@ -1,3 +1,18 @@ +error[E0425]: cannot find value `this` in this scope + --> $DIR/issue-103474.rs:23:9 + | +LL | this.i + | ^^^^ not found in this scope + | +help: you might have meant to use `self` here instead + | +LL | self.i + | ~~~~ +help: if you meant to use `self`, you are also missing a `self` receiver argument + | +LL | fn needs_self(&self) { + | +++++ + error[E0425]: cannot find function `first` in this scope --> $DIR/issue-103474.rs:6:9 | @@ -15,6 +30,6 @@ error[E0425]: cannot find function `no_method_err` in this scope LL | no_method_err() | ^^^^^^^^^^^^^ not found in this scope -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. From d6013d8caa1c7a9d0ed47bc12de8b062f6bb9a86 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Wed, 14 Sep 2022 23:07:19 +0800 Subject: [PATCH 451/482] lint auto pass Revert "lint auto pass" This reverts commit e58e4466384924c491a932d3f18ef50ffa5a5065. --- compiler/rustc_borrowck/src/borrow_set.rs | 2 ++ compiler/rustc_borrowck/src/constraint_generation.rs | 2 ++ compiler/rustc_borrowck/src/constraints/mod.rs | 3 +++ compiler/rustc_borrowck/src/consumers.rs | 2 ++ compiler/rustc_borrowck/src/dataflow.rs | 2 ++ compiler/rustc_borrowck/src/def_use.rs | 2 ++ compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs | 3 +++ compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs | 3 +++ compiler/rustc_borrowck/src/diagnostics/find_use.rs | 3 +++ compiler/rustc_borrowck/src/diagnostics/var_name.rs | 3 +++ compiler/rustc_borrowck/src/facts.rs | 2 ++ compiler/rustc_borrowck/src/invalidation.rs | 2 ++ compiler/rustc_borrowck/src/location.rs | 2 ++ compiler/rustc_borrowck/src/member_constraints.rs | 2 ++ compiler/rustc_borrowck/src/nll.rs | 2 ++ compiler/rustc_borrowck/src/path_utils.rs | 2 ++ compiler/rustc_borrowck/src/place_ext.rs | 2 ++ compiler/rustc_borrowck/src/places_conflict.rs | 2 ++ compiler/rustc_borrowck/src/prefixes.rs | 2 ++ compiler/rustc_borrowck/src/region_infer/dump_mir.rs | 2 ++ compiler/rustc_borrowck/src/region_infer/graphviz.rs | 2 ++ compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs | 2 ++ compiler/rustc_borrowck/src/region_infer/values.rs | 2 ++ compiler/rustc_borrowck/src/renumber.rs | 2 ++ compiler/rustc_borrowck/src/type_check/mod.rs | 2 ++ compiler/rustc_borrowck/src/used_muts.rs | 2 ++ 26 files changed, 57 insertions(+) diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index 41279588e6334..563ff056ae467 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::nll::ToRegionVid; use crate::path_utils::allow_two_phase_borrow; use crate::place_ext::PlaceExt; diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index f185e402fc6de..11b31c3f14028 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_infer::infer::InferCtxt; use rustc_middle::mir::visit::TyContext; use rustc_middle::mir::visit::Visitor; diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 9d9c4abb0aa57..84a93e5f72e9d 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_data_structures::graph::scc::Sccs; use rustc_index::vec::IndexVec; use rustc_middle::mir::ConstraintCategory; diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index b162095f8a6cd..86da767f32273 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This file provides API for compiler consumers. use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 9f7a4d49989ab..8070c0e6710ee 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; use rustc_middle::mir::{self, BasicBlock, Body, Location, Place}; diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index a5c0d77429de8..8e62a0198be46 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_middle::mir::visit::{ MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 897a161f78563..b99bfda1a51fe 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; diff --git a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs index b3edc35dc3642..498e9834354b7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::BTreeSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index b5a3081e56a7a..15f42e26cbf4a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use std::collections::VecDeque; use std::rc::Rc; diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 9ba29f04b1a9a..b385f95b67c6f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -1,3 +1,6 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + use crate::Upvar; use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use rustc_index::vec::{Idx, IndexVec}; diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 22134d5a71ce1..51ed27c167d38 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::location::{LocationIndex, LocationTable}; use crate::BorrowIndex; use polonius_engine::AllFacts as PoloniusFacts; diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 3157f861d93be..f5317a143aed7 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::graph::dominators::Dominators; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue}; diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 877944d3d70cb..9fa7e218b1b6f 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::{BasicBlock, Body, Location}; diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index 43253a2aab00c..b48f9f97daad8 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::IndexVec; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 4e0205f8d43a1..f8856b56d140b 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! The entry point of the NLL borrow checker. use rustc_data_structures::vec_map::VecMap; diff --git a/compiler/rustc_borrowck/src/path_utils.rs b/compiler/rustc_borrowck/src/path_utils.rs index b2c8dfc82c206..f8a99a2699e6f 100644 --- a/compiler/rustc_borrowck/src/path_utils.rs +++ b/compiler/rustc_borrowck/src/path_utils.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; use crate::places_conflict; use crate::AccessDepth; diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs index 93d202e49a159..9f6b1fdfcb540 100644 --- a/compiler/rustc_borrowck/src/place_ext.rs +++ b/compiler/rustc_borrowck/src/place_ext.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::borrow_set::LocalsStateAtExit; use rustc_hir as hir; use rustc_middle::mir::ProjectionElem; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 0e71efd6f8d3e..8a87d1972ebf3 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::ArtificialField; use crate::Overlap; use crate::{AccessDepth, Deep, Shallow}; diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 2b50cbac9a02d..6f28134986376 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an //! place are formed by stripping away fields and derefs, except that //! we stop when we reach the deref of a shared reference. [...] " diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index cc9450999525a..6524b594e44dc 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! As part of generating the regions, if you enable `-Zdump-mir=nll`, //! we will generate an annotated copy of the MIR that includes the //! state of region inference. This code handles emitting the region diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index f31ccd74ca6f7..2e15586e03b3b 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This module provides linkage between RegionInferenceContext and //! `rustc_graphviz` traits, specialized to attaching borrowck analysis //! data to rendered labels. diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 1e6798eee3df8..167f664609698 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::constraints::ConstraintSccIndex; use crate::RegionInferenceContext; use itertools::Itertools; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index de20a4bb465c2..7498ddccf196a 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::IntervalSet; diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index f3023769081f2..084754830bdbf 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::mir::visit::{MutVisitor, TyContext}; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9c1d0bb8b2357..6ccc29b09c0a5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This pass type-checks the MIR to ensure it is not broken. use std::rc::Rc; diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 8833753b12c5d..e297b1230ea0c 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ From 985ae0eeccfbb78d55d0e537cac61d3cba71d689 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Fri, 4 Nov 2022 17:09:14 +0800 Subject: [PATCH 452/482] remove old var_span_path_only doc comment --- .../src/diagnostics/conflict_errors.rs | 15 ++----- .../rustc_borrowck/src/diagnostics/mod.rs | 33 +++++++++++--- .../rustc_borrowck/src/session_diagnostics.rs | 44 +++++++++++++++++++ .../locales/en-US/borrowck.ftl | 24 ++++++++++ 4 files changed, 99 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 86cae5d09b5aa..ea07a3fa3e04c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -224,10 +224,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - use_spans.var_span_label_path_only( - &mut err, - format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), - ); + use_spans.var_path_only_subdiag(&mut err, desired_action); if !is_loop_move { err.span_label( @@ -404,10 +401,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let used = desired_action.as_general_verb_in_past_tense(); let mut err = struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}"); - use_spans.var_span_label_path_only( - &mut err, - format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), - ); + use_spans.var_path_only_subdiag(&mut err, desired_action); if let InitializationRequiringAction::PartialAssignment | InitializationRequiringAction::Assignment = desired_action @@ -678,10 +672,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); err.span_label(span, format!("move out of {} occurs here", value_msg)); - borrow_spans.var_span_label_path_only( - &mut err, - format!("borrow occurs due to use{}", borrow_spans.describe()), - ); + borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow); move_spans.var_span_label( &mut err, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 61518378e3d0c..c7b9f617d5a52 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -595,11 +595,34 @@ impl UseSpans<'_> { } } - // Add a span label to the use of the captured variable, if it exists. - // only adds label to the `path_span` - pub(super) fn var_span_label_path_only(self, err: &mut Diagnostic, message: impl Into) { - if let UseSpans::ClosureUse { path_span, .. } = self { - err.span_label(path_span, message); + /// Add a span label to the use of the captured variable, if it exists. + /// only adds label to the `path_span` + pub(super) fn var_path_only_subdiag( + self, + err: &mut Diagnostic, + action: crate::InitializationRequiringAction, + ) { + use crate::session_diagnostics::CaptureVarPathUseCause::*; + use crate::InitializationRequiringAction::*; + if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self { + match generator_kind { + Some(_) => { + err.subdiagnostic(match action { + Borrow => BorrowInGenerator { path_span }, + MatchOn | Use => UseInGenerator { path_span }, + Assignment => AssignInGenerator { path_span }, + PartialAssignment => AssignPartInGenerator { path_span }, + }); + } + None => { + err.subdiagnostic(match action { + Borrow => BorrowInClosure { path_span }, + MatchOn | Use => UseInClosure { path_span }, + Assignment => AssignInClosure { path_span }, + PartialAssignment => AssignPartInClosure { path_span }, + }); + } + } } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 824f20a31bb09..62c11e303b800 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -178,3 +178,47 @@ pub(crate) enum CaptureVarCause { var_span: Span, }, } + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarPathUseCause { + #[label(borrowck_borrow_due_to_use_generator)] + BorrowInGenerator { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_use_due_to_use_generator)] + UseInGenerator { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_assign_due_to_use_generator)] + AssignInGenerator { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_assign_part_due_to_use_generator)] + AssignPartInGenerator { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_borrow_due_to_use_closure)] + BorrowInClosure { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_use_due_to_use_closure)] + UseInClosure { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_assign_due_to_use_closure)] + AssignInClosure { + #[primary_span] + path_span: Span, + }, + #[label(borrowck_assign_part_due_to_use_closure)] + AssignPartInClosure { + #[primary_span] + path_span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 80fc4c6e4f5d3..5d6617d5bcc72 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -70,3 +70,27 @@ borrowck_var_borrow_by_use_place_in_closure = borrowck_var_borrow_by_use_place = borrow occurs due to use of {$place} + +borrowck_borrow_due_to_use_generator = + borrow occurs due to use in generator + +borrowck_use_due_to_use_generator = + use occurs due to use in generator + +borrowck_assign_due_to_use_generator = + assign occurs due to use in generator + +borrowck_assign_part_due_to_use_generator = + assign to part occurs due to use in generator + +borrowck_borrow_due_to_use_closure = + borrow occurs due to use in closure + +borrowck_use_due_to_use_closure = + use occurs due to use in closure + +borrowck_assign_due_to_use_closure = + assign occurs due to use in closure + +borrowck_assign_part_due_to_use_closure = + assign to part occurs due to use in closure From c9e2156d58e86e446f382ef8abf25e0ef465ac69 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:56:28 +0800 Subject: [PATCH 453/482] var_subdiag refinement trim old --- .../src/diagnostics/conflict_errors.rs | 25 +++---- .../rustc_borrowck/src/diagnostics/mod.rs | 31 +++++---- .../rustc_borrowck/src/session_diagnostics.rs | 65 ++++++++++--------- .../locales/en-US/borrowck.ftl | 15 +++++ compiler/rustc_middle/src/mir/mod.rs | 1 + 5 files changed, 80 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ea07a3fa3e04c..eb254c76aabad 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -715,22 +715,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - borrow_spans.var_subdiag( - &mut err, - |var_span| { - use crate::session_diagnostics::CaptureVarCause::*; - let place = &borrow.borrowed_place; - let desc_place = self.describe_any_place(place.as_ref()); - match borrow_spans { - UseSpans::ClosureUse { generator_kind, .. } => match generator_kind { - Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, - None => BorrowUsePlaceClosure { place: desc_place, var_span }, - }, - _ => BorrowUsePlace { place: desc_place, var_span }, - } - }, - "mutable", - ); + borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + let place = &borrow.borrowed_place; + let desc_place = self.describe_any_place(place.as_ref()); + match kind { + Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, + None => BorrowUsePlaceClosure { place: desc_place, var_span }, + } + }); self.explain_why_borrow_contains_point(location, borrow, None) .add_explanation_to_diagnostic( diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c7b9f617d5a52..7f26af67c71b2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -650,19 +650,28 @@ impl UseSpans<'_> { pub(super) fn var_subdiag( self, err: &mut Diagnostic, - f: impl Fn(Span) -> crate::session_diagnostics::CaptureVarCause, - kind_desc: impl Into, + kind: Option, + f: impl Fn(Option, Span) -> crate::session_diagnostics::CaptureVarCause, ) { - if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self { - if capture_kind_span == path_span { - err.subdiagnostic(f(capture_kind_span)); - } else { - err.subdiagnostic(crate::session_diagnostics::CaptureVarKind { - kind_desc: kind_desc.into(), - kind_span: capture_kind_span, + use crate::session_diagnostics::CaptureVarKind::*; + if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self { + if capture_kind_span != path_span { + err.subdiagnostic(match kind { + Some(kd) => match kd { + rustc_middle::mir::BorrowKind::Shared + | rustc_middle::mir::BorrowKind::Shallow + | rustc_middle::mir::BorrowKind::Unique => { + Immute { kind_span: capture_kind_span } + } + + rustc_middle::mir::BorrowKind::Mut { .. } => { + Mut { kind_span: capture_kind_span } + } + }, + None => Move { kind_span: capture_kind_span }, }); - err.subdiagnostic(f(path_span)); - } + }; + err.subdiagnostic(f(generator_kind, path_span)); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 62c11e303b800..3f9bfc5373aea 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -149,36 +149,6 @@ pub(crate) enum RequireStaticErr { }, } -#[derive(Subdiagnostic)] -#[label(borrowck_capture_kind_label)] -pub(crate) struct CaptureVarKind { - pub kind_desc: String, - #[primary_span] - pub kind_span: Span, -} - -#[derive(Subdiagnostic)] -pub(crate) enum CaptureVarCause { - #[label(borrowck_var_borrow_by_use_place)] - BorrowUsePlace { - place: String, - #[primary_span] - var_span: Span, - }, - #[label(borrowck_var_borrow_by_use_place_in_generator)] - BorrowUsePlaceGenerator { - place: String, - #[primary_span] - var_span: Span, - }, - #[label(borrowck_var_borrow_by_use_place_in_closure)] - BorrowUsePlaceClosure { - place: String, - #[primary_span] - var_span: Span, - }, -} - #[derive(Subdiagnostic)] pub(crate) enum CaptureVarPathUseCause { #[label(borrowck_borrow_due_to_use_generator)] @@ -222,3 +192,38 @@ pub(crate) enum CaptureVarPathUseCause { path_span: Span, }, } + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarKind { + #[label(borrowck_capture_immute)] + Immute { + #[primary_span] + kind_span: Span, + }, + #[label(borrowck_capture_mut)] + Mut { + #[primary_span] + kind_span: Span, + }, + #[label(borrowck_capture_move)] + Move { + #[primary_span] + kind_span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarCause { + #[label(borrowck_var_borrow_by_use_place_in_generator)] + BorrowUsePlaceGenerator { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_borrow_by_use_place_in_closure)] + BorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 5d6617d5bcc72..e3174360c90e2 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -94,3 +94,18 @@ borrowck_assign_due_to_use_closure = borrowck_assign_part_due_to_use_closure = assign to part occurs due to use in closure + +borrowck_capture_immute = + capture is immutable because of use here + +borrowck_capture_mut = + capture is mutable because of use here + +borrowck_capture_move = + capture is moved because of use here + +borrowck_var_move_by_use_place_in_generator = + move occurs due to use of {$place} in generator + +borrowck_var_move_by_use_place_in_closure = + move occurs due to use of {$place} in closure diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 54f3964d28f06..a4495d2934df3 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1957,6 +1957,7 @@ impl BorrowKind { } } + // FIXME: won't be used after diagnostic migration pub fn describe_mutability(&self) -> &str { match *self { BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => "immutable", From a0308634b1933d50ffeb0c1358941ef2e9f6aac9 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:57:44 +0800 Subject: [PATCH 454/482] struct error E0505 --- compiler/rustc_borrowck/src/borrowck_errors.rs | 13 +++++++++++-- .../src/diagnostics/conflict_errors.rs | 11 +++++++---- compiler/rustc_borrowck/src/session_diagnostics.rs | 13 +++++++++++++ .../locales/en-US/borrowck.ftl | 14 ++++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 08ea00d71ef9d..01be379120dc7 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -8,9 +8,18 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { pub(crate) fn cannot_move_when_borrowed( &self, span: Span, - desc: &str, + borrow_span: Span, + place: &str, + borrow_place: &str, + value_place: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,) + self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow { + place, + span, + borrow_place, + value_place, + borrow_span, + }) } pub(crate) fn cannot_use_when_mutably_borrowed( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index eb254c76aabad..9e0aa57b2553f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -667,10 +667,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let move_spans = self.move_spans(place.as_ref(), location); let span = move_spans.args_or_use(); - let mut err = - self.cannot_move_when_borrowed(span, &self.describe_any_place(place.as_ref())); - err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); - err.span_label(span, format!("move out of {} occurs here", value_msg)); + let mut err = self.cannot_move_when_borrowed( + span, + borrow_span, + &self.describe_any_place(place.as_ref()), + &borrow_msg, + &value_msg, + ); borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow); diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 3f9bfc5373aea..577332c0744b8 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -227,3 +227,16 @@ pub(crate) enum CaptureVarCause { var_span: Span, }, } + +#[derive(Diagnostic)] +#[diag(borrowck_cannot_move_when_borrowed, code = "E0505")] +pub(crate) struct MoveBorrow<'a> { + pub place: &'a str, + pub borrow_place: &'a str, + pub value_place: &'a str, + #[primary_span] + #[label(move_label)] + pub span: Span, + #[label] + pub borrow_span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index e3174360c90e2..de47ada826444 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -109,3 +109,17 @@ borrowck_var_move_by_use_place_in_generator = borrowck_var_move_by_use_place_in_closure = move occurs due to use of {$place} in closure + +borrowck_cannot_move_when_borrowed = + cannot move out of {$place -> + [value] value + *[other] {$place} + } because it is borrowed + .label = borrow of {$borrow_place -> + [value] value + *[other] {$borrow_place} + } occurs here + .move_label = move out of {$value_place -> + [value] value + *[other] {$value_place} + } occurs here From 4db1d359cab30bd0437bf3afce3e239d6cc4464e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Oct 2022 12:36:31 +0200 Subject: [PATCH 455/482] explain how to go back to rustup-managed Miri --- src/tools/miri/CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index b1e6b9c69d390..a2c86c3a8b23e 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -138,6 +138,9 @@ There's a test for the cargo wrapper in the `test-cargo-miri` directory; run `./run-test.py` in there to execute it. Like `./miri test`, this respects the `MIRI_TEST_TARGET` environment variable to execute the test for another target. +Note that installing Miri like this will "take away" Miri management from `rustup`. +If you want to later go back to a rustup-installed Miri, run `rustup update`. + ### Using a modified standard library Miri re-builds the standard library into a custom sysroot, so it is fairly easy From 7567627c2b6b9ca4a588f8eeb81f85383aec1b6a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Oct 2022 11:30:07 +0200 Subject: [PATCH 456/482] teach ./miri how to do Josh syncs --- src/tools/miri/CONTRIBUTING.md | 23 +++---- src/tools/miri/miri | 110 +++++++++++++++++++++++---------- 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index a2c86c3a8b23e..ecf6e59dd576a 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -293,14 +293,12 @@ cargo run --release -p josh-proxy -- --local=$(pwd)/local --remote=https://githu ### Importing changes from the rustc repo +Josh needs to be running, as described above. We assume we start on an up-to-date master branch in the Miri repo. ```sh -# Fetch rustc side of the history. Takes ca 5 min the first time. -# Do NOT change that commit ID, it needs to be exactly this! -git fetch http://localhost:8000/rust-lang/rust.git:at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri.git master -# Include that history into ours. -git merge FETCH_HEAD -m "merge rustc history" +# Fetch and merge rustc side of the history. Takes ca 5 min the first time. +./miri rustc-pull # Update toolchain reference and apply formatting. ./rustup-toolchain HEAD && ./miri fmt git commit -am "rustup" @@ -313,16 +311,15 @@ needed. ### Exporting changes to the rustc repo -We will use the josh proxy to push to your fork of rustc. You need to make sure -that the master branch of your fork is up-to-date. Also make sure that there -exists no branch called `miri` in your fork. Then run the following in the Miri -repo, assuming we are on an up-to-date master branch: +Josh needs to be running, as described above. We will use the josh proxy to push +to your fork of rustc. Run the following in the Miri repo, assuming we are on an +up-to-date master branch: ```sh # Push the Miri changes to your rustc fork (substitute your github handle for YOUR_NAME). -# Do NOT change that commit ID, it needs to be exactly this! -git push http://localhost:8000/YOUR_NAME/rust.git:at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri.git -o base=master HEAD:miri +./miri rustc-push YOUR_NAME miri ``` -This will create a new branch in your fork, and the output should include a link -to create a rustc PR that will integrate those changes into the main repository. +This will create a new branch called 'miri' in your fork, and the output should +include a link to create a rustc PR that will integrate those changes into the +main repository. diff --git a/src/tools/miri/miri b/src/tools/miri/miri index e492308a62eb5..662f2b8e63172 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -42,6 +42,15 @@ many different seeds. Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed. can explicitly list the benchmarks to run; by default, all of them are run. +./miri rustc-pull: +Pull and merge Miri changes from the rustc repo. + +./miri rustc-push : +Push Miri changes back to the rustc repo. This will update the 'master' branch +in the Rust fork of the given user to upstream. It will also pull a copy of the +rustc history into the Miri repo, unless you set the RUSTC_GIT env var to an +existing clone of the rustc repo. + ENVIRONMENT VARIABLES MIRI_SYSROOT: @@ -52,37 +61,60 @@ Pass extra flags to all cargo invocations. (Ignored by `./miri cargo`.) EOF ) -## We need to know where we are. +## We need to know which command to run and some global constants. +COMMAND="$1" +if [ -z "$COMMAND" ]; then + echo "$USAGE" + exit 1 +fi +shift # macOS does not have a useful readlink/realpath so we have to use Python instead... MIRIDIR=$(python3 -c 'import os, sys; print(os.path.dirname(os.path.realpath(sys.argv[1])))' "$0") +# Used for rustc syncs. +JOSH_FILTER=":at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri" -## Run the auto-things. -if [ -z "$MIRI_AUTO_OPS" ]; then - export MIRI_AUTO_OPS=42 - - # Run this first, so that the toolchain doesn't change after - # other code has run. - if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-toolchain" ] ; then - (cd "$MIRIDIR" && ./rustup-toolchain) +## Early commands, that don't do auto-things and don't want the environment-altering things happening below. +case "$COMMAND" in +rustc-pull) + cd "$MIRIDIR" + git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master + git merge FETCH_HEAD + exit 0 + ;; +rustc-push) + USER="$1" + BRANCH="$2" + if [ -z "$USER" ] || [ -z "$BRANCH" ]; then + echo "Usage: $0 rustc-push " + exit 1 fi - - if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-fmt" ] ; then - $0 fmt + if [ -n "$RUSTC_GIT" ]; then + # Use an existing fork for the branch updates. + cd "$RUSTC_GIT" + else + # Do this in the local Miri repo. + echo "This will pull a copy of the rust-lang/rust history into this Miri checkout, growing it by about 1GB." + read -r -p "To avoid that, abort now and set the RUSTC_GIT environment variable to an existing rustc checkout. Proceed? [y/N] " + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + cd "$MIRIDIR" fi - - if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-clippy" ] ; then - $0 clippy -- -D warnings + # Prepare the branches. For reliable pushing we need to push to a non-existent branch + # and set `-o base` to a branch that holds current rustc master. + echo "Preparing $USER/rust..." + if git fetch https://github.com/$USER/rust $BRANCH &>/dev/null; then + echo "The '$BRANCH' seems to already exist in $USER/rust. Please delete it and try again." + exit 1 fi -fi - -## Determine command and toolchain. -COMMAND="$1" -[ $# -gt 0 ] && shift -# Doing this *after* auto-toolchain logic above, since that might change the toolchain. -TOOLCHAIN=$(cd "$MIRIDIR"; rustup show active-toolchain | head -n 1 | cut -d ' ' -f 1) - -## Handle some commands early, since they should *not* alter the environment. -case "$COMMAND" in + git fetch https://github.com/rust-lang/rust master + git push https://github.com/$USER/rust FETCH_HEAD:master + # Do the actual push. + cd "$MIRIDIR" + echo "Pushing Miri changes..." + git push http://localhost:8000/$USER/rust.git$JOSH_FILTER.git HEAD:$BRANCH -o base=master + exit 0 + ;; many-seeds) for SEED in $({ echo obase=16; seq 0 255; } | bc); do echo "Trying seed: $SEED" @@ -106,9 +138,28 @@ bench) ;; esac +## Run the auto-things. +if [ -z "$MIRI_AUTO_OPS" ]; then + export MIRI_AUTO_OPS=42 + + # Run this first, so that the toolchain doesn't change after + # other code has run. + if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-toolchain" ] ; then + (cd "$MIRIDIR" && ./rustup-toolchain) + fi + + if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-fmt" ] ; then + $0 fmt + fi + + if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-clippy" ] ; then + $0 clippy -- -D warnings + fi +fi + ## Prepare the environment # Determine some toolchain properties -# export the target so its available in miri +TOOLCHAIN=$(cd "$MIRIDIR"; rustup show active-toolchain | head -n 1 | cut -d ' ' -f 1) TARGET=$(rustc +$TOOLCHAIN --version --verbose | grep "^host:" | cut -d ' ' -f 2) SYSROOT=$(rustc +$TOOLCHAIN --print sysroot) LIBDIR=$SYSROOT/lib/rustlib/$TARGET/lib @@ -227,10 +278,7 @@ cargo) $CARGO "$@" ;; *) - if [ -n "$COMMAND" ]; then - echo "Unknown command: $COMMAND" - echo - fi - echo "$USAGE" + echo "Unknown command: $COMMAND" exit 1 + ;; esac From b3c8584eb34e5947c9bc4f942584519fe0debd18 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Oct 2022 12:17:04 +0200 Subject: [PATCH 457/482] merge rustup-toolchain into ./miri --- src/tools/miri/.github/workflows/ci.yml | 6 +-- src/tools/miri/.gitpod.yml | 4 +- src/tools/miri/CONTRIBUTING.md | 10 ++--- src/tools/miri/README.md | 6 +-- src/tools/miri/miri | 45 ++++++++++++++++++++- src/tools/miri/rust-version | 2 +- src/tools/miri/rustup-toolchain | 53 ------------------------- 7 files changed, 58 insertions(+), 68 deletions(-) delete mode 100755 src/tools/miri/rustup-toolchain diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 3efb2d733d426..607ffe0cc59fe 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -67,9 +67,9 @@ jobs: shell: bash run: | if [[ ${{ github.event_name }} == 'schedule' ]]; then - ./rustup-toolchain HEAD --host ${{ matrix.host_target }} + ./miri toolchain HEAD --host ${{ matrix.host_target }} else - ./rustup-toolchain "" --host ${{ matrix.host_target }} + ./miri toolchain "" --host ${{ matrix.host_target }} fi - name: Show Rust version @@ -118,7 +118,7 @@ jobs: - name: Install "master" toolchain shell: bash run: | - ./rustup-toolchain "" -c clippy + ./miri toolchain - name: Show Rust version run: | diff --git a/src/tools/miri/.gitpod.yml b/src/tools/miri/.gitpod.yml index 36bd991740a82..724cf26df2b9b 100644 --- a/src/tools/miri/.gitpod.yml +++ b/src/tools/miri/.gitpod.yml @@ -4,6 +4,6 @@ tasks: - before: echo "..." init: | cargo install rustup-toolchain-install-master - ./rustup-toolchain + ./miri toolchain ./miri build - command: echo "Run tests with ./miri test" \ No newline at end of file + command: echo "Run tests with ./miri test" diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index ecf6e59dd576a..5c41547616ec6 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -23,13 +23,13 @@ tested against. Other versions will likely not work. After installing [`rustup-toolchain-install-master`], you can run the following command to install that exact version of rustc as a toolchain: ``` -./rustup-toolchain +./miri toolchain ``` This will set up a rustup toolchain called `miri` and set it as an override for the current directory. You can also create a `.auto-everything` file (contents don't matter, can be empty), which -will cause any `./miri` command to automatically call `rustup-toolchain`, `clippy` and `rustfmt` +will cause any `./miri` command to automatically call `./miri toolchain`, `clippy` and `rustfmt` for you. If you don't want all of these to happen, you can add individual `.auto-toolchain`, `.auto-clippy` and `.auto-fmt` files respectively. @@ -132,7 +132,7 @@ development version of Miri using and then you can use it as if it was installed by `rustup`. Make sure you use the same toolchain when calling `cargo miri` that you used when installing Miri! Usually this means you have to write `cargo +miri miri ...` to select the `miri` -toolchain that was installed by `./rustup-toolchain`. +toolchain that was installed by `./miri toolchain`. There's a test for the cargo wrapper in the `test-cargo-miri` directory; run `./run-test.py` in there to execute it. Like `./miri test`, this respects the @@ -217,7 +217,7 @@ for changes in rustc. In both cases, `rustc-version` needs updating. To update the `rustc-version` file and install the latest rustc, you can run: ``` -./rustup-toolchain HEAD +./miri toolchain HEAD ``` Now edit Miri until `./miri test` passes, and submit a PR. Generally, it is @@ -300,7 +300,7 @@ We assume we start on an up-to-date master branch in the Miri repo. # Fetch and merge rustc side of the history. Takes ca 5 min the first time. ./miri rustc-pull # Update toolchain reference and apply formatting. -./rustup-toolchain HEAD && ./miri fmt +./miri toolchain HEAD && ./miri fmt git commit -am "rustup" ``` diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index f5a20d592d06d..ff534c1ed6a0b 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -419,9 +419,9 @@ Some native rustc `-Z` flags are also very relevant for Miri: Moreover, Miri recognizes some environment variables: -* `MIRI_AUTO_OPS` indicates whether the automatic execution of rustfmt, clippy and rustup-toolchain - should be skipped. If it is set to any value, they are skipped. This is used for avoiding - infinite recursion in `./miri` and to allow automated IDE actions to avoid the auto ops. +* `MIRI_AUTO_OPS` indicates whether the automatic execution of rustfmt, clippy and toolchain setup + should be skipped. If it is set to any value, they are skipped. This is used for avoiding infinite + recursion in `./miri` and to allow automated IDE actions to avoid the auto ops. * `MIRI_LOG`, `MIRI_BACKTRACE` control logging and backtrace printing during Miri executions, also [see "Testing the Miri driver" in `CONTRIBUTING.md`][testing-miri]. * `MIRIFLAGS` (recognized by `cargo miri` and the test suite) defines extra diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 662f2b8e63172..52902410a6b2d 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -51,6 +51,13 @@ in the Rust fork of the given user to upstream. It will also pull a copy of the rustc history into the Miri repo, unless you set the RUSTC_GIT env var to an existing clone of the rustc repo. +./miri toolchain : +Update and activate the rustup toolchain 'miri'. If no commit is given, updates +to the commit given in the `rust-version` file. If the commit is `HEAD`, updates +to the latest upstream rustc commit. +`rustup-toolchain-install-master` must be installed for this to work. Any extra +flags are passed to `rustup-toolchain-install-master`. + ENVIRONMENT VARIABLES MIRI_SYSROOT: @@ -75,6 +82,42 @@ JOSH_FILTER=":at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/too ## Early commands, that don't do auto-things and don't want the environment-altering things happening below. case "$COMMAND" in +toolchain) + cd "$MIRIDIR" + # Make sure rustup-toolchain-install-master is installed. + if ! which rustup-toolchain-install-master >/dev/null; then + echo "Please install rustup-toolchain-install-master by running 'cargo install rustup-toolchain-install-master'" + exit 1 + fi + # Determine new commit. + if [[ "$1" == "" ]]; then + NEW_COMMIT=$(cat rust-version) + elif [[ "$1" == "HEAD" ]]; then + NEW_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) + else + NEW_COMMIT="$1" + fi + echo "$NEW_COMMIT" > rust-version + shift || true # don't fail if shifting fails because no commit was given + # Check if we already are at that commit. + CUR_COMMIT=$(rustc +miri --version -v 2>/dev/null | grep "^commit-hash: " | cut -d " " -f 2) + if [[ "$CUR_COMMIT" == "$NEW_COMMIT" ]]; then + echo "miri toolchain is already at commit $CUR_COMMIT." + rustup override set miri + exit 0 + fi + # Install and setup new toolchain. + rustup toolchain uninstall miri + rustup-toolchain-install-master -n miri -c cargo -c rust-src -c rustc-dev -c llvm-tools -c rustfmt -c clippy "$@" -- "$NEW_COMMIT" + rustup override set miri + # Cleanup. + cargo clean + # Call 'cargo metadata' on the sources in case that changes the lockfile + # (which fails under some setups when it is done from inside vscode). + cargo metadata --format-version 1 --manifest-path "$(rustc --print sysroot)/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml" >/dev/null + # Done! + exit 0 + ;; rustc-pull) cd "$MIRIDIR" git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master @@ -145,7 +188,7 @@ if [ -z "$MIRI_AUTO_OPS" ]; then # Run this first, so that the toolchain doesn't change after # other code has run. if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-toolchain" ] ; then - (cd "$MIRIDIR" && ./rustup-toolchain) + $0 toolchain fi if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-fmt" ] ; then diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index d0e98a8b0dba9..e582bf35356d6 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -85d089b41e2a0c0f07ab34f6c5a7c451389f25e6 +607878d069267e1402ad792c9331b426e4c6d0f9 diff --git a/src/tools/miri/rustup-toolchain b/src/tools/miri/rustup-toolchain deleted file mode 100755 index d7730f2b06d36..0000000000000 --- a/src/tools/miri/rustup-toolchain +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -set -e -# Manages a rustup toolchain called "miri". -# -# All commands set "miri" as the override toolchain for the current directory, -# and make the `rust-version` file match that toolchain. -# -# USAGE: -# -# ./rustup-toolchain: Update "miri" toolchain to match `rust-version` (the known-good version for this commit). -# -# ./rustup-toolchain HEAD: Update "miri" toolchain and `rust-version` file to latest rustc HEAD. -# -# ./rustup-toolchain $COMMIT: Update "miri" toolchain and `rust-version` file to match that commit. -# -# Any extra parameters are passed to `rustup-toolchain-install-master`. - -# Make sure rustup-toolchain-install-master is installed. -if ! which rustup-toolchain-install-master >/dev/null; then - echo "Please install rustup-toolchain-install-master by running 'cargo install rustup-toolchain-install-master'" - exit 1 -fi - -# Determine new commit. -if [[ "$1" == "" ]]; then - NEW_COMMIT=$(cat rust-version) -elif [[ "$1" == "HEAD" ]]; then - NEW_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) -else - NEW_COMMIT="$1" -fi -echo "$NEW_COMMIT" > rust-version -shift || true # don't fail if shifting fails - -# Check if we already are at that commit. -CUR_COMMIT=$(rustc +miri --version -v 2>/dev/null | grep "^commit-hash: " | cut -d " " -f 2) -if [[ "$CUR_COMMIT" == "$NEW_COMMIT" ]]; then - echo "miri toolchain is already at commit $CUR_COMMIT." - rustup override set miri - exit 0 -fi - -# Install and setup new toolchain. -rustup toolchain uninstall miri -rustup-toolchain-install-master -n miri -c cargo -c rust-src -c rustc-dev -c llvm-tools -c rustfmt -c clippy "$@" -- "$NEW_COMMIT" -rustup override set miri - -# Cleanup. -cargo clean - -# Call 'cargo metadata' on the sources in case that changes the lockfile -# (which fails under some setups when it is done from inside vscode). -cargo metadata --format-version 1 --manifest-path "$(rustc --print sysroot)/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml" >/dev/null From 31160c41f43f9be3cdf68e2039302d04a8666a46 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Oct 2022 16:11:03 +0200 Subject: [PATCH 458/482] Stacked Borrows: make scalar field retagging the default --- src/tools/miri/README.md | 7 ++++--- src/tools/miri/src/eval.rs | 2 +- .../stacked_borrows/newtype_pair_retagging.rs | 1 - .../fail/stacked_borrows/newtype_retagging.rs | 1 - .../return_invalid_mut_option.rs | 5 ++--- .../return_invalid_mut_option.stderr | 19 ++++++++++++------- .../return_invalid_mut_tuple.rs | 5 ++--- .../return_invalid_mut_tuple.stderr | 13 +++++++++---- .../return_invalid_shr_option.rs | 5 ++--- .../return_invalid_shr_option.stderr | 19 ++++++++++++------- .../return_invalid_shr_tuple.rs | 5 ++--- .../return_invalid_shr_tuple.stderr | 13 +++++++++---- .../stacked-borrows/no_field_retagging.rs | 19 +++++++++++++++++++ .../stacked-borrows/stack-printing.stdout | 4 ++-- 14 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 src/tools/miri/tests/pass/stacked-borrows/no_field_retagging.rs diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index ff534c1ed6a0b..1185525f6865c 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -374,14 +374,15 @@ to Miri failing to detect cases of undefined behavior in a program. application instead of raising an error within the context of Miri (and halting execution). Note that code might not expect these operations to ever panic, so this flag can lead to strange (mis)behavior. -* `-Zmiri-retag-fields` changes Stacked Borrows retagging to recurse into fields. +* `-Zmiri-retag-fields` changes Stacked Borrows retagging to recurse into *all* fields. This means that references in fields of structs/enums/tuples/arrays/... are retagged, and in particular, they are protected when passed as function arguments. + (The default is to recurse only in cases where rustc would actually emit a `noalias` attribute.) * `-Zmiri-retag-fields=` controls when Stacked Borrows retagging recurses into fields. `all` means it always recurses (like `-Zmiri-retag-fields`), `none` means it never - recurses (the default), `scalar` means it only recurses for types where we would also emit + recurses, `scalar` (the default) means it only recurses for types where we would also emit `noalias` annotations in the generated LLVM IR (types passed as indivudal scalars or pairs of - scalars). + scalars). Setting this to `none` is **unsound**. * `-Zmiri-tag-gc=` configures how often the pointer tag garbage collector runs. The default is to search for and remove unreachable tags once every `10000` basic blocks. Setting this to `0` disables the garbage collector, which causes some programs to have explosive memory usage diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index a3fc343f8b67c..81132db94cf18 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -163,7 +163,7 @@ impl Default for MiriConfig { mute_stdout_stderr: false, preemption_rate: 0.01, // 1% report_progress: None, - retag_fields: RetagFields::No, + retag_fields: RetagFields::OnlyScalar, external_so_file: None, gc_interval: 10_000, num_cpus: 1, diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs index 5cefdb08e7879..cc774500a3c69 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs @@ -1,4 +1,3 @@ -//@compile-flags: -Zmiri-retag-fields=scalar //@error-pattern: which is protected struct Newtype<'a>(&'a mut i32, i32); diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs index bc3883575c333..1aa6e240e30f1 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs @@ -1,4 +1,3 @@ -//@compile-flags: -Zmiri-retag-fields=scalar //@error-pattern: which is protected struct Newtype<'a>(&'a mut i32); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.rs b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.rs index 7fa9cf77d44b2..5a9dc6afba8da 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.rs @@ -1,16 +1,15 @@ // Make sure that we cannot return a `&mut` that got already invalidated, not even in an `Option`. -// Due to shallow reborrowing, the error only surfaces when we look into the `Option`. fn foo(x: &mut (i32, i32)) -> Option<&mut i32> { let xraw = x as *mut (i32, i32); let ret = unsafe { &mut (*xraw).1 }; // let-bind to avoid 2phase let ret = Some(ret); let _val = unsafe { *xraw }; // invalidate xref - ret + ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ } fn main() { match foo(&mut (1, 2)) { - Some(_x) => {} //~ ERROR: /retag .* tag does not exist in the borrow stack/ + Some(_x) => {} None => {} } } diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr index 1068c286c62fa..c0ff35ebcde30 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr @@ -1,11 +1,11 @@ error: Undefined Behavior: trying to retag from for Unique permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location --> $DIR/return_invalid_mut_option.rs:LL:CC | -LL | Some(_x) => {} - | ^^ - | | - | trying to retag from for Unique permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location - | this error occurs as part of retag at ALLOC[0x4..0x8] +LL | ret + | ^^^ + | | + | trying to retag from for Unique permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location + | this error occurs as part of retag at ALLOC[0x4..0x8] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -13,14 +13,19 @@ help: was created by a Unique retag at offsets [0x4..0x8] --> $DIR/return_invalid_mut_option.rs:LL:CC | LL | let ret = Some(ret); - | ^^^ + | ^^^^^^^^^ help: was later invalidated at offsets [0x0..0x8] by a read access --> $DIR/return_invalid_mut_option.rs:LL:CC | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ = note: BACKTRACE: - = note: inside `main` at $DIR/return_invalid_mut_option.rs:LL:CC + = note: inside `foo` at $DIR/return_invalid_mut_option.rs:LL:CC +note: inside `main` at $DIR/return_invalid_mut_option.rs:LL:CC + --> $DIR/return_invalid_mut_option.rs:LL:CC + | +LL | match foo(&mut (1, 2)) { + | ^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.rs b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.rs index c94fef90542fd..8fe7f15cab0c1 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.rs @@ -1,12 +1,11 @@ // Make sure that we cannot return a `&mut` that got already invalidated, not even in a tuple. -// Due to shallow reborrowing, the error only surfaces when we look into the tuple. fn foo(x: &mut (i32, i32)) -> (&mut i32,) { let xraw = x as *mut (i32, i32); let ret = (unsafe { &mut (*xraw).1 },); let _val = unsafe { *xraw }; // invalidate xref - ret + ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ } fn main() { - foo(&mut (1, 2)).0; //~ ERROR: /retag .* tag does not exist in the borrow stack/ + foo(&mut (1, 2)).0; } diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr index 79de9b668cf2b..9abf43c29f08f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: trying to retag from for Unique permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location --> $DIR/return_invalid_mut_tuple.rs:LL:CC | -LL | foo(&mut (1, 2)).0; - | ^^^^^^^^^^^^^^^^^^ +LL | ret + | ^^^ | | | trying to retag from for Unique permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location | this error occurs as part of retag at ALLOC[0x4..0x8] @@ -13,14 +13,19 @@ help: was created by a Unique retag at offsets [0x4..0x8] --> $DIR/return_invalid_mut_tuple.rs:LL:CC | LL | let ret = (unsafe { &mut (*xraw).1 },); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x8] by a read access --> $DIR/return_invalid_mut_tuple.rs:LL:CC | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ = note: BACKTRACE: - = note: inside `main` at $DIR/return_invalid_mut_tuple.rs:LL:CC + = note: inside `foo` at $DIR/return_invalid_mut_tuple.rs:LL:CC +note: inside `main` at $DIR/return_invalid_mut_tuple.rs:LL:CC + --> $DIR/return_invalid_mut_tuple.rs:LL:CC + | +LL | foo(&mut (1, 2)).0; + | ^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs index 3a028ceed86ae..094ce33b9c1f7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.rs @@ -1,15 +1,14 @@ // Make sure that we cannot return a `&` that got already invalidated, not even in an `Option`. -// Due to shallow reborrowing, the error only surfaces when we look into the `Option`. fn foo(x: &mut (i32, i32)) -> Option<&i32> { let xraw = x as *mut (i32, i32); let ret = Some(unsafe { &(*xraw).1 }); unsafe { *xraw = (42, 23) }; // unfreeze - ret + ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ } fn main() { match foo(&mut (1, 2)) { - Some(_x) => {} //~ ERROR: /retag .* tag does not exist in the borrow stack/ + Some(_x) => {} None => {} } } diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr index f45456305db29..6066bf89f5d09 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr @@ -1,11 +1,11 @@ error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location --> $DIR/return_invalid_shr_option.rs:LL:CC | -LL | Some(_x) => {} - | ^^ - | | - | trying to retag from for SharedReadOnly permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location - | this error occurs as part of retag at ALLOC[0x4..0x8] +LL | ret + | ^^^ + | | + | trying to retag from for SharedReadOnly permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location + | this error occurs as part of retag at ALLOC[0x4..0x8] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -13,14 +13,19 @@ help: was created by a SharedReadOnly retag at offsets [0x4..0x8] --> $DIR/return_invalid_shr_option.rs:LL:CC | LL | let ret = Some(unsafe { &(*xraw).1 }); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x8] by a write access --> $DIR/return_invalid_shr_option.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = note: BACKTRACE: - = note: inside `main` at $DIR/return_invalid_shr_option.rs:LL:CC + = note: inside `foo` at $DIR/return_invalid_shr_option.rs:LL:CC +note: inside `main` at $DIR/return_invalid_shr_option.rs:LL:CC + --> $DIR/return_invalid_shr_option.rs:LL:CC + | +LL | match foo(&mut (1, 2)) { + | ^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs index e4536626dbf2c..d0fd53e06aa26 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.rs @@ -1,12 +1,11 @@ // Make sure that we cannot return a `&` that got already invalidated, not even in a tuple. -// Due to shallow reborrowing, the error only surfaces when we look into the tuple. fn foo(x: &mut (i32, i32)) -> (&i32,) { let xraw = x as *mut (i32, i32); let ret = (unsafe { &(*xraw).1 },); unsafe { *xraw = (42, 23) }; // unfreeze - ret + ret //~ ERROR: /retag .* tag does not exist in the borrow stack/ } fn main() { - foo(&mut (1, 2)).0; //~ ERROR: /retag .* tag does not exist in the borrow stack/ + foo(&mut (1, 2)).0; } diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr index 2e41f505bb9d2..52d365246a744 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location --> $DIR/return_invalid_shr_tuple.rs:LL:CC | -LL | foo(&mut (1, 2)).0; - | ^^^^^^^^^^^^^^^^^^ +LL | ret + | ^^^ | | | trying to retag from for SharedReadOnly permission at ALLOC[0x4], but that tag does not exist in the borrow stack for this location | this error occurs as part of retag at ALLOC[0x4..0x8] @@ -13,14 +13,19 @@ help: was created by a SharedReadOnly retag at offsets [0x4..0x8] --> $DIR/return_invalid_shr_tuple.rs:LL:CC | LL | let ret = (unsafe { &(*xraw).1 },); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x8] by a write access --> $DIR/return_invalid_shr_tuple.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = note: BACKTRACE: - = note: inside `main` at $DIR/return_invalid_shr_tuple.rs:LL:CC + = note: inside `foo` at $DIR/return_invalid_shr_tuple.rs:LL:CC +note: inside `main` at $DIR/return_invalid_shr_tuple.rs:LL:CC + --> $DIR/return_invalid_shr_tuple.rs:LL:CC + | +LL | foo(&mut (1, 2)).0; + | ^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/pass/stacked-borrows/no_field_retagging.rs b/src/tools/miri/tests/pass/stacked-borrows/no_field_retagging.rs new file mode 100644 index 0000000000000..48fc8e8668ce0 --- /dev/null +++ b/src/tools/miri/tests/pass/stacked-borrows/no_field_retagging.rs @@ -0,0 +1,19 @@ +//@compile-flags: -Zmiri-retag-fields=none + +struct Newtype<'a>(&'a mut i32); + +fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { + dealloc(); +} + +// Make sure that we do *not* retag the fields of `Newtype`. +fn main() { + let ptr = Box::into_raw(Box::new(0i32)); + #[rustfmt::skip] // I like my newlines + unsafe { + dealloc_while_running( + Newtype(&mut *ptr), + || drop(Box::from_raw(ptr)), + ) + }; +} diff --git a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout index 838733078209d..296339e738455 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout +++ b/src/tools/miri/tests/pass/stacked-borrows/stack-printing.stdout @@ -1,6 +1,6 @@ 0..1: [ SharedReadWrite ] 0..1: [ SharedReadWrite ] 0..1: [ SharedReadWrite ] -0..1: [ SharedReadWrite Unique Unique Unique Unique Unique ] -0..1: [ SharedReadWrite Disabled Disabled Disabled Disabled Disabled SharedReadOnly ] +0..1: [ SharedReadWrite Unique Unique Unique Unique Unique Unique Unique ] +0..1: [ SharedReadWrite Disabled Disabled Disabled Disabled Disabled Disabled Disabled SharedReadOnly ] 0..1: [ unknown-bottom(..) ] From b18fe3d567297297a518dfbb9efb025fdb0f4799 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Oct 2022 09:10:45 +0100 Subject: [PATCH 459/482] rustup --- src/tools/miri/miri | 2 +- src/tools/miri/rust-version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 52902410a6b2d..a0593deb08a37 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -121,7 +121,7 @@ toolchain) rustc-pull) cd "$MIRIDIR" git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master - git merge FETCH_HEAD + git merge FETCH_HEAD --no-ff -m "Merge from rustc" exit 0 ;; rustc-push) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index e582bf35356d6..13492d183c999 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -607878d069267e1402ad792c9331b426e4c6d0f9 +b03502b35d111bef0399a66ab3cc765f0802e8ba From d42bad515ddd754f76ce524931f8edb6f86d3cd3 Mon Sep 17 00:00:00 2001 From: Rageking8 Date: Mon, 31 Oct 2022 12:41:26 +0800 Subject: [PATCH 460/482] fix dupe word typos --- src/tools/miri/cargo-miri/src/phases.rs | 2 +- src/tools/miri/src/stacked_borrows/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 22da80be90211..2c84165a0f0a1 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -528,7 +528,7 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner cmd.args(binary_args); // Make sure we use the build-time working directory for interpreting Miri/rustc arguments. - // But then we need to switch to the run-time one, which we instruct Miri do do by setting `MIRI_CWD`. + // But then we need to switch to the run-time one, which we instruct Miri do by setting `MIRI_CWD`. cmd.current_dir(info.current_dir); cmd.env("MIRI_CWD", env::current_dir().unwrap()); diff --git a/src/tools/miri/src/stacked_borrows/mod.rs b/src/tools/miri/src/stacked_borrows/mod.rs index 5ec787dd44113..7f18e5dbae052 100644 --- a/src/tools/miri/src/stacked_borrows/mod.rs +++ b/src/tools/miri/src/stacked_borrows/mod.rs @@ -252,7 +252,7 @@ pub fn err_sb_ub<'tcx>( /// We need to make at least the following things true: /// /// U1: After creating a `Uniq`, it is at the top. -/// U2: If the top is `Uniq`, accesses must be through that `Uniq` or remove it it. +/// U2: If the top is `Uniq`, accesses must be through that `Uniq` or remove it. /// U3: If an access happens with a `Uniq`, it requires the `Uniq` to be in the stack. /// /// F1: After creating a `&`, the parts outside `UnsafeCell` have our `SharedReadOnly` on top. From 34eebdb0b39f949c9fca4b59a64c402cafe7a4e9 Mon Sep 17 00:00:00 2001 From: Rageking8 Date: Mon, 31 Oct 2022 15:56:48 +0800 Subject: [PATCH 461/482] followup for pr 2640 --- src/tools/miri/cargo-miri/src/phases.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 2c84165a0f0a1..df36041c75ed3 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -528,7 +528,7 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner cmd.args(binary_args); // Make sure we use the build-time working directory for interpreting Miri/rustc arguments. - // But then we need to switch to the run-time one, which we instruct Miri do by setting `MIRI_CWD`. + // But then we need to switch to the run-time one, which we instruct Miri to do by setting `MIRI_CWD`. cmd.current_dir(info.current_dir); cmd.env("MIRI_CWD", env::current_dir().unwrap()); From 37107e53ed6d454c1170246b2a4ddc0a823c6065 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 2 Nov 2022 08:43:53 +0100 Subject: [PATCH 462/482] fix ./miri bench --- src/tools/miri/miri | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/miri b/src/tools/miri/miri index a0593deb08a37..f0986bfb1cdbe 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -79,6 +79,8 @@ shift MIRIDIR=$(python3 -c 'import os, sys; print(os.path.dirname(os.path.realpath(sys.argv[1])))' "$0") # Used for rustc syncs. JOSH_FILTER=":at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri" +# Needed for `./miri bench`. +TOOLCHAIN=$(cd "$MIRIDIR"; rustup show active-toolchain | head -n 1 | cut -d ' ' -f 1) ## Early commands, that don't do auto-things and don't want the environment-altering things happening below. case "$COMMAND" in @@ -189,6 +191,8 @@ if [ -z "$MIRI_AUTO_OPS" ]; then # other code has run. if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-toolchain" ] ; then $0 toolchain + # Let's make sure to actually use that toolchain, too. + TOOLCHAIN=miri fi if [ -f "$MIRIDIR/.auto-everything" ] || [ -f "$MIRIDIR/.auto-fmt" ] ; then @@ -202,7 +206,6 @@ fi ## Prepare the environment # Determine some toolchain properties -TOOLCHAIN=$(cd "$MIRIDIR"; rustup show active-toolchain | head -n 1 | cut -d ' ' -f 1) TARGET=$(rustc +$TOOLCHAIN --version --verbose | grep "^host:" | cut -d ' ' -f 2) SYSROOT=$(rustc +$TOOLCHAIN --print sysroot) LIBDIR=$SYSROOT/lib/rustlib/$TARGET/lib From f2af03bd39cbe522951d638c00e6da4ddb70bcfa Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sun, 30 Oct 2022 21:39:16 -0700 Subject: [PATCH 463/482] add acquire when init once is already complete --- src/tools/miri/src/concurrency/init_once.rs | 35 +++++++++-------- src/tools/miri/src/shims/windows/sync.rs | 6 ++- .../pass/concurrency/windows_init_once.rs | 38 +++++++++++++++++++ 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index 791931901e2a9..b1443662e2b7f 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -141,18 +141,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Wake up everyone. // need to take the queue to avoid having `this` be borrowed multiple times for waiter in std::mem::take(&mut init_once.waiters) { - // End of the wait happens-before woken-up thread. - if let Some(data_race) = &this.machine.data_race { - data_race.validate_lock_acquire( - &this.machine.threads.sync.init_onces[id].data_race, - waiter.thread, - ); - } - this.unblock_thread(waiter.thread); // Call callback, with the woken-up thread as `current`. this.set_active_thread(waiter.thread); + this.init_once_acquire(id); waiter.callback.call(this)?; this.set_active_thread(current_thread); } @@ -172,26 +165,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ); // Each complete happens-before the end of the wait - // FIXME: should this really induce synchronization? If we think of it as a lock, then yes, - // but the docs don't talk about such details. if let Some(data_race) = &this.machine.data_race { data_race.validate_lock_release(&mut init_once.data_race, current_thread); } // Wake up one waiting thread, so they can go ahead and try to init this. if let Some(waiter) = init_once.waiters.pop_front() { - // End of the wait happens-before woken-up thread. - if let Some(data_race) = &this.machine.data_race { - data_race.validate_lock_acquire( - &this.machine.threads.sync.init_onces[id].data_race, - waiter.thread, - ); - } - this.unblock_thread(waiter.thread); // Call callback, with the woken-up thread as `current`. this.set_active_thread(waiter.thread); + this.init_once_acquire(id); waiter.callback.call(this)?; this.set_active_thread(current_thread); } else { @@ -201,4 +185,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } + + /// Synchronize with the previous completion or failure of an InitOnce. + /// This is required to prevent data races. + #[inline] + fn init_once_acquire(&mut self, id: InitOnceId) { + let this = self.eval_context_mut(); + let current_thread = this.get_active_thread(); + + if let Some(data_race) = &this.machine.data_race { + data_race.validate_lock_acquire( + &this.machine.threads.sync.init_onces[id].data_race, + current_thread, + ); + } + } } diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 8156ae8af1ef1..f8980e188b45b 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -177,8 +177,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Box::new(Callback { init_once_id: id, pending_place }), ) } - InitOnceStatus::Complete => - this.write_scalar(this.eval_windows("c", "FALSE")?, &pending_place)?, + InitOnceStatus::Complete => { + this.init_once_acquire(id); + this.write_scalar(this.eval_windows("c", "FALSE")?, &pending_place)?; + } } // This always succeeds (even if the thread is blocked, we will succeed if we ever unblock). diff --git a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs index d3c72c3d028cf..6e5129acaf853 100644 --- a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs +++ b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs @@ -131,8 +131,46 @@ fn retry_on_fail() { waiter2.join().unwrap(); } +fn no_data_race_after_complete() { + let mut init_once = null_mut(); + let mut pending = 0; + + unsafe { + assert_eq!(InitOnceBeginInitialize(&mut init_once, 0, &mut pending, null_mut()), TRUE); + assert_eq!(pending, TRUE); + } + + let init_once_ptr = SendPtr(&mut init_once); + + let mut place = 0; + let place_ptr = SendPtr(&mut place); + + let reader = thread::spawn(move || unsafe { + let mut pending = 0; + + assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE); + assert_eq!(pending, FALSE); + // this should not data race + place_ptr.0.read() + }); + + unsafe { + // this should not data race + place_ptr.0.write(1); + } + + unsafe { + assert_eq!(InitOnceComplete(init_once_ptr.0, 0, null_mut()), TRUE); + } + //println!("complete"); + + // run reader + assert_eq!(reader.join().unwrap(), 1); +} + fn main() { single_thread(); block_until_complete(); retry_on_fail(); + no_data_race_after_complete(); } From b7c28581f27fbcc9e59b0cd4e8b797e6c8b16250 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:13:53 -0700 Subject: [PATCH 464/482] refactor into private functions --- src/tools/miri/src/concurrency/init_once.rs | 75 ++++++++++++++------- src/tools/miri/src/shims/windows/sync.rs | 2 +- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index b1443662e2b7f..eb42cdf80abbe 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -3,7 +3,7 @@ use std::num::NonZeroU32; use rustc_index::vec::Idx; -use super::sync::EvalContextExtPriv; +use super::sync::EvalContextExtPriv as _; use super::thread::MachineCallback; use super::vector_clock::VClock; use crate::*; @@ -52,6 +52,43 @@ impl<'mir, 'tcx> VisitTags for InitOnce<'mir, 'tcx> { } } +impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { + /// Synchronize with the previous initialization attempt of an InitOnce. + #[inline] + fn init_once_observe_attempt(&mut self, id: InitOnceId) { + let this = self.eval_context_mut(); + let current_thread = this.get_active_thread(); + + if let Some(data_race) = &this.machine.data_race { + data_race.validate_lock_acquire( + &this.machine.threads.sync.init_onces[id].data_race, + current_thread, + ); + } + } + + #[inline] + fn init_once_wake_waiter( + &mut self, + id: InitOnceId, + waiter: InitOnceWaiter<'mir, 'tcx>, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + let current_thread = this.get_active_thread(); + + this.unblock_thread(waiter.thread); + + // Call callback, with the woken-up thread as `current`. + this.set_active_thread(waiter.thread); + this.init_once_observe_attempt(id); + waiter.callback.call(this)?; + this.set_active_thread(current_thread); + + Ok(()) + } +} + impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn init_once_get_or_create_id( @@ -141,13 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Wake up everyone. // need to take the queue to avoid having `this` be borrowed multiple times for waiter in std::mem::take(&mut init_once.waiters) { - this.unblock_thread(waiter.thread); - - // Call callback, with the woken-up thread as `current`. - this.set_active_thread(waiter.thread); - this.init_once_acquire(id); - waiter.callback.call(this)?; - this.set_active_thread(current_thread); + this.init_once_wake_waiter(id, waiter)?; } Ok(()) @@ -171,13 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Wake up one waiting thread, so they can go ahead and try to init this. if let Some(waiter) = init_once.waiters.pop_front() { - this.unblock_thread(waiter.thread); - - // Call callback, with the woken-up thread as `current`. - this.set_active_thread(waiter.thread); - this.init_once_acquire(id); - waiter.callback.call(this)?; - this.set_active_thread(current_thread); + this.init_once_wake_waiter(id, waiter)?; } else { // Nobody there to take this, so go back to 'uninit' init_once.status = InitOnceStatus::Uninitialized; @@ -186,18 +211,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } - /// Synchronize with the previous completion or failure of an InitOnce. - /// This is required to prevent data races. + /// Synchronize with the previous completion of an InitOnce. + /// Must only be called after checking that it is complete. #[inline] - fn init_once_acquire(&mut self, id: InitOnceId) { + fn init_once_observe_completed(&mut self, id: InitOnceId) { let this = self.eval_context_mut(); - let current_thread = this.get_active_thread(); - if let Some(data_race) = &this.machine.data_race { - data_race.validate_lock_acquire( - &this.machine.threads.sync.init_onces[id].data_race, - current_thread, - ); - } + assert_eq!( + this.init_once_status(id), + InitOnceStatus::Complete, + "observing the completion of incomplete init once" + ); + + this.init_once_observe_attempt(id); } } diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index f8980e188b45b..098804626f2f9 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -178,7 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) } InitOnceStatus::Complete => { - this.init_once_acquire(id); + this.init_once_observe_completed(id); this.write_scalar(this.eval_windows("c", "FALSE")?, &pending_place)?; } } From f1e6fe309e747a33399018ba2a9a80eb7b727034 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:30:04 -0700 Subject: [PATCH 465/482] clarify no_data_race_after_complete test --- src/tools/miri/tests/pass/concurrency/windows_init_once.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs index 6e5129acaf853..4eb8837962059 100644 --- a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs +++ b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs @@ -148,6 +148,7 @@ fn no_data_race_after_complete() { let reader = thread::spawn(move || unsafe { let mut pending = 0; + // this doesn't block because reader only executes after `InitOnceComplete` is called assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE); assert_eq!(pending, FALSE); // this should not data race @@ -162,9 +163,8 @@ fn no_data_race_after_complete() { unsafe { assert_eq!(InitOnceComplete(init_once_ptr.0, 0, null_mut()), TRUE); } - //println!("complete"); - // run reader + // run reader (without preemption, it has not taken a step yet) assert_eq!(reader.join().unwrap(), 1); } From 39e5ce70257958a38a2e89a5bc7bfd329f603c7d Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sat, 29 Oct 2022 22:58:34 -0700 Subject: [PATCH 466/482] impl condvars for windows --- src/tools/miri/src/concurrency/sync.rs | 14 +- src/tools/miri/src/shims/unix/sync.rs | 14 +- .../miri/src/shims/windows/foreign_items.rs | 19 +++ src/tools/miri/src/shims/windows/sync.rs | 146 ++++++++++++++++++ src/tools/miri/tests/pass/concurrency/sync.rs | 20 +-- .../tests/pass/concurrency/sync_nopreempt.rs | 1 - .../miri/tests/pass/panic/concurrent-panic.rs | 1 - 7 files changed, 185 insertions(+), 30 deletions(-) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index e76610e730280..48f9e605276e9 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -121,8 +121,10 @@ declare_id!(CondvarId); struct CondvarWaiter { /// The thread that is waiting on this variable. thread: ThreadId, - /// The mutex on which the thread is waiting. - mutex: MutexId, + /// The mutex or rwlock on which the thread is waiting. + lock: u32, + /// If the lock is shared or exclusive + shared: bool, } /// The conditional variable state. @@ -569,16 +571,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } /// Mark that the thread is waiting on the conditional variable. - fn condvar_wait(&mut self, id: CondvarId, thread: ThreadId, mutex: MutexId) { + fn condvar_wait(&mut self, id: CondvarId, thread: ThreadId, lock: u32, shared: bool) { let this = self.eval_context_mut(); let waiters = &mut this.machine.threads.sync.condvars[id].waiters; assert!(waiters.iter().all(|waiter| waiter.thread != thread), "thread is already waiting"); - waiters.push_back(CondvarWaiter { thread, mutex }); + waiters.push_back(CondvarWaiter { thread, lock, shared }); } /// Wake up some thread (if there is any) sleeping on the conditional /// variable. - fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, MutexId)> { + fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, u32, bool)> { let this = self.eval_context_mut(); let current_thread = this.get_active_thread(); let condvar = &mut this.machine.threads.sync.condvars[id]; @@ -592,7 +594,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if let Some(data_race) = data_race { data_race.validate_lock_acquire(&condvar.data_race, waiter.thread); } - (waiter.thread, waiter.mutex) + (waiter.thread, waiter.lock, waiter.shared) }) } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index fcb006920794c..d24e1a56bd527 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -696,8 +696,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?; - if let Some((thread, mutex)) = this.condvar_signal(id) { - post_cond_signal(this, thread, mutex)?; + if let Some((thread, mutex, shared)) = this.condvar_signal(id) { + assert!(!shared); + post_cond_signal(this, thread, MutexId::from_u32(mutex))?; } Ok(0) @@ -710,8 +711,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?; - while let Some((thread, mutex)) = this.condvar_signal(id) { - post_cond_signal(this, thread, mutex)?; + while let Some((thread, mutex, shared)) = this.condvar_signal(id) { + assert!(!shared); + post_cond_signal(this, thread, MutexId::from_u32(mutex))?; } Ok(0) @@ -729,7 +731,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let active_thread = this.get_active_thread(); release_cond_mutex_and_block(this, active_thread, mutex_id)?; - this.condvar_wait(id, active_thread, mutex_id); + this.condvar_wait(id, active_thread, mutex_id.to_u32(), false); Ok(0) } @@ -768,7 +770,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; release_cond_mutex_and_block(this, active_thread, mutex_id)?; - this.condvar_wait(id, active_thread, mutex_id); + this.condvar_wait(id, active_thread, mutex_id.to_u32(), false); // We return success for now and override it in the timeout callback. this.write_scalar(Scalar::from_i32(0), dest)?; diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 2a34a3a47bbb5..e16749c986b16 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -273,6 +273,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } + "SleepConditionVariableSRW" => { + let [condvar, lock, timeout, flags] = + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + + let result = this.SleepConditionVariableSRW(condvar, lock, timeout, flags, dest)?; + this.write_scalar(result, dest)?; + } + "WakeConditionVariable" => { + let [condvar] = + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + + this.WakeConditionVariable(condvar)?; + } + "WakeAllConditionVariable" => { + let [condvar] = + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + + this.WakeAllConditionVariable(condvar)?; + } // Dynamic symbol loading "GetProcAddress" => { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 098804626f2f9..2eab1794c4f44 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -8,6 +8,38 @@ use crate::*; const SRWLOCK_ID_OFFSET: u64 = 0; const INIT_ONCE_ID_OFFSET: u64 = 0; +const CONDVAR_ID_OFFSET: u64 = 0; + +impl<'mir, 'tcx> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +pub trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { + /// Try to reacquire the lock associated with the condition variable after we + /// were signaled. + fn reacquire_cond_lock( + &mut self, + thread: ThreadId, + lock: RwLockId, + shared: bool, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + this.unblock_thread(thread); + + if shared { + if this.rwlock_is_locked(lock) { + this.rwlock_enqueue_and_block_reader(lock, thread); + } else { + this.rwlock_reader_lock(lock, thread); + } + } else { + if this.rwlock_is_write_locked(lock) { + this.rwlock_enqueue_and_block_writer(lock, thread); + } else { + this.rwlock_writer_lock(lock, thread); + } + } + + Ok(()) + } +} impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} #[allow(non_snake_case)] @@ -327,4 +359,118 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } + + fn SleepConditionVariableSRW( + &mut self, + condvar_op: &OpTy<'tcx, Provenance>, + lock_op: &OpTy<'tcx, Provenance>, + timeout_op: &OpTy<'tcx, Provenance>, + flags_op: &OpTy<'tcx, Provenance>, + dest: &PlaceTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, Scalar> { + let this = self.eval_context_mut(); + + let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?; + let lock_id = this.rwlock_get_or_create_id(lock_op, SRWLOCK_ID_OFFSET)?; + let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?; + let flags = this.read_scalar(flags_op)?.to_u32()?; + + let timeout_time = if timeout_ms == this.eval_windows("c", "INFINITE")?.to_u32()? { + None + } else { + let duration = Duration::from_millis(timeout_ms.into()); + Some(this.machine.clock.now().checked_add(duration).unwrap()) + }; + + let shared_mode = 0x1; // CONDITION_VARIABLE_LOCKMODE_SHARED is not in std + let shared = flags == shared_mode; + + let active_thread = this.get_active_thread(); + + let was_locked = if shared { + this.rwlock_reader_unlock(lock_id, active_thread) + } else { + this.rwlock_writer_unlock(lock_id, active_thread) + }; + + if !was_locked { + throw_ub_format!( + "calling SleepConditionVariableSRW with an SRWLock that is not locked by the current thread" + ); + } + + this.block_thread(active_thread); + this.condvar_wait(condvar_id, active_thread, lock_id.to_u32(), shared); + + if let Some(timeout_time) = timeout_time { + struct Callback<'tcx> { + thread: ThreadId, + condvar_id: CondvarId, + lock_id: RwLockId, + shared: bool, + dest: PlaceTy<'tcx, Provenance>, + } + + impl<'tcx> VisitTags for Callback<'tcx> { + fn visit_tags(&self, visit: &mut dyn FnMut(SbTag)) { + let Callback { thread: _, condvar_id: _, lock_id: _, shared: _, dest } = self; + dest.visit_tags(visit); + } + } + + impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> { + fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> { + this.reacquire_cond_lock(self.thread, self.lock_id, self.shared)?; + + this.condvar_remove_waiter(self.condvar_id, self.thread); + + let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT")?; + this.set_last_error(error_timeout)?; + this.write_scalar(this.eval_windows("c", "FALSE")?, &self.dest)?; + Ok(()) + } + } + + this.register_timeout_callback( + active_thread, + Time::Monotonic(timeout_time), + Box::new(Callback { + thread: active_thread, + condvar_id, + lock_id, + shared, + dest: dest.clone(), + }), + ); + } + + this.eval_windows("c", "TRUE") + } + + fn WakeConditionVariable(&mut self, condvar_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?; + + if let Some((thread, lock, shared)) = this.condvar_signal(condvar_id) { + this.reacquire_cond_lock(thread, RwLockId::from_u32(lock), shared)?; + this.unregister_timeout_callback_if_exists(thread); + } + + Ok(()) + } + + fn WakeAllConditionVariable( + &mut self, + condvar_op: &OpTy<'tcx, Provenance>, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?; + + while let Some((thread, lock, shared)) = this.condvar_signal(condvar_id) { + this.reacquire_cond_lock(thread, RwLockId::from_u32(lock), shared)?; + this.unregister_timeout_callback_if_exists(thread); + } + + Ok(()) + } } diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs index b1518a49fbb1b..19ea6c130bdd8 100644 --- a/src/tools/miri/tests/pass/concurrency/sync.rs +++ b/src/tools/miri/tests/pass/concurrency/sync.rs @@ -230,20 +230,8 @@ fn main() { check_once(); park_timeout(); park_unpark(); - - if !cfg!(windows) { - // ignore-target-windows: Condvars on Windows are not supported yet - check_barriers(); - check_conditional_variables_notify_one(); - check_conditional_variables_timed_wait_timeout(); - check_conditional_variables_timed_wait_notimeout(); - } else { - // We need to fake the same output... - for _ in 0..10 { - println!("before wait"); - } - for _ in 0..10 { - println!("after wait"); - } - } + check_barriers(); + check_conditional_variables_notify_one(); + check_conditional_variables_timed_wait_timeout(); + check_conditional_variables_timed_wait_notimeout(); } diff --git a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs index 55206f4bfc526..c6cff038f81e0 100644 --- a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs +++ b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs @@ -1,4 +1,3 @@ -//@ignore-target-windows: Condvars on Windows are not supported yet. // We are making scheduler assumptions here. //@compile-flags: -Zmiri-strict-provenance -Zmiri-preemption-rate=0 diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.rs b/src/tools/miri/tests/pass/panic/concurrent-panic.rs index 342269c6acbe3..776bc2057f350 100644 --- a/src/tools/miri/tests/pass/panic/concurrent-panic.rs +++ b/src/tools/miri/tests/pass/panic/concurrent-panic.rs @@ -1,4 +1,3 @@ -//@ignore-target-windows: Condvars on Windows are not supported yet. // We are making scheduler assumptions here. //@compile-flags: -Zmiri-preemption-rate=0 From 4d1fee8c52e4e169111eb896db705f62770500b3 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sun, 30 Oct 2022 14:56:49 -0700 Subject: [PATCH 467/482] use enum for condvar locks --- src/tools/miri/src/concurrency/sync.rs | 24 +++++--- src/tools/miri/src/shims/unix/sync.rs | 23 +++++--- src/tools/miri/src/shims/windows/sync.rs | 73 ++++++++++++++---------- 3 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 48f9e605276e9..ba5ae852c5a96 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -116,15 +116,25 @@ struct RwLock { declare_id!(CondvarId); +#[derive(Debug, Copy, Clone)] +pub enum RwLockMode { + Read, + Write, +} + +#[derive(Debug)] +pub enum CondvarLock { + Mutex(MutexId), + RwLock { id: RwLockId, mode: RwLockMode }, +} + /// A thread waiting on a conditional variable. #[derive(Debug)] struct CondvarWaiter { /// The thread that is waiting on this variable. thread: ThreadId, /// The mutex or rwlock on which the thread is waiting. - lock: u32, - /// If the lock is shared or exclusive - shared: bool, + lock: CondvarLock, } /// The conditional variable state. @@ -571,16 +581,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } /// Mark that the thread is waiting on the conditional variable. - fn condvar_wait(&mut self, id: CondvarId, thread: ThreadId, lock: u32, shared: bool) { + fn condvar_wait(&mut self, id: CondvarId, thread: ThreadId, lock: CondvarLock) { let this = self.eval_context_mut(); let waiters = &mut this.machine.threads.sync.condvars[id].waiters; assert!(waiters.iter().all(|waiter| waiter.thread != thread), "thread is already waiting"); - waiters.push_back(CondvarWaiter { thread, lock, shared }); + waiters.push_back(CondvarWaiter { thread, lock }); } /// Wake up some thread (if there is any) sleeping on the conditional /// variable. - fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, u32, bool)> { + fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, CondvarLock)> { let this = self.eval_context_mut(); let current_thread = this.get_active_thread(); let condvar = &mut this.machine.threads.sync.condvars[id]; @@ -594,7 +604,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { if let Some(data_race) = data_race { data_race.validate_lock_acquire(&condvar.data_race, waiter.thread); } - (waiter.thread, waiter.lock, waiter.shared) + (waiter.thread, waiter.lock) }) } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index d24e1a56bd527..a7275646847e2 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -3,6 +3,7 @@ use std::time::SystemTime; use rustc_hir::LangItem; use rustc_middle::ty::{layout::TyAndLayout, query::TyCtxtAt, Ty}; +use crate::concurrency::sync::CondvarLock; use crate::concurrency::thread::{MachineCallback, Time}; use crate::*; @@ -696,9 +697,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?; - if let Some((thread, mutex, shared)) = this.condvar_signal(id) { - assert!(!shared); - post_cond_signal(this, thread, MutexId::from_u32(mutex))?; + if let Some((thread, lock)) = this.condvar_signal(id) { + if let CondvarLock::Mutex(mutex) = lock { + post_cond_signal(this, thread, mutex)?; + } else { + panic!("condvar should not have an rwlock on unix"); + } } Ok(0) @@ -711,9 +715,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?; - while let Some((thread, mutex, shared)) = this.condvar_signal(id) { - assert!(!shared); - post_cond_signal(this, thread, MutexId::from_u32(mutex))?; + while let Some((thread, lock)) = this.condvar_signal(id) { + if let CondvarLock::Mutex(mutex) = lock { + post_cond_signal(this, thread, mutex)?; + } else { + panic!("condvar should not have an rwlock on unix"); + } } Ok(0) @@ -731,7 +738,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let active_thread = this.get_active_thread(); release_cond_mutex_and_block(this, active_thread, mutex_id)?; - this.condvar_wait(id, active_thread, mutex_id.to_u32(), false); + this.condvar_wait(id, active_thread, CondvarLock::Mutex(mutex_id)); Ok(0) } @@ -770,7 +777,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; release_cond_mutex_and_block(this, active_thread, mutex_id)?; - this.condvar_wait(id, active_thread, mutex_id.to_u32(), false); + this.condvar_wait(id, active_thread, CondvarLock::Mutex(mutex_id)); // We return success for now and override it in the timeout callback. this.write_scalar(Scalar::from_i32(0), dest)?; diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 2eab1794c4f44..a34d142f4a5ef 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -3,6 +3,7 @@ use std::time::Duration; use rustc_target::abi::Size; use crate::concurrency::init_once::InitOnceStatus; +use crate::concurrency::sync::{CondvarLock, RwLockMode}; use crate::concurrency::thread::MachineCallback; use crate::*; @@ -18,23 +19,24 @@ pub trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tc &mut self, thread: ThreadId, lock: RwLockId, - shared: bool, + mode: RwLockMode, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); this.unblock_thread(thread); - if shared { - if this.rwlock_is_locked(lock) { - this.rwlock_enqueue_and_block_reader(lock, thread); - } else { - this.rwlock_reader_lock(lock, thread); - } - } else { - if this.rwlock_is_write_locked(lock) { - this.rwlock_enqueue_and_block_writer(lock, thread); - } else { - this.rwlock_writer_lock(lock, thread); - } + match mode { + RwLockMode::Read => + if this.rwlock_is_locked(lock) { + this.rwlock_enqueue_and_block_reader(lock, thread); + } else { + this.rwlock_reader_lock(lock, thread); + }, + RwLockMode::Write => + if this.rwlock_is_write_locked(lock) { + this.rwlock_enqueue_and_block_writer(lock, thread); + } else { + this.rwlock_writer_lock(lock, thread); + }, } Ok(()) @@ -383,14 +385,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; let shared_mode = 0x1; // CONDITION_VARIABLE_LOCKMODE_SHARED is not in std - let shared = flags == shared_mode; + let mode = if flags == 0 { + RwLockMode::Write + } else if flags == shared_mode { + RwLockMode::Read + } else { + throw_unsup_format!("unsupported `Flags` {flags} in `SleepConditionVariableSRW`"); + }; let active_thread = this.get_active_thread(); - let was_locked = if shared { - this.rwlock_reader_unlock(lock_id, active_thread) - } else { - this.rwlock_writer_unlock(lock_id, active_thread) + let was_locked = match mode { + RwLockMode::Read => this.rwlock_reader_unlock(lock_id, active_thread), + RwLockMode::Write => this.rwlock_writer_unlock(lock_id, active_thread), }; if !was_locked { @@ -400,27 +407,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } this.block_thread(active_thread); - this.condvar_wait(condvar_id, active_thread, lock_id.to_u32(), shared); + this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, mode }); if let Some(timeout_time) = timeout_time { struct Callback<'tcx> { thread: ThreadId, condvar_id: CondvarId, lock_id: RwLockId, - shared: bool, + mode: RwLockMode, dest: PlaceTy<'tcx, Provenance>, } impl<'tcx> VisitTags for Callback<'tcx> { fn visit_tags(&self, visit: &mut dyn FnMut(SbTag)) { - let Callback { thread: _, condvar_id: _, lock_id: _, shared: _, dest } = self; + let Callback { thread: _, condvar_id: _, lock_id: _, mode: _, dest } = self; dest.visit_tags(visit); } } impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> { fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> { - this.reacquire_cond_lock(self.thread, self.lock_id, self.shared)?; + this.reacquire_cond_lock(self.thread, self.lock_id, self.mode)?; this.condvar_remove_waiter(self.condvar_id, self.thread); @@ -438,7 +445,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { thread: active_thread, condvar_id, lock_id, - shared, + mode, dest: dest.clone(), }), ); @@ -451,9 +458,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?; - if let Some((thread, lock, shared)) = this.condvar_signal(condvar_id) { - this.reacquire_cond_lock(thread, RwLockId::from_u32(lock), shared)?; - this.unregister_timeout_callback_if_exists(thread); + if let Some((thread, lock)) = this.condvar_signal(condvar_id) { + if let CondvarLock::RwLock { id, mode } = lock { + this.reacquire_cond_lock(thread, id, mode)?; + this.unregister_timeout_callback_if_exists(thread); + } else { + panic!("mutexes should not exist on windows"); + } } Ok(()) @@ -466,9 +477,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?; - while let Some((thread, lock, shared)) = this.condvar_signal(condvar_id) { - this.reacquire_cond_lock(thread, RwLockId::from_u32(lock), shared)?; - this.unregister_timeout_callback_if_exists(thread); + while let Some((thread, lock)) = this.condvar_signal(condvar_id) { + if let CondvarLock::RwLock { id, mode } = lock { + this.reacquire_cond_lock(thread, id, mode)?; + this.unregister_timeout_callback_if_exists(thread); + } else { + panic!("mutexes should not exist on windows"); + } } Ok(()) From 460e90c5318ad0a6e12b1c0cdc36c717a4ee105e Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:14:45 -0700 Subject: [PATCH 468/482] fix shared behavior and add tests --- src/tools/miri/src/shims/windows/sync.rs | 6 +- .../concurrency/windows_condvar_shared.rs | 227 ++++++++++++++++++ .../concurrency/windows_condvar_shared.stdout | 60 +++++ 3 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs create mode 100644 src/tools/miri/tests/pass/concurrency/windows_condvar_shared.stdout diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index a34d142f4a5ef..8f414d98dba5f 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -12,7 +12,7 @@ const INIT_ONCE_ID_OFFSET: u64 = 0; const CONDVAR_ID_OFFSET: u64 = 0; impl<'mir, 'tcx> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Try to reacquire the lock associated with the condition variable after we /// were signaled. fn reacquire_cond_lock( @@ -26,13 +26,13 @@ pub trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tc match mode { RwLockMode::Read => - if this.rwlock_is_locked(lock) { + if this.rwlock_is_write_locked(lock) { this.rwlock_enqueue_and_block_reader(lock, thread); } else { this.rwlock_reader_lock(lock, thread); }, RwLockMode::Write => - if this.rwlock_is_write_locked(lock) { + if this.rwlock_is_locked(lock) { this.rwlock_enqueue_and_block_writer(lock, thread); } else { this.rwlock_writer_lock(lock, thread); diff --git a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs new file mode 100644 index 0000000000000..d89320bfe5971 --- /dev/null +++ b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs @@ -0,0 +1,227 @@ +//@only-target-windows: Uses win32 api functions +// We are making scheduler assumptions here. +//@compile-flags: -Zmiri-preemption-rate=0 + +use std::ffi::c_void; +use std::ptr::null_mut; +use std::thread; + +#[derive(Copy, Clone)] +struct SendPtr(*mut T); + +unsafe impl Send for SendPtr {} + +extern "system" { + fn SleepConditionVariableSRW( + condvar: *mut *mut c_void, + lock: *mut *mut c_void, + timeout: u32, + flags: u32, + ) -> i32; + fn WakeAllConditionVariable(condvar: *mut *mut c_void); + + fn AcquireSRWLockExclusive(lock: *mut *mut c_void); + fn AcquireSRWLockShared(lock: *mut *mut c_void); + fn ReleaseSRWLockExclusive(lock: *mut *mut c_void); + fn ReleaseSRWLockShared(lock: *mut *mut c_void); +} + +const CONDITION_VARIABLE_LOCKMODE_SHARED: u32 = 1; +const INFINITE: u32 = u32::MAX; + +/// threads should be able to reacquire the lock while it is locked by multiple other threads in shared mode +fn all_shared() { + println!("all_shared"); + + let mut lock = null_mut(); + let mut condvar = null_mut(); + + let lock_ptr = SendPtr(&mut lock); + let condvar_ptr = SendPtr(&mut condvar); + + let mut handles = Vec::with_capacity(10); + + // waiters + for i in 0..5 { + handles.push(thread::spawn(move || { + unsafe { + AcquireSRWLockShared(lock_ptr.0); + } + println!("exclusive waiter {i} locked"); + + let r = unsafe { + SleepConditionVariableSRW( + condvar_ptr.0, + lock_ptr.0, + INFINITE, + CONDITION_VARIABLE_LOCKMODE_SHARED, + ) + }; + assert_ne!(r, 0); + + println!("exclusive waiter {i} reacquired lock"); + + // unlocking is unnecessary because the lock is never used again + })); + } + + // ensures each waiter is waiting by this point + thread::yield_now(); + + // readers + for i in 0..5 { + handles.push(thread::spawn(move || { + unsafe { + AcquireSRWLockShared(lock_ptr.0); + } + println!("reader {i} locked"); + + // switch to next reader or main thread + thread::yield_now(); + + unsafe { + ReleaseSRWLockShared(lock_ptr.0); + } + println!("reader {i} unlocked"); + })); + } + + // ensures each reader has acquired the lock + thread::yield_now(); + + unsafe { + WakeAllConditionVariable(condvar_ptr.0); + } + + for handle in handles { + handle.join().unwrap(); + } +} + +// reacquiring a lock should wait until the lock is not exclusively locked +fn shared_sleep_and_exclusive_lock() { + println!("shared_sleep_and_exclusive_lock"); + + let mut lock = null_mut(); + let mut condvar = null_mut(); + + let lock_ptr = SendPtr(&mut lock); + let condvar_ptr = SendPtr(&mut condvar); + + let mut waiters = Vec::with_capacity(5); + for i in 0..5 { + waiters.push(thread::spawn(move || { + unsafe { + AcquireSRWLockShared(lock_ptr.0); + } + println!("shared waiter {i} locked"); + + let r = unsafe { + SleepConditionVariableSRW( + condvar_ptr.0, + lock_ptr.0, + INFINITE, + CONDITION_VARIABLE_LOCKMODE_SHARED, + ) + }; + assert_ne!(r, 0); + + println!("shared waiter {i} reacquired lock"); + + // unlocking is unnecessary because the lock is never used again + })); + } + + // ensures each waiter is waiting by this point + thread::yield_now(); + + unsafe { + AcquireSRWLockExclusive(lock_ptr.0); + } + println!("main locked"); + + unsafe { + WakeAllConditionVariable(condvar_ptr.0); + } + + // waiters are now waiting for the lock to be unlocked + thread::yield_now(); + + unsafe { + ReleaseSRWLockExclusive(lock_ptr.0); + } + println!("main unlocked"); + + for handle in waiters { + handle.join().unwrap(); + } +} + +// threads reacquiring locks should wait for all locks to be released first +fn exclusive_sleep_and_shared_lock() { + println!("exclusive_sleep_and_shared_lock"); + + let mut lock = null_mut(); + let mut condvar = null_mut(); + + let lock_ptr = SendPtr(&mut lock); + let condvar_ptr = SendPtr(&mut condvar); + + let mut handles = Vec::with_capacity(10); + for i in 0..5 { + handles.push(thread::spawn(move || { + unsafe { + AcquireSRWLockExclusive(lock_ptr.0); + } + + println!("exclusive waiter {i} locked"); + + let r = unsafe { SleepConditionVariableSRW(condvar_ptr.0, lock_ptr.0, INFINITE, 0) }; + assert_ne!(r, 0); + + println!("exclusive waiter {i} reacquired lock"); + + // switch to next waiter or main thread + thread::yield_now(); + + unsafe { + ReleaseSRWLockExclusive(lock_ptr.0); + } + println!("exclusive waiter {i} unlocked"); + })); + } + + for i in 0..5 { + handles.push(thread::spawn(move || { + unsafe { + AcquireSRWLockShared(lock_ptr.0); + } + println!("reader {i} locked"); + + // switch to next reader or main thread + thread::yield_now(); + + unsafe { + ReleaseSRWLockShared(lock_ptr.0); + } + println!("reader {i} unlocked"); + })); + } + + // ensures each reader has acquired the lock + thread::yield_now(); + + unsafe { + WakeAllConditionVariable(condvar_ptr.0); + } + + for handle in handles { + handle.join().unwrap(); + } +} + +fn main() { + all_shared(); + shared_sleep_and_exclusive_lock(); + exclusive_sleep_and_shared_lock(); +} diff --git a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.stdout b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.stdout new file mode 100644 index 0000000000000..918b54668f201 --- /dev/null +++ b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.stdout @@ -0,0 +1,60 @@ +all_shared +exclusive waiter 0 locked +exclusive waiter 1 locked +exclusive waiter 2 locked +exclusive waiter 3 locked +exclusive waiter 4 locked +reader 0 locked +reader 1 locked +reader 2 locked +reader 3 locked +reader 4 locked +exclusive waiter 0 reacquired lock +exclusive waiter 1 reacquired lock +exclusive waiter 2 reacquired lock +exclusive waiter 3 reacquired lock +exclusive waiter 4 reacquired lock +reader 0 unlocked +reader 1 unlocked +reader 2 unlocked +reader 3 unlocked +reader 4 unlocked +shared_sleep_and_exclusive_lock +shared waiter 0 locked +shared waiter 1 locked +shared waiter 2 locked +shared waiter 3 locked +shared waiter 4 locked +main locked +main unlocked +shared waiter 0 reacquired lock +shared waiter 1 reacquired lock +shared waiter 2 reacquired lock +shared waiter 3 reacquired lock +shared waiter 4 reacquired lock +exclusive_sleep_and_shared_lock +exclusive waiter 0 locked +exclusive waiter 1 locked +exclusive waiter 2 locked +exclusive waiter 3 locked +exclusive waiter 4 locked +reader 0 locked +reader 1 locked +reader 2 locked +reader 3 locked +reader 4 locked +reader 0 unlocked +reader 1 unlocked +reader 2 unlocked +reader 3 unlocked +reader 4 unlocked +exclusive waiter 0 reacquired lock +exclusive waiter 0 unlocked +exclusive waiter 1 reacquired lock +exclusive waiter 1 unlocked +exclusive waiter 2 reacquired lock +exclusive waiter 2 unlocked +exclusive waiter 3 reacquired lock +exclusive waiter 3 unlocked +exclusive waiter 4 reacquired lock +exclusive waiter 4 unlocked From 327d2e1aacf7bf38168f802b3c7b691d05466809 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 7 Nov 2022 11:13:01 -0700 Subject: [PATCH 469/482] rustdoc: refactor `notable_traits_decl` to just act on the type directly --- src/librustdoc/html/render/mod.rs | 133 +++++++++++------------ src/librustdoc/html/render/print_item.rs | 7 +- 2 files changed, 72 insertions(+), 68 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 3a041ae15d618..881f107925315 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -861,7 +861,11 @@ fn assoc_method( name = name, generics = g.print(cx), decl = d.full_print(header_len, indent, cx), - notable_traits = notable_traits_decl(d, cx), + notable_traits = d + .output + .as_return() + .and_then(|output| notable_traits_decl(output, cx)) + .unwrap_or_default(), where_clause = print_where_clause(g, cx, indent, end_newline), ) } @@ -1273,71 +1277,64 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> } } -fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { +fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option { let mut out = Buffer::html(); - if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t))) + let did = ty.def_id(cx.cache())?; + + // Box has pass-through impls for Read, Write, Iterator, and Future when the + // boxed type implements one of those. We don't want to treat every Box return + // as being notably an Iterator (etc), though, so we exempt it. Pin has the same + // issue, with a pass-through impl for Future. + if Some(did) == cx.tcx().lang_items().owned_box() + || Some(did) == cx.tcx().lang_items().pin_type() { - // Box has pass-through impls for Read, Write, Iterator, and Future when the - // boxed type implements one of those. We don't want to treat every Box return - // as being notably an Iterator (etc), though, so we exempt it. Pin has the same - // issue, with a pass-through impl for Future. - if Some(did) == cx.tcx().lang_items().owned_box() - || Some(did) == cx.tcx().lang_items().pin_type() - { - return "".to_string(); - } - if let Some(impls) = cx.cache().impls.get(&did) { - for i in impls { - let impl_ = i.inner_impl(); - if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) - { - // Two different types might have the same did, - // without actually being the same. - continue; - } - if let Some(trait_) = &impl_.trait_ { - let trait_did = trait_.def_id(); - - if cx - .cache() - .traits - .get(&trait_did) - .map_or(false, |t| t.is_notable_trait(cx.tcx())) - { - if out.is_empty() { - write!( - &mut out, - "Notable traits for {}\ - ", - impl_.for_.print(cx) - ); - } + return None; + } + if let Some(impls) = cx.cache().impls.get(&did) { + for i in impls { + let impl_ = i.inner_impl(); + if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) { + // Two different types might have the same did, + // without actually being the same. + continue; + } + if let Some(trait_) = &impl_.trait_ { + let trait_did = trait_.def_id(); - //use the "where" class here to make it small + if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) + { + if out.is_empty() { write!( &mut out, - "{}", - impl_.print(false, cx) + "Notable traits for {}\ + ", + impl_.for_.print(cx) ); - for it in &impl_.items { - if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { - out.push_str(" "); - let empty_set = FxHashSet::default(); - let src_link = - AssocItemLink::GotoSource(trait_did.into(), &empty_set); - assoc_type( - &mut out, - it, - &tydef.generics, - &[], // intentionally leaving out bounds - Some(&tydef.type_), - src_link, - 0, - cx, - ); - out.push_str(";"); - } + } + + //use the "where" class here to make it small + write!( + &mut out, + "{}", + impl_.print(false, cx) + ); + for it in &impl_.items { + if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { + out.push_str(" "); + let empty_set = FxHashSet::default(); + let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set); + assoc_type( + &mut out, + it, + &tydef.generics, + &[], // intentionally leaving out bounds + Some(&tydef.type_), + src_link, + 0, + cx, + ); + out.push_str(";"); } } } @@ -1345,16 +1342,18 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { } } - if !out.is_empty() { - out.insert_str( - 0, - "ⓘ\ - ", - ); - out.push_str(""); + if out.is_empty() { + return None; } - out.into_inner() + out.insert_str( + 0, + "ⓘ\ + ", + ); + out.push_str(""); + + Some(out.into_inner()) } #[derive(Clone, Copy, Debug)] diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ce4fc4d68fac2..e6abd23eb951b 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -533,7 +533,12 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle generics = f.generics.print(cx), where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), decl = f.decl.full_print(header_len, 0, cx), - notable_traits = notable_traits_decl(&f.decl, cx), + notable_traits = f + .decl + .output + .as_return() + .and_then(|output| notable_traits_decl(output, cx)) + .unwrap_or_default(), ); }); }); From da9d28f8379d6d28d453440ceff004d64e79df69 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 7 Nov 2022 15:53:30 -0700 Subject: [PATCH 470/482] rustdoc: use javascript to layout notable traits popups Fixes #102576 --- src/librustdoc/html/format.rs | 4 - src/librustdoc/html/render/context.rs | 7 +- src/librustdoc/html/render/mod.rs | 145 ++++++++++++------ src/librustdoc/html/render/print_item.rs | 29 ++-- src/librustdoc/html/static/css/noscript.css | 6 + src/librustdoc/html/static/css/rustdoc.css | 23 +-- src/librustdoc/html/static/js/main.js | 85 +++++++++- src/test/rustdoc-gui/notable-trait.goml | 29 ++-- ...c-notable_trait-slice.bare_fn_matches.html | 1 + src/test/rustdoc/doc-notable_trait-slice.rs | 4 +- .../rustdoc/doc-notable_trait.bare-fn.html | 1 + src/test/rustdoc/doc-notable_trait.rs | 10 +- .../doc-notable_trait.some-struct-new.html | 1 + .../rustdoc/doc-notable_trait.wrap-me.html | 1 + .../spotlight-from-dependency.odd.html | 1 + src/test/rustdoc/spotlight-from-dependency.rs | 3 +- 16 files changed, 260 insertions(+), 90 deletions(-) create mode 100644 src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html create mode 100644 src/test/rustdoc/doc-notable_trait.bare-fn.html create mode 100644 src/test/rustdoc/doc-notable_trait.some-struct-new.html create mode 100644 src/test/rustdoc/doc-notable_trait.wrap-me.html create mode 100644 src/test/rustdoc/spotlight-from-dependency.odd.html diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a5c3d35b1b594..39e2a90222670 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -107,10 +107,6 @@ impl Buffer { self.buffer } - pub(crate) fn insert_str(&mut self, idx: usize, s: &str) { - self.buffer.insert_str(idx, s); - } - pub(crate) fn push_str(&mut self, s: &str) { self.buffer.push_str(s); } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 51843a505f709..73690c86f4f72 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -69,11 +69,13 @@ pub(crate) struct Context<'tcx> { /// the source files are present in the html rendering, then this will be /// `true`. pub(crate) include_sources: bool, + /// Collection of all types with notable traits referenced in the current module. + pub(crate) types_with_notable_traits: FxHashSet, } // `Context` is cloned a lot, so we don't want the size to grow unexpectedly. #[cfg(all(not(windows), target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Context<'_>, 128); +rustc_data_structures::static_assert_size!(Context<'_>, 160); /// Shared mutable state used in [`Context`] and elsewhere. pub(crate) struct SharedContext<'tcx> { @@ -532,6 +534,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { deref_id_map: FxHashMap::default(), shared: Rc::new(scx), include_sources, + types_with_notable_traits: FxHashSet::default(), }; if emit_crate { @@ -560,6 +563,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { id_map: IdMap::new(), shared: Rc::clone(&self.shared), include_sources: self.include_sources, + types_with_notable_traits: FxHashSet::default(), } } @@ -803,6 +807,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { } } } + Ok(()) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 881f107925315..1c13e2bf67781 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -59,7 +59,7 @@ use rustc_span::{ symbol::{sym, Symbol}, BytePos, FileName, RealFileName, }; -use serde::ser::SerializeSeq; +use serde::ser::{SerializeMap, SerializeSeq}; use serde::{Serialize, Serializer}; use crate::clean::{self, ItemId, RenderedLink, SelfTy}; @@ -803,7 +803,7 @@ fn assoc_method( d: &clean::FnDecl, link: AssocItemLink<'_>, parent: ItemType, - cx: &Context<'_>, + cx: &mut Context<'_>, render_mode: RenderMode, ) { let tcx = cx.tcx(); @@ -836,6 +836,8 @@ fn assoc_method( + name.as_str().len() + generics_len; + let notable_traits = d.output.as_return().and_then(|output| notable_traits_button(output, cx)); + let (indent, indent_str, end_newline) = if parent == ItemType::Trait { header_len += 4; let indent_str = " "; @@ -861,13 +863,9 @@ fn assoc_method( name = name, generics = g.print(cx), decl = d.full_print(header_len, indent, cx), - notable_traits = d - .output - .as_return() - .and_then(|output| notable_traits_decl(output, cx)) - .unwrap_or_default(), + notable_traits = notable_traits.unwrap_or_default(), where_clause = print_where_clause(g, cx, indent, end_newline), - ) + ); } /// Writes a span containing the versions at which an item became stable and/or const-stable. For @@ -967,7 +965,7 @@ fn render_assoc_item( item: &clean::Item, link: AssocItemLink<'_>, parent: ItemType, - cx: &Context<'_>, + cx: &mut Context<'_>, render_mode: RenderMode, ) { match &*item.kind { @@ -1277,8 +1275,8 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> } } -fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option { - let mut out = Buffer::html(); +pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> Option { + let mut has_notable_trait = false; let did = ty.def_id(cx.cache())?; @@ -1291,6 +1289,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option { { return None; } + if let Some(impls) = cx.cache().impls.get(&did) { for i in impls { let impl_ = i.inner_impl(); @@ -1304,56 +1303,106 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> Option { if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) { - if out.is_empty() { - write!( - &mut out, - "Notable traits for {}\ - ", - impl_.for_.print(cx) - ); - } + has_notable_trait = true; + } + } + } + } + + if has_notable_trait { + cx.types_with_notable_traits.insert(ty.clone()); + Some(format!( + "\ + \ + ", + ty = ty.print(cx), + )) + } else { + None + } +} + +fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { + let mut out = Buffer::html(); + + let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this"); - //use the "where" class here to make it small + let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this"); + + for i in impls { + let impl_ = i.inner_impl(); + if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) { + // Two different types might have the same did, + // without actually being the same. + continue; + } + if let Some(trait_) = &impl_.trait_ { + let trait_did = trait_.def_id(); + + if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) { + if out.is_empty() { write!( &mut out, - "{}", - impl_.print(false, cx) + "

Notable traits for {}

\ +
",
+                        impl_.for_.print(cx)
                     );
-                    for it in &impl_.items {
-                        if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
-                            out.push_str("    ");
-                            let empty_set = FxHashSet::default();
-                            let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
-                            assoc_type(
-                                &mut out,
-                                it,
-                                &tydef.generics,
-                                &[], // intentionally leaving out bounds
-                                Some(&tydef.type_),
-                                src_link,
-                                0,
-                                cx,
-                            );
-                            out.push_str(";");
-                        }
+                }
+
+                //use the "where" class here to make it small
+                write!(
+                    &mut out,
+                    "{}",
+                    impl_.print(false, cx)
+                );
+                for it in &impl_.items {
+                    if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
+                        out.push_str("    ");
+                        let empty_set = FxHashSet::default();
+                        let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
+                        assoc_type(
+                            &mut out,
+                            it,
+                            &tydef.generics,
+                            &[], // intentionally leaving out bounds
+                            Some(&tydef.type_),
+                            src_link,
+                            0,
+                            cx,
+                        );
+                        out.push_str(";");
                     }
                 }
             }
         }
     }
-
     if out.is_empty() {
-        return None;
+        write!(&mut out, "
",); } - out.insert_str( - 0, - "ⓘ\ - ", - ); - out.push_str("
"); + (format!("{:#}", ty.print(cx)), out.into_inner()) +} - Some(out.into_inner()) +pub(crate) fn notable_traits_json<'a>( + tys: impl Iterator, + cx: &Context<'_>, +) -> String { + let mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect(); + struct NotableTraitsMap(Vec<(String, String)>); + impl Serialize for NotableTraitsMap { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(self.0.len()))?; + for item in &self.0 { + map.serialize_entry(&item.0, &item.1)?; + } + map.end() + } + } + serde_json::to_string(&NotableTraitsMap(mp)) + .expect("serialize (string, string) -> json object cannot fail") } #[derive(Clone, Copy, Debug)] diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index e6abd23eb951b..ac11a860a4f0b 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -17,9 +17,10 @@ use std::rc::Rc; use super::{ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, - item_ty_to_section, notable_traits_decl, render_all_impls, render_assoc_item, - render_assoc_items, render_attributes_in_code, render_attributes_in_pre, render_impl, - render_rightside, render_stability_since_raw, AssocItemLink, Context, ImplRenderingParameters, + item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, + render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre, + render_impl, render_rightside, render_stability_since_raw, AssocItemLink, Context, + ImplRenderingParameters, }; use crate::clean; use crate::config::ModuleSorting; @@ -183,6 +184,16 @@ pub(super) fn print_item( unreachable!(); } } + + // Render notable-traits.js used for all methods in this module. + if !cx.types_with_notable_traits.is_empty() { + write!( + buf, + r#""#, + notable_traits_json(cx.types_with_notable_traits.iter(), cx) + ); + cx.types_with_notable_traits.clear(); + } } /// For large structs, enums, unions, etc, determine whether to hide their fields @@ -516,6 +527,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle + name.as_str().len() + generics_len; + let notable_traits = + f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx)); + wrap_into_item_decl(w, |w| { wrap_item(w, "fn", |w| { render_attributes_in_pre(w, it, ""); @@ -533,16 +547,11 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle generics = f.generics.print(cx), where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), decl = f.decl.full_print(header_len, 0, cx), - notable_traits = f - .decl - .output - .as_return() - .and_then(|output| notable_traits_decl(output, cx)) - .unwrap_or_default(), + notable_traits = notable_traits.unwrap_or_default(), ); }); }); - document(w, cx, it, None, HeadingOffset::H2) + document(w, cx, it, None, HeadingOffset::H2); } fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) { diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 301f03a16427a..54e8b6561f34f 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -22,3 +22,9 @@ nav.sub { .source .sidebar { display: none; } + +.notable-traits { + /* layout requires javascript + https://github.com/rust-lang/rust/issues/102576 */ + display: none; +} diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 972ceb67e7648..6a068a3d243d9 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -183,6 +183,8 @@ h4.code-header { font-weight: 600; margin: 0; padding: 0; + /* position notable traits in mobile mode within the header */ + position: relative; } #crate-search, @@ -1278,13 +1280,12 @@ h3.variant { cursor: pointer; } -.notable-traits:hover .notable-traits-tooltiptext, -.notable-traits .notable-traits-tooltiptext.force-tooltip { +.notable-traits .notable-traits-tooltiptext { display: inline-block; + visibility: hidden; } -.notable-traits .notable-traits-tooltiptext { - display: none; +.notable-traits-tooltiptext { padding: 5px 3px 3px 3px; border-radius: 6px; margin-left: 5px; @@ -1302,22 +1303,26 @@ h3.variant { content: "\00a0\00a0\00a0"; } -.notable-traits .docblock { +.notable-traits-tooltiptext .docblock { margin: 0; } -.notable-traits .notable { - margin: 0; - margin-bottom: 13px; +.notable-traits-tooltiptext .notable { font-size: 1.1875rem; font-weight: 600; display: block; } -.notable-traits .docblock code.content { +.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code { + background: transparent; +} + +.notable-traits-tooltiptext .docblock pre.content { margin: 0; padding: 0; font-size: 1.25rem; + white-space: pre-wrap; + overflow: hidden; } .search-failed { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 1c84393cb4e6f..8c9d8bc34631a 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -790,6 +790,19 @@ function loadCss(cssUrl) { // we need to switch away from mobile mode and make the main content area scrollable. hideSidebar(); } + if (window.CURRENT_NOTABLE_ELEMENT) { + // As a workaround to the behavior of `contains: layout` used in doc togglers, the + // notable traits popup is positioned using javascript. + // + // This means when the window is resized, we need to redo the layout. + const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE; + const force_visible = base.NOTABLE_FORCE_VISIBLE; + hideNotable(); + if (force_visible) { + showNotable(base); + base.NOTABLE_FORCE_VISIBLE = true; + } + } }); function handleClick(id, f) { @@ -822,10 +835,78 @@ function loadCss(cssUrl) { }); }); + function showNotable(e) { + if (!window.NOTABLE_TRAITS) { + const data = document.getElementById("notable-traits-data"); + if (data) { + window.NOTABLE_TRAITS = JSON.parse(data.innerText); + } else { + throw new Error("showNotable() called on page without any notable traits!"); + } + } + if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) { + // Make this function idempotent. + return; + } + hideNotable(); + const ty = e.getAttribute("data-ty"); + const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0]; + const wrapper = document.createElement("div"); + wrapper.innerHTML = "
" + window.NOTABLE_TRAITS[ty] + "
"; + wrapper.className = "notable-traits-tooltiptext"; + tooltip.appendChild(wrapper); + const pos = wrapper.getBoundingClientRect(); + tooltip.removeChild(wrapper); + wrapper.style.top = (pos.top + window.scrollY) + "px"; + wrapper.style.left = (pos.left + window.scrollX) + "px"; + wrapper.style.width = pos.width + "px"; + document.documentElement.appendChild(wrapper); + window.CURRENT_NOTABLE_ELEMENT = wrapper; + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e; + wrapper.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) { + hideNotable(); + } + }; + } + + function hideNotable() { + if (window.CURRENT_NOTABLE_ELEMENT) { + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; + document.documentElement.removeChild(window.CURRENT_NOTABLE_ELEMENT); + window.CURRENT_NOTABLE_ELEMENT = null; + } + } + onEachLazy(document.getElementsByClassName("notable-traits"), e => { e.onclick = function() { - this.getElementsByClassName("notable-traits-tooltiptext")[0] - .classList.toggle("force-tooltip"); + this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true; + if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) { + hideNotable(); + } else { + showNotable(this); + } + }; + e.onpointerenter = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + showNotable(this); + }; + e.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!this.NOTABLE_FORCE_VISIBLE && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) { + hideNotable(); + } }; }); diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index efe0cb15f08a0..81d381ed1262d 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -25,22 +25,28 @@ assert-position: ( {"x": 951}, ) // The tooltip should be beside the `i` +// Also, clicking the tooltip should bring its text into the DOM +assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable-traits-tooltiptext']", 1) compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable-traits-tooltiptext']", {"y": 2} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable-traits-tooltiptext']", ("x") ) // The docblock should be flush with the border. assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']", + "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']", {"margin-left": "0px"} ) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//h1" +assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) // Now only the `i` should be on the next line. size: (1055, 600) @@ -98,26 +104,31 @@ assert-position: ( {"x": 289}, ) // The tooltip should be below `i` +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable-traits-tooltiptext']", 1) compare-elements-position-near-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable-traits-tooltiptext']", {"y": 2} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable-traits-tooltiptext']", ("x") ) compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']/parent::*", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", - {"x": 5} + "//*[@id='method.create_an_iterator_from_read']", + "//*[@class='notable-traits-tooltiptext']", + {"x": 10} ) // The docblock should be flush with the border. assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']", + "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']", {"margin-left": "0px"} ) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//h1" +assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) // Checking on very small mobile. The `i` should be on its own line. size: (365, 600) diff --git a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html new file mode 100644 index 0000000000000..6b58be7e6853e --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait-slice.rs b/src/test/rustdoc/doc-notable_trait-slice.rs index b0d414027216a..2411da8cd4549 100644 --- a/src/test/rustdoc/doc-notable_trait-slice.rs +++ b/src/test/rustdoc/doc-notable_trait-slice.rs @@ -8,13 +8,13 @@ pub struct OtherStruct; impl SomeTrait for &[SomeStruct] {} // @has doc_notable_trait_slice/fn.bare_fn_matches.html -// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]' +// @snapshot bare_fn_matches - '//script[@id="notable-traits-data"]' pub fn bare_fn_matches() -> &'static [SomeStruct] { &[] } // @has doc_notable_trait_slice/fn.bare_fn_no_matches.html -// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]' +// @count - '//script[@id="notable-traits-data"]' 0 pub fn bare_fn_no_matches() -> &'static [OtherStruct] { &[] } diff --git a/src/test/rustdoc/doc-notable_trait.bare-fn.html b/src/test/rustdoc/doc-notable_trait.bare-fn.html new file mode 100644 index 0000000000000..4e4a3f18f2498 --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.bare-fn.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.rs b/src/test/rustdoc/doc-notable_trait.rs index 58a24b855d6e2..1f2cd7181c3d4 100644 --- a/src/test/rustdoc/doc-notable_trait.rs +++ b/src/test/rustdoc/doc-notable_trait.rs @@ -9,7 +9,8 @@ impl SomeTrait for Wrapper {} #[doc(notable_trait)] pub trait SomeTrait { // @has doc_notable_trait/trait.SomeTrait.html - // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' + // @has - '//span[@class="notable-traits"]/@data-ty' 'Wrapper' + // @snapshot wrap-me - '//script[@id="notable-traits-data"]' fn wrap_me(self) -> Wrapper where Self: Sized { Wrapper { inner: self, @@ -22,15 +23,16 @@ impl SomeTrait for SomeStruct {} impl SomeStruct { // @has doc_notable_trait/struct.SomeStruct.html - // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' - // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' + // @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct' + // @snapshot some-struct-new - '//script[@id="notable-traits-data"]' pub fn new() -> SomeStruct { SomeStruct } } // @has doc_notable_trait/fn.bare_fn.html -// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' +// @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct' +// @snapshot bare-fn - '//script[@id="notable-traits-data"]' pub fn bare_fn() -> SomeStruct { SomeStruct } diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html new file mode 100644 index 0000000000000..a61e7c752e66d --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.wrap-me.html b/src/test/rustdoc/doc-notable_trait.wrap-me.html new file mode 100644 index 0000000000000..9a59d5edd12a8 --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.wrap-me.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/rustdoc/spotlight-from-dependency.odd.html b/src/test/rustdoc/spotlight-from-dependency.odd.html new file mode 100644 index 0000000000000..987a949af44b1 --- /dev/null +++ b/src/test/rustdoc/spotlight-from-dependency.odd.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/rustdoc/spotlight-from-dependency.rs b/src/test/rustdoc/spotlight-from-dependency.rs index 5245789212d8c..156aedca62b4e 100644 --- a/src/test/rustdoc/spotlight-from-dependency.rs +++ b/src/test/rustdoc/spotlight-from-dependency.rs @@ -3,7 +3,8 @@ use std::iter::Iterator; // @has foo/struct.Odd.html -// @has - '//*[@id="method.new"]//span[@class="notable-traits"]//code/span' 'impl Iterator for Odd' +// @has - '//*[@id="method.new"]//span[@class="notable-traits"]/@data-ty' 'Odd' +// @snapshot odd - '//script[@id="notable-traits-data"]' pub struct Odd { current: usize, } From 19e1c7b7c5669cb3262ef864cb9b599115c952af Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 7 Nov 2022 21:18:01 -0700 Subject: [PATCH 471/482] rustdoc: fix font color inheritance from body, and test --- src/librustdoc/html/static/js/main.js | 6 +- src/test/rustdoc-gui/notable-trait.goml | 73 +++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 8c9d8bc34631a..0426774e80d46 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -860,7 +860,8 @@ function loadCss(cssUrl) { wrapper.style.top = (pos.top + window.scrollY) + "px"; wrapper.style.left = (pos.left + window.scrollX) + "px"; wrapper.style.width = pos.width + "px"; - document.documentElement.appendChild(wrapper); + const body = document.getElementsByTagName("body")[0]; + body.appendChild(wrapper); window.CURRENT_NOTABLE_ELEMENT = wrapper; window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e; wrapper.onpointerleave = function(ev) { @@ -877,7 +878,8 @@ function loadCss(cssUrl) { function hideNotable() { if (window.CURRENT_NOTABLE_ELEMENT) { window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; - document.documentElement.removeChild(window.CURRENT_NOTABLE_ELEMENT); + const body = document.getElementsByTagName("body")[0]; + body.removeChild(window.CURRENT_NOTABLE_ELEMENT); window.CURRENT_NOTABLE_ELEMENT = null; } } diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index 81d381ed1262d..d8261d8dc902c 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -137,3 +137,76 @@ compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", ("y", "x"), ) + +// Now check the colors. +define-function: ( + "check-colors", + (theme, header_color, content_color, type_color, trait_color), + [ + ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"), + // This is needed to ensure that the text color is computed. + ("show-text", true), + + // Setting the theme. + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + // We reload the page so the local storage settings are being used. + ("reload"), + + ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"), + ("assert-count", (".notable-traits-tooltiptext", 1)), + + ("assert-css", ( + ".notable-traits-tooltiptext h3.notable", + {"color": |header_color|}, + ALL, + )), + ("assert-css", ( + ".notable-traits-tooltiptext pre.content", + {"color": |content_color|}, + ALL, + )), + ("assert-css", ( + ".notable-traits-tooltiptext pre.content a.struct", + {"color": |type_color|}, + ALL, + )), + ("assert-css", ( + ".notable-traits-tooltiptext pre.content a.trait", + {"color": |trait_color|}, + ALL, + )), + ] +) + +call-function: ( + "check-colors", + { + "theme": "ayu", + "content_color": "rgb(230, 225, 207)", + "header_color": "rgb(255, 255, 255)", + "type_color": "rgb(255, 160, 165)", + "trait_color": "rgb(57, 175, 215)", + }, +) + +call-function: ( + "check-colors", + { + "theme": "dark", + "content_color": "rgb(221, 221, 221)", + "header_color": "rgb(221, 221, 221)", + "type_color": "rgb(45, 191, 184)", + "trait_color": "rgb(183, 140, 242)", + }, +) + +call-function: ( + "check-colors", + { + "theme": "light", + "content_color": "rgb(0, 0, 0)", + "header_color": "rgb(0, 0, 0)", + "type_color": "rgb(173, 55, 138)", + "trait_color": "rgb(110, 79, 201)", + }, +) From cef1ac38e93cb5a93e0b5e379b73fae78093eb35 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 9 Nov 2022 13:55:52 -0700 Subject: [PATCH 472/482] rustdoc: sort output to make it deterministic --- src/librustdoc/html/render/mod.rs | 3 ++- src/test/rustdoc/doc-notable_trait.some-struct-new.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1c13e2bf67781..fffd90c51fad1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1387,7 +1387,8 @@ pub(crate) fn notable_traits_json<'a>( tys: impl Iterator, cx: &Context<'_>, ) -> String { - let mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect(); + let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect(); + mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2)); struct NotableTraitsMap(Vec<(String, String)>); impl Serialize for NotableTraitsMap { fn serialize(&self, serializer: S) -> Result diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html index a61e7c752e66d..c0fd9748fd371 100644 --- a/src/test/rustdoc/doc-notable_trait.some-struct-new.html +++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From ccbdd816aa02e84e65e242c2578537f02c5d0c16 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 11 Nov 2022 07:35:09 -0700 Subject: [PATCH 473/482] rustdoc: fix HTML validation failure by escaping `data-ty` --- src/librustdoc/html/render/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fffd90c51fad1..266ec2ac7ad73 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1312,10 +1312,10 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O if has_notable_trait { cx.types_with_notable_traits.insert(ty.clone()); Some(format!( - "\ + "\ \ ", - ty = ty.print(cx), + ty = Escape(&format!("{:#}", ty.print(cx))), )) } else { None From 8915da990aeb11a0c91d62b3ecb08b6769c3a359 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 18 Oct 2022 13:23:49 +0200 Subject: [PATCH 474/482] std: remove lock wrappers in `sys_common` --- library/std/src/sync/condvar.rs | 2 +- library/std/src/sync/mutex.rs | 16 +- library/std/src/sync/rwlock.rs | 12 +- library/std/src/sys/hermit/mod.rs | 6 +- library/std/src/sys/itron/condvar.rs | 9 +- library/std/src/sys/itron/mutex.rs | 6 +- library/std/src/sys/sgx/condvar.rs | 29 +-- library/std/src/sys/sgx/mutex.rs | 24 +-- library/std/src/sys/sgx/rwlock.rs | 78 ++++---- library/std/src/sys/sgx/rwlock/tests.rs | 16 +- library/std/src/sys/solid/rwlock.rs | 10 +- .../std/src/sys/unix/locks/fuchsia_mutex.rs | 18 +- .../std/src/sys/unix/locks/futex_condvar.rs | 6 +- library/std/src/sys/unix/locks/futex_mutex.rs | 6 +- .../std/src/sys/unix/locks/futex_rwlock.rs | 10 +- library/std/src/sys/unix/locks/mod.rs | 18 +- .../std/src/sys/unix/locks/pthread_condvar.rs | 179 +++++++++--------- .../std/src/sys/unix/locks/pthread_mutex.rs | 134 +++++++------ .../std/src/sys/unix/locks/pthread_rwlock.rs | 148 +++++++++------ .../std/src/sys/unsupported/locks/condvar.rs | 6 +- library/std/src/sys/unsupported/locks/mod.rs | 6 +- .../std/src/sys/unsupported/locks/mutex.rs | 6 +- .../std/src/sys/unsupported/locks/rwlock.rs | 10 +- library/std/src/sys/wasm/mod.rs | 6 +- library/std/src/sys/windows/locks/condvar.rs | 10 +- library/std/src/sys/windows/locks/mod.rs | 6 +- library/std/src/sys/windows/locks/mutex.rs | 13 +- library/std/src/sys/windows/locks/rwlock.rs | 18 +- library/std/src/sys_common/condvar.rs | 57 ------ library/std/src/sys_common/condvar/check.rs | 58 ------ library/std/src/sys_common/mod.rs | 3 - library/std/src/sys_common/mutex.rs | 50 ----- library/std/src/sys_common/remutex.rs | 10 +- library/std/src/sys_common/rwlock.rs | 71 ------- 34 files changed, 404 insertions(+), 653 deletions(-) delete mode 100644 library/std/src/sys_common/condvar.rs delete mode 100644 library/std/src/sys_common/condvar/check.rs delete mode 100644 library/std/src/sys_common/mutex.rs delete mode 100644 library/std/src/sys_common/rwlock.rs diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs index eb1e7135a6e41..76a1b4a2a86cd 100644 --- a/library/std/src/sync/condvar.rs +++ b/library/std/src/sync/condvar.rs @@ -3,7 +3,7 @@ mod tests; use crate::fmt; use crate::sync::{mutex, poison, LockResult, MutexGuard, PoisonError}; -use crate::sys_common::condvar as sys; +use crate::sys::locks as sys; use crate::time::{Duration, Instant}; /// A type indicating whether a timed wait on a condition variable returned diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index de851c8fbbed5..065045f442069 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -5,7 +5,7 @@ use crate::cell::UnsafeCell; use crate::fmt; use crate::ops::{Deref, DerefMut}; use crate::sync::{poison, LockResult, TryLockError, TryLockResult}; -use crate::sys_common::mutex as sys; +use crate::sys::locks as sys; /// A mutual exclusion primitive useful for protecting shared data /// @@ -163,7 +163,7 @@ use crate::sys_common::mutex as sys; #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Mutex")] pub struct Mutex { - inner: sys::MovableMutex, + inner: sys::Mutex, poison: poison::Flag, data: UnsafeCell, } @@ -217,11 +217,7 @@ impl Mutex { #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] #[inline] pub const fn new(t: T) -> Mutex { - Mutex { - inner: sys::MovableMutex::new(), - poison: poison::Flag::new(), - data: UnsafeCell::new(t), - } + Mutex { inner: sys::Mutex::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) } } } @@ -264,7 +260,7 @@ impl Mutex { #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> LockResult> { unsafe { - self.inner.raw_lock(); + self.inner.lock(); MutexGuard::new(self) } } @@ -526,7 +522,7 @@ impl Drop for MutexGuard<'_, T> { fn drop(&mut self) { unsafe { self.lock.poison.done(&self.poison); - self.lock.inner.raw_unlock(); + self.lock.inner.unlock(); } } } @@ -545,7 +541,7 @@ impl fmt::Display for MutexGuard<'_, T> { } } -pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::MovableMutex { +pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex { &guard.lock.inner } diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 8b387760768c5..7c409cb3e9776 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -6,7 +6,7 @@ use crate::fmt; use crate::ops::{Deref, DerefMut}; use crate::ptr::NonNull; use crate::sync::{poison, LockResult, TryLockError, TryLockResult}; -use crate::sys_common::rwlock as sys; +use crate::sys::locks as sys; /// A reader-writer lock /// @@ -78,7 +78,7 @@ use crate::sys_common::rwlock as sys; #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")] pub struct RwLock { - inner: sys::MovableRwLock, + inner: sys::RwLock, poison: poison::Flag, data: UnsafeCell, } @@ -109,7 +109,7 @@ pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { // `NonNull` is also covariant over `T`, just like we would have with `&T`. `NonNull` // is preferable over `const* T` to allow for niche optimization. data: NonNull, - inner_lock: &'a sys::MovableRwLock, + inner_lock: &'a sys::RwLock, } #[stable(feature = "rust1", since = "1.0.0")] @@ -158,11 +158,7 @@ impl RwLock { #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] #[inline] pub const fn new(t: T) -> RwLock { - RwLock { - inner: sys::MovableRwLock::new(), - poison: poison::Flag::new(), - data: UnsafeCell::new(t), - } + RwLock { inner: sys::RwLock::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) } } } diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index e6534df8938eb..6811fadb0188c 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -51,9 +51,9 @@ pub mod locks { mod futex_condvar; mod futex_mutex; mod futex_rwlock; - pub(crate) use futex_condvar::MovableCondvar; - pub(crate) use futex_mutex::{MovableMutex, Mutex}; - pub(crate) use futex_rwlock::{MovableRwLock, RwLock}; + pub(crate) use futex_condvar::Condvar; + pub(crate) use futex_mutex::Mutex; + pub(crate) use futex_rwlock::RwLock; } use crate::io::ErrorKind; diff --git a/library/std/src/sys/itron/condvar.rs b/library/std/src/sys/itron/condvar.rs index 008cd8fb1e392..f70aa434e4834 100644 --- a/library/std/src/sys/itron/condvar.rs +++ b/library/std/src/sys/itron/condvar.rs @@ -12,18 +12,13 @@ pub struct Condvar { unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} -pub type MovableCondvar = Condvar; - impl Condvar { #[inline] pub const fn new() -> Condvar { Condvar { waiters: SpinMutex::new(waiter_queue::WaiterQueue::new()) } } - #[inline] - pub unsafe fn init(&mut self) {} - - pub unsafe fn notify_one(&self) { + pub fn notify_one(&self) { self.waiters.with_locked(|waiters| { if let Some(task) = waiters.pop_front() { // Unpark the task @@ -39,7 +34,7 @@ impl Condvar { }); } - pub unsafe fn notify_all(&self) { + pub fn notify_all(&self) { self.waiters.with_locked(|waiters| { while let Some(task) = waiters.pop_front() { // Unpark the task diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs index 085662e6d44b8..f2eed8e771c40 100644 --- a/library/std/src/sys/itron/mutex.rs +++ b/library/std/src/sys/itron/mutex.rs @@ -11,8 +11,6 @@ pub struct Mutex { mtx: SpinIdOnceCell<()>, } -pub type MovableMutex = Mutex; - /// Create a mutex object. This function never panics. fn new_mtx() -> Result { ItronError::err_if_negative(unsafe { @@ -39,7 +37,7 @@ impl Mutex { } } - pub unsafe fn lock(&self) { + pub fn lock(&self) { let mtx = self.raw(); expect_success(unsafe { abi::loc_mtx(mtx) }, &"loc_mtx"); } @@ -49,7 +47,7 @@ impl Mutex { expect_success_aborting(unsafe { abi::unl_mtx(mtx) }, &"unl_mtx"); } - pub unsafe fn try_lock(&self) -> bool { + pub fn try_lock(&self) -> bool { let mtx = self.raw(); match unsafe { abi::ploc_mtx(mtx) } { abi::E_TMOUT => false, diff --git a/library/std/src/sys/sgx/condvar.rs b/library/std/src/sys/sgx/condvar.rs index 36534e0eff3fd..aa1174664aeb0 100644 --- a/library/std/src/sys/sgx/condvar.rs +++ b/library/std/src/sys/sgx/condvar.rs @@ -4,42 +4,43 @@ use crate::time::Duration; use super::waitqueue::{SpinMutex, WaitQueue, WaitVariable}; +/// FIXME: `UnsafeList` is not movable. +struct AllocatedCondvar(SpinMutex>); + pub struct Condvar { - inner: SpinMutex>, + inner: LazyBox, } -pub(crate) type MovableCondvar = LazyBox; - -impl LazyInit for Condvar { +impl LazyInit for AllocatedCondvar { fn init() -> Box { - Box::new(Self::new()) + Box::new(AllocatedCondvar(SpinMutex::new(WaitVariable::new(())))) } } impl Condvar { pub const fn new() -> Condvar { - Condvar { inner: SpinMutex::new(WaitVariable::new(())) } + Condvar { inner: LazyBox::new() } } #[inline] - pub unsafe fn notify_one(&self) { - let _ = WaitQueue::notify_one(self.inner.lock()); + pub fn notify_one(&self) { + let _ = WaitQueue::notify_one(self.inner.0.lock()); } #[inline] - pub unsafe fn notify_all(&self) { - let _ = WaitQueue::notify_all(self.inner.lock()); + pub fn notify_all(&self) { + let _ = WaitQueue::notify_all(self.inner.0.lock()); } pub unsafe fn wait(&self, mutex: &Mutex) { - let guard = self.inner.lock(); + let guard = self.inner.0.lock(); WaitQueue::wait(guard, || unsafe { mutex.unlock() }); - unsafe { mutex.lock() } + mutex.lock() } pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - let success = WaitQueue::wait_timeout(&self.inner, dur, || unsafe { mutex.unlock() }); - unsafe { mutex.lock() }; + let success = WaitQueue::wait_timeout(&self.inner.0, dur, || unsafe { mutex.unlock() }); + mutex.lock(); success } } diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs index aa747d56b0d3b..0dbf020ebe06a 100644 --- a/library/std/src/sys/sgx/mutex.rs +++ b/library/std/src/sys/sgx/mutex.rs @@ -1,28 +1,28 @@ use super::waitqueue::{try_lock_or_false, SpinMutex, WaitQueue, WaitVariable}; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; +/// FIXME: `UnsafeList` is not movable. +struct AllocatedMutex(SpinMutex>); + pub struct Mutex { - inner: SpinMutex>, + inner: LazyBox, } -// not movable: see UnsafeList implementation -pub(crate) type MovableMutex = LazyBox; - -impl LazyInit for Mutex { +impl LazyInit for AllocatedMutex { fn init() -> Box { - Box::new(Self::new()) + Box::new(AllocatedMutex(SpinMutex::new(WaitVariable::new(false)))) } } // Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28 impl Mutex { pub const fn new() -> Mutex { - Mutex { inner: SpinMutex::new(WaitVariable::new(false)) } + Mutex { inner: LazyBox::new() } } #[inline] - pub unsafe fn lock(&self) { - let mut guard = self.inner.lock(); + pub fn lock(&self) { + let mut guard = self.inner.0.lock(); if *guard.lock_var() { // Another thread has the lock, wait WaitQueue::wait(guard, || {}) @@ -35,7 +35,7 @@ impl Mutex { #[inline] pub unsafe fn unlock(&self) { - let guard = self.inner.lock(); + let guard = self.inner.0.lock(); if let Err(mut guard) = WaitQueue::notify_one(guard) { // No other waiters, unlock *guard.lock_var_mut() = false; @@ -45,8 +45,8 @@ impl Mutex { } #[inline] - pub unsafe fn try_lock(&self) -> bool { - let mut guard = try_lock_or_false!(self.inner); + pub fn try_lock(&self) -> bool { + let mut guard = try_lock_or_false!(self.inner.0); if *guard.lock_var() { // Another thread has the lock false diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs index a97fb9ab026f0..d89de18ca5ff8 100644 --- a/library/std/src/sys/sgx/rwlock.rs +++ b/library/std/src/sys/sgx/rwlock.rs @@ -7,42 +7,45 @@ use crate::sys_common::lazy_box::{LazyBox, LazyInit}; use super::waitqueue::{ try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, }; -use crate::mem; +use crate::alloc::Layout; -pub struct RwLock { +struct AllocatedRwLock { readers: SpinMutex>>, writer: SpinMutex>, } -pub(crate) type MovableRwLock = LazyBox; +pub struct RwLock { + inner: LazyBox, +} -impl LazyInit for RwLock { +impl LazyInit for AllocatedRwLock { fn init() -> Box { - Box::new(Self::new()) + Box::new(AllocatedRwLock { + readers: SpinMutex::new(WaitVariable::new(None)), + writer: SpinMutex::new(WaitVariable::new(false)), + }) } } -// Check at compile time that RwLock size matches C definition (see test_c_rwlock_initializer below) -// -// # Safety -// Never called, as it is a compile time check. -#[allow(dead_code)] -unsafe fn rw_lock_size_assert(r: RwLock) { - unsafe { mem::transmute::(r) }; -} +// Check at compile time that RwLock's size and alignment matches the C definition +// in libunwind (see also `test_c_rwlock_initializer` in `tests`). +const _: () = { + let rust = Layout::new::(); + let c = Layout::new::<*mut ()>(); + assert!(rust.size() == c.size()); + assert!(rust.align() == c.align()); +}; impl RwLock { pub const fn new() -> RwLock { - RwLock { - readers: SpinMutex::new(WaitVariable::new(None)), - writer: SpinMutex::new(WaitVariable::new(false)), - } + RwLock { inner: LazyBox::new() } } #[inline] - pub unsafe fn read(&self) { - let mut rguard = self.readers.lock(); - let wguard = self.writer.lock(); + pub fn read(&self) { + let lock = &*self.inner; + let mut rguard = lock.readers.lock(); + let wguard = lock.writer.lock(); if *wguard.lock_var() || !wguard.queue_empty() { // Another thread has or is waiting for the write lock, wait drop(wguard); @@ -57,8 +60,9 @@ impl RwLock { #[inline] pub unsafe fn try_read(&self) -> bool { - let mut rguard = try_lock_or_false!(self.readers); - let wguard = try_lock_or_false!(self.writer); + let lock = &*self.inner; + let mut rguard = try_lock_or_false!(lock.readers); + let wguard = try_lock_or_false!(lock.writer); if *wguard.lock_var() || !wguard.queue_empty() { // Another thread has or is waiting for the write lock false @@ -71,9 +75,10 @@ impl RwLock { } #[inline] - pub unsafe fn write(&self) { - let rguard = self.readers.lock(); - let mut wguard = self.writer.lock(); + pub fn write(&self) { + let lock = &*self.inner; + let rguard = lock.readers.lock(); + let mut wguard = lock.writer.lock(); if *wguard.lock_var() || rguard.lock_var().is_some() { // Another thread has the lock, wait drop(rguard); @@ -86,9 +91,10 @@ impl RwLock { } #[inline] - pub unsafe fn try_write(&self) -> bool { - let rguard = try_lock_or_false!(self.readers); - let mut wguard = try_lock_or_false!(self.writer); + pub fn try_write(&self) -> bool { + let lock = &*self.inner; + let rguard = try_lock_or_false!(lock.readers); + let mut wguard = try_lock_or_false!(lock.writer); if *wguard.lock_var() || rguard.lock_var().is_some() { // Another thread has the lock false @@ -122,8 +128,9 @@ impl RwLock { #[inline] pub unsafe fn read_unlock(&self) { - let rguard = self.readers.lock(); - let wguard = self.writer.lock(); + let lock = &*self.inner; + let rguard = lock.readers.lock(); + let wguard = lock.writer.lock(); unsafe { self.__read_unlock(rguard, wguard) }; } @@ -158,8 +165,9 @@ impl RwLock { #[inline] pub unsafe fn write_unlock(&self) { - let rguard = self.readers.lock(); - let wguard = self.writer.lock(); + let lock = &*self.inner; + let rguard = lock.readers.lock(); + let wguard = lock.writer.lock(); unsafe { self.__write_unlock(rguard, wguard) }; } @@ -167,8 +175,9 @@ impl RwLock { #[inline] #[cfg_attr(test, allow(dead_code))] unsafe fn unlock(&self) { - let rguard = self.readers.lock(); - let wguard = self.writer.lock(); + let lock = &*self.inner; + let rguard = lock.readers.lock(); + let wguard = lock.writer.lock(); if *wguard.lock_var() == true { unsafe { self.__write_unlock(rguard, wguard) }; } else { @@ -201,6 +210,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { unsafe { (*p).write() }; return 0; } + #[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { diff --git a/library/std/src/sys/sgx/rwlock/tests.rs b/library/std/src/sys/sgx/rwlock/tests.rs index 4799961154a47..5fd6670afd435 100644 --- a/library/std/src/sys/sgx/rwlock/tests.rs +++ b/library/std/src/sys/sgx/rwlock/tests.rs @@ -1,22 +1,12 @@ use super::*; +use crate::ptr; // Verify that the byte pattern libunwind uses to initialize an RwLock is // equivalent to the value of RwLock::new(). If the value changes, // `src/UnwindRustSgx.h` in libunwind needs to be changed too. #[test] fn test_c_rwlock_initializer() { - #[rustfmt::skip] - const C_RWLOCK_INIT: &[u8] = &[ - /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - ]; + const C_RWLOCK_INIT: *mut () = ptr::null_mut(); // For the test to work, we need the padding/unused bytes in RwLock to be // initialized as 0. In practice, this is the case with statics. @@ -26,6 +16,6 @@ fn test_c_rwlock_initializer() { // If the assertion fails, that not necessarily an issue with the value // of C_RWLOCK_INIT. It might just be an issue with the way padding // bytes are initialized in the test code. - assert_eq!(&crate::mem::transmute_copy::<_, [u8; 144]>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT); + assert_eq!(crate::mem::transmute_copy::<_, *mut ()>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT); }; } diff --git a/library/std/src/sys/solid/rwlock.rs b/library/std/src/sys/solid/rwlock.rs index 0a770cf03f2f5..ecb4eb83b9b05 100644 --- a/library/std/src/sys/solid/rwlock.rs +++ b/library/std/src/sys/solid/rwlock.rs @@ -12,8 +12,6 @@ pub struct RwLock { rwl: SpinIdOnceCell<()>, } -pub type MovableRwLock = RwLock; - // Safety: `num_readers` is protected by `mtx_num_readers` unsafe impl Send for RwLock {} unsafe impl Sync for RwLock {} @@ -37,13 +35,13 @@ impl RwLock { } #[inline] - pub unsafe fn read(&self) { + pub fn read(&self) { let rwl = self.raw(); expect_success(unsafe { abi::rwl_loc_rdl(rwl) }, &"rwl_loc_rdl"); } #[inline] - pub unsafe fn try_read(&self) -> bool { + pub fn try_read(&self) -> bool { let rwl = self.raw(); match unsafe { abi::rwl_ploc_rdl(rwl) } { abi::E_TMOUT => false, @@ -55,13 +53,13 @@ impl RwLock { } #[inline] - pub unsafe fn write(&self) { + pub fn write(&self) { let rwl = self.raw(); expect_success(unsafe { abi::rwl_loc_wrl(rwl) }, &"rwl_loc_wrl"); } #[inline] - pub unsafe fn try_write(&self) -> bool { + pub fn try_write(&self) -> bool { let rwl = self.raw(); match unsafe { abi::rwl_ploc_wrl(rwl) } { abi::E_TMOUT => false, diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs index 117611ce43f24..5d89e5a13fd36 100644 --- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -53,8 +53,6 @@ const CONTESTED_BIT: u32 = 1; // This can never be a valid `zx_handle_t`. const UNLOCKED: u32 = 0; -pub type MovableMutex = Mutex; - pub struct Mutex { futex: AtomicU32, } @@ -86,23 +84,27 @@ impl Mutex { } #[inline] - pub unsafe fn try_lock(&self) -> bool { - let thread_self = zx_thread_self(); + pub fn try_lock(&self) -> bool { + let thread_self = unsafe { zx_thread_self() }; self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok() } #[inline] - pub unsafe fn lock(&self) { - let thread_self = zx_thread_self(); + pub fn lock(&self) { + let thread_self = unsafe { zx_thread_self() }; if let Err(state) = self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed) { - self.lock_contested(state, thread_self); + unsafe { + self.lock_contested(state, thread_self); + } } } + /// # Safety + /// `thread_self` must be the handle for the current thread. #[cold] - fn lock_contested(&self, mut state: u32, thread_self: zx_handle_t) { + unsafe fn lock_contested(&self, mut state: u32, thread_self: zx_handle_t) { let owned_state = mark_contested(to_state(thread_self)); loop { // Mark the mutex as contested if it is not already. diff --git a/library/std/src/sys/unix/locks/futex_condvar.rs b/library/std/src/sys/unix/locks/futex_condvar.rs index c0576c17880e1..4bd65dd25c292 100644 --- a/library/std/src/sys/unix/locks/futex_condvar.rs +++ b/library/std/src/sys/unix/locks/futex_condvar.rs @@ -3,8 +3,6 @@ use crate::sync::atomic::{AtomicU32, Ordering::Relaxed}; use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; use crate::time::Duration; -pub type MovableCondvar = Condvar; - pub struct Condvar { // The value of this atomic is simply incremented on every notification. // This is used by `.wait()` to not miss any notifications after @@ -21,12 +19,12 @@ impl Condvar { // All the memory orderings here are `Relaxed`, // because synchronization is done by unlocking and locking the mutex. - pub unsafe fn notify_one(&self) { + pub fn notify_one(&self) { self.futex.fetch_add(1, Relaxed); futex_wake(&self.futex); } - pub unsafe fn notify_all(&self) { + pub fn notify_all(&self) { self.futex.fetch_add(1, Relaxed); futex_wake_all(&self.futex); } diff --git a/library/std/src/sys/unix/locks/futex_mutex.rs b/library/std/src/sys/unix/locks/futex_mutex.rs index 33b13dad4d65d..c01229586c302 100644 --- a/library/std/src/sys/unix/locks/futex_mutex.rs +++ b/library/std/src/sys/unix/locks/futex_mutex.rs @@ -4,8 +4,6 @@ use crate::sync::atomic::{ }; use crate::sys::futex::{futex_wait, futex_wake}; -pub type MovableMutex = Mutex; - pub struct Mutex { /// 0: unlocked /// 1: locked, no other threads waiting @@ -20,12 +18,12 @@ impl Mutex { } #[inline] - pub unsafe fn try_lock(&self) -> bool { + pub fn try_lock(&self) -> bool { self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_ok() } #[inline] - pub unsafe fn lock(&self) { + pub fn lock(&self) { if self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_err() { self.lock_contended(); } diff --git a/library/std/src/sys/unix/locks/futex_rwlock.rs b/library/std/src/sys/unix/locks/futex_rwlock.rs index 0cc92244ecad3..aa0de900238f5 100644 --- a/library/std/src/sys/unix/locks/futex_rwlock.rs +++ b/library/std/src/sys/unix/locks/futex_rwlock.rs @@ -4,8 +4,6 @@ use crate::sync::atomic::{ }; use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; -pub type MovableRwLock = RwLock; - pub struct RwLock { // The state consists of a 30-bit reader counter, a 'readers waiting' flag, and a 'writers waiting' flag. // Bits 0..30: @@ -70,14 +68,14 @@ impl RwLock { } #[inline] - pub unsafe fn try_read(&self) -> bool { + pub fn try_read(&self) -> bool { self.state .fetch_update(Acquire, Relaxed, |s| is_read_lockable(s).then(|| s + READ_LOCKED)) .is_ok() } #[inline] - pub unsafe fn read(&self) { + pub fn read(&self) { let state = self.state.load(Relaxed); if !is_read_lockable(state) || self @@ -144,14 +142,14 @@ impl RwLock { } #[inline] - pub unsafe fn try_write(&self) -> bool { + pub fn try_write(&self) -> bool { self.state .fetch_update(Acquire, Relaxed, |s| is_unlocked(s).then(|| s + WRITE_LOCKED)) .is_ok() } #[inline] - pub unsafe fn write(&self) { + pub fn write(&self) { if self.state.compare_exchange_weak(0, WRITE_LOCKED, Acquire, Relaxed).is_err() { self.write_contended(); } diff --git a/library/std/src/sys/unix/locks/mod.rs b/library/std/src/sys/unix/locks/mod.rs index 9bb314b7010a5..b2e0e49ad736d 100644 --- a/library/std/src/sys/unix/locks/mod.rs +++ b/library/std/src/sys/unix/locks/mod.rs @@ -10,22 +10,22 @@ cfg_if::cfg_if! { mod futex_mutex; mod futex_rwlock; mod futex_condvar; - pub(crate) use futex_mutex::{Mutex, MovableMutex}; - pub(crate) use futex_rwlock::MovableRwLock; - pub(crate) use futex_condvar::MovableCondvar; + pub(crate) use futex_mutex::Mutex; + pub(crate) use futex_rwlock::RwLock; + pub(crate) use futex_condvar::Condvar; } else if #[cfg(target_os = "fuchsia")] { mod fuchsia_mutex; mod futex_rwlock; mod futex_condvar; - pub(crate) use fuchsia_mutex::{Mutex, MovableMutex}; - pub(crate) use futex_rwlock::MovableRwLock; - pub(crate) use futex_condvar::MovableCondvar; + pub(crate) use fuchsia_mutex::Mutex; + pub(crate) use futex_rwlock::RwLock; + pub(crate) use futex_condvar::Condvar; } else { mod pthread_mutex; mod pthread_rwlock; mod pthread_condvar; - pub(crate) use pthread_mutex::{Mutex, MovableMutex}; - pub(crate) use pthread_rwlock::MovableRwLock; - pub(crate) use pthread_condvar::MovableCondvar; + pub(crate) use pthread_mutex::Mutex; + pub(crate) use pthread_rwlock::RwLock; + pub(crate) use pthread_condvar::Condvar; } } diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 4741c0c6736e3..1ddb09905db2c 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -1,17 +1,17 @@ use crate::cell::UnsafeCell; +use crate::ptr; +use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed}; use crate::sys::locks::{pthread_mutex, Mutex}; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; use crate::time::Duration; +struct AllocatedCondvar(UnsafeCell); + pub struct Condvar { - inner: UnsafeCell, + inner: LazyBox, + mutex: AtomicPtr, } -pub(crate) type MovableCondvar = LazyBox; - -unsafe impl Send for Condvar {} -unsafe impl Sync for Condvar {} - const TIMESPEC_MAX: libc::timespec = libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; @@ -19,81 +19,104 @@ fn saturating_cast_to_time_t(value: u64) -> libc::time_t { if value > ::MAX as u64 { ::MAX } else { value as libc::time_t } } -impl LazyInit for Condvar { +#[inline] +fn raw(c: &Condvar) -> *mut libc::pthread_cond_t { + c.inner.0.get() +} + +unsafe impl Send for AllocatedCondvar {} +unsafe impl Sync for AllocatedCondvar {} + +impl LazyInit for AllocatedCondvar { fn init() -> Box { - let mut condvar = Box::new(Self::new()); - unsafe { condvar.init() }; + let condvar = Box::new(AllocatedCondvar(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER))); + + cfg_if::cfg_if! { + if #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "watchos", + target_os = "l4re", + target_os = "android", + target_os = "redox" + ))] { + // `pthread_condattr_setclock` is unfortunately not supported on these platforms. + } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { + // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet + // So on that platform, init() should always be called + // Moreover, that platform does not have pthread_condattr_setclock support, + // hence that initialization should be skipped as well + // + // Similar story for the 3DS (horizon). + let r = unsafe { libc::pthread_cond_init(condvar.0.get(), crate::ptr::null()) }; + assert_eq!(r, 0); + } else { + use crate::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + let r = unsafe { libc::pthread_condattr_init(attr.as_mut_ptr()) }; + assert_eq!(r, 0); + let r = unsafe { libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC) }; + assert_eq!(r, 0); + let r = unsafe { libc::pthread_cond_init(condvar.0.get(), attr.as_ptr()) }; + assert_eq!(r, 0); + let r = unsafe { libc::pthread_condattr_destroy(attr.as_mut_ptr()) }; + assert_eq!(r, 0); + } + } + condvar } } -impl Condvar { - pub const fn new() -> Condvar { - // Might be moved and address is changing it is better to avoid - // initialization of potentially opaque OS data before it landed - Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) } +impl Drop for AllocatedCondvar { + #[inline] + fn drop(&mut self) { + let r = unsafe { libc::pthread_cond_destroy(self.0.get()) }; + if cfg!(target_os = "dragonfly") { + // On DragonFly pthread_cond_destroy() returns EINVAL if called on + // a condvar that was just initialized with + // libc::PTHREAD_COND_INITIALIZER. Once it is used or + // pthread_cond_init() is called, this behaviour no longer occurs. + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } } +} - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "l4re", - target_os = "android", - target_os = "redox" - ))] - unsafe fn init(&mut self) {} - - // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet - // So on that platform, init() should always be called - // Moreover, that platform does not have pthread_condattr_setclock support, - // hence that initialization should be skipped as well - // - // Similar story for the 3DS (horizon). - #[cfg(any(target_os = "espidf", target_os = "horizon"))] - unsafe fn init(&mut self) { - let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null()); - assert_eq!(r, 0); +impl Condvar { + pub const fn new() -> Condvar { + Condvar { inner: LazyBox::new(), mutex: AtomicPtr::new(ptr::null_mut()) } } - #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "l4re", - target_os = "android", - target_os = "redox", - target_os = "espidf", - target_os = "horizon" - )))] - unsafe fn init(&mut self) { - use crate::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - let r = libc::pthread_condattr_init(attr.as_mut_ptr()); - assert_eq!(r, 0); - let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC); - assert_eq!(r, 0); - let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr()); - assert_eq!(r, 0); - let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); - assert_eq!(r, 0); + #[inline] + fn verify(&self, mutex: *mut libc::pthread_mutex_t) { + // Relaxed is okay here because we never read through `self.addr`, and only use it to + // compare addresses. + match self.mutex.compare_exchange(ptr::null_mut(), mutex, Relaxed, Relaxed) { + Ok(_) => {} // Stored the address + Err(n) if n == mutex => {} // Lost a race to store the same address + _ => panic!("attempted to use a condition variable with two mutexes"), + } } #[inline] - pub unsafe fn notify_one(&self) { - let r = libc::pthread_cond_signal(self.inner.get()); + pub fn notify_one(&self) { + let r = unsafe { libc::pthread_cond_signal(raw(self)) }; debug_assert_eq!(r, 0); } #[inline] - pub unsafe fn notify_all(&self) { - let r = libc::pthread_cond_broadcast(self.inner.get()); + pub fn notify_all(&self) { + let r = unsafe { libc::pthread_cond_broadcast(raw(self)) }; debug_assert_eq!(r, 0); } #[inline] pub unsafe fn wait(&self, mutex: &Mutex) { - let r = libc::pthread_cond_wait(self.inner.get(), pthread_mutex::raw(mutex)); + let mutex = pthread_mutex::raw(mutex); + self.verify(mutex); + let r = libc::pthread_cond_wait(raw(self), mutex); debug_assert_eq!(r, 0); } @@ -112,6 +135,9 @@ impl Condvar { pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::mem; + let mutex = pthread_mutex::raw(mutex); + self.verify(mutex); + let mut now: libc::timespec = mem::zeroed(); let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now); assert_eq!(r, 0); @@ -127,7 +153,7 @@ impl Condvar { let timeout = sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX); - let r = libc::pthread_cond_timedwait(self.inner.get(), pthread_mutex::raw(mutex), &timeout); + let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); assert!(r == libc::ETIMEDOUT || r == 0); r == 0 } @@ -144,9 +170,11 @@ impl Condvar { target_os = "horizon" ))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { - use crate::ptr; use crate::time::Instant; + let mutex = pthread_mutex::raw(mutex); + self.verify(mutex); + // 1000 years let max_dur = Duration::from_secs(1000 * 365 * 86400); @@ -187,36 +215,11 @@ impl Condvar { .unwrap_or(TIMESPEC_MAX); // And wait! - let r = libc::pthread_cond_timedwait(self.inner.get(), pthread_mutex::raw(mutex), &timeout); + let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); debug_assert!(r == libc::ETIMEDOUT || r == 0); // ETIMEDOUT is not a totally reliable method of determining timeout due // to clock shifts, so do the check ourselves stable_now.elapsed() < dur } - - #[inline] - #[cfg(not(target_os = "dragonfly"))] - unsafe fn destroy(&mut self) { - let r = libc::pthread_cond_destroy(self.inner.get()); - debug_assert_eq!(r, 0); - } - - #[inline] - #[cfg(target_os = "dragonfly")] - unsafe fn destroy(&mut self) { - let r = libc::pthread_cond_destroy(self.inner.get()); - // On DragonFly pthread_cond_destroy() returns EINVAL if called on - // a condvar that was just initialized with - // libc::PTHREAD_COND_INITIALIZER. Once it is used or - // pthread_cond_init() is called, this behaviour no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); - } -} - -impl Drop for Condvar { - #[inline] - fn drop(&mut self) { - unsafe { self.destroy() }; - } } diff --git a/library/std/src/sys/unix/locks/pthread_mutex.rs b/library/std/src/sys/unix/locks/pthread_mutex.rs index 5964935ddb541..a1155a808aaf4 100644 --- a/library/std/src/sys/unix/locks/pthread_mutex.rs +++ b/library/std/src/sys/unix/locks/pthread_mutex.rs @@ -3,56 +3,24 @@ use crate::mem::{forget, MaybeUninit}; use crate::sys::cvt_nz; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; +struct AllocatedMutex(UnsafeCell); + pub struct Mutex { - inner: UnsafeCell, + inner: LazyBox, } -pub(crate) type MovableMutex = LazyBox; - #[inline] pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t { - m.inner.get() + m.inner.0.get() } -unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} +unsafe impl Send for AllocatedMutex {} +unsafe impl Sync for AllocatedMutex {} -impl LazyInit for Mutex { +impl LazyInit for AllocatedMutex { fn init() -> Box { - let mut mutex = Box::new(Self::new()); - unsafe { mutex.init() }; - mutex - } - - fn destroy(mutex: Box) { - // We're not allowed to pthread_mutex_destroy a locked mutex, - // so check first if it's unlocked. - if unsafe { mutex.try_lock() } { - unsafe { mutex.unlock() }; - drop(mutex); - } else { - // The mutex is locked. This happens if a MutexGuard is leaked. - // In this case, we just leak the Mutex too. - forget(mutex); - } - } - - fn cancel_init(_: Box) { - // In this case, we can just drop it without any checks, - // since it cannot have been locked yet. - } -} + let mutex = Box::new(AllocatedMutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))); -impl Mutex { - pub const fn new() -> Mutex { - // Might be moved to a different address, so it is better to avoid - // initialization of potentially opaque OS data before it landed. - // Be very careful using this newly constructed `Mutex`, reentrant - // locking is undefined behavior until `init` is called! - Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) } - } - #[inline] - unsafe fn init(&mut self) { // Issue #33770 // // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have @@ -77,49 +45,77 @@ impl Mutex { // references, we instead create the mutex with type // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to // re-lock it from the same thread, thus avoiding undefined behavior. - let mut attr = MaybeUninit::::uninit(); - cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap(); - let attr = PthreadMutexAttr(&mut attr); - cvt_nz(libc::pthread_mutexattr_settype(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL)) + unsafe { + let mut attr = MaybeUninit::::uninit(); + cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap(); + let attr = PthreadMutexAttr(&mut attr); + cvt_nz(libc::pthread_mutexattr_settype( + attr.0.as_mut_ptr(), + libc::PTHREAD_MUTEX_NORMAL, + )) .unwrap(); - cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap(); + cvt_nz(libc::pthread_mutex_init(mutex.0.get(), attr.0.as_ptr())).unwrap(); + } + + mutex } - #[inline] - pub unsafe fn lock(&self) { - let r = libc::pthread_mutex_lock(self.inner.get()); - debug_assert_eq!(r, 0); + + fn destroy(mutex: Box) { + // We're not allowed to pthread_mutex_destroy a locked mutex, + // so check first if it's unlocked. + if unsafe { libc::pthread_mutex_trylock(mutex.0.get()) == 0 } { + unsafe { libc::pthread_mutex_destroy(mutex.0.get()) }; + drop(mutex); + } else { + // The mutex is locked. This happens if a MutexGuard is leaked. + // In this case, we just leak the Mutex too. + forget(mutex); + } } + + fn cancel_init(_: Box) { + // In this case, we can just drop it without any checks, + // since it cannot have been locked yet. + } +} + +impl Drop for AllocatedMutex { #[inline] - pub unsafe fn unlock(&self) { - let r = libc::pthread_mutex_unlock(self.inner.get()); - debug_assert_eq!(r, 0); + fn drop(&mut self) { + let r = unsafe { libc::pthread_mutex_destroy(self.0.get()) }; + if cfg!(target_os = "dragonfly") { + // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a + // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. + // Once it is used (locked/unlocked) or pthread_mutex_init() is called, + // this behaviour no longer occurs. + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } } +} + +impl Mutex { #[inline] - pub unsafe fn try_lock(&self) -> bool { - libc::pthread_mutex_trylock(self.inner.get()) == 0 + pub const fn new() -> Mutex { + Mutex { inner: LazyBox::new() } } + #[inline] - #[cfg(not(target_os = "dragonfly"))] - unsafe fn destroy(&mut self) { - let r = libc::pthread_mutex_destroy(self.inner.get()); + pub unsafe fn lock(&self) { + let r = libc::pthread_mutex_lock(raw(self)); debug_assert_eq!(r, 0); } + #[inline] - #[cfg(target_os = "dragonfly")] - unsafe fn destroy(&mut self) { - let r = libc::pthread_mutex_destroy(self.inner.get()); - // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a - // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. - // Once it is used (locked/unlocked) or pthread_mutex_init() is called, - // this behaviour no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); + pub unsafe fn unlock(&self) { + let r = libc::pthread_mutex_unlock(raw(self)); + debug_assert_eq!(r, 0); } -} -impl Drop for Mutex { #[inline] - fn drop(&mut self) { - unsafe { self.destroy() }; + pub unsafe fn try_lock(&self) -> bool { + libc::pthread_mutex_trylock(raw(self)) == 0 } } diff --git a/library/std/src/sys/unix/locks/pthread_rwlock.rs b/library/std/src/sys/unix/locks/pthread_rwlock.rs index adfe2a88338f5..04662be9d8275 100644 --- a/library/std/src/sys/unix/locks/pthread_rwlock.rs +++ b/library/std/src/sys/unix/locks/pthread_rwlock.rs @@ -3,20 +3,26 @@ use crate::mem::forget; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; -pub struct RwLock { +struct AllocatedRwLock { inner: UnsafeCell, write_locked: UnsafeCell, // guarded by the `inner` RwLock num_readers: AtomicUsize, } -pub(crate) type MovableRwLock = LazyBox; +unsafe impl Send for AllocatedRwLock {} +unsafe impl Sync for AllocatedRwLock {} -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} +pub struct RwLock { + inner: LazyBox, +} -impl LazyInit for RwLock { +impl LazyInit for AllocatedRwLock { fn init() -> Box { - Box::new(Self::new()) + Box::new(AllocatedRwLock { + inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER), + write_locked: UnsafeCell::new(false), + num_readers: AtomicUsize::new(0), + }) } fn destroy(mut rwlock: Box) { @@ -35,17 +41,39 @@ impl LazyInit for RwLock { } } +impl AllocatedRwLock { + #[inline] + unsafe fn raw_unlock(&self) { + let r = libc::pthread_rwlock_unlock(self.inner.get()); + debug_assert_eq!(r, 0); + } +} + +impl Drop for AllocatedRwLock { + fn drop(&mut self) { + let r = unsafe { libc::pthread_rwlock_destroy(self.inner.get()) }; + // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a + // rwlock that was just initialized with + // libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked) + // or pthread_rwlock_init() is called, this behaviour no longer occurs. + if cfg!(target_os = "dragonfly") { + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } + } +} + impl RwLock { + #[inline] pub const fn new() -> RwLock { - RwLock { - inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER), - write_locked: UnsafeCell::new(false), - num_readers: AtomicUsize::new(0), - } + RwLock { inner: LazyBox::new() } } + #[inline] - pub unsafe fn read(&self) { - let r = libc::pthread_rwlock_rdlock(self.inner.get()); + pub fn read(&self) { + let lock = &*self.inner; + let r = unsafe { libc::pthread_rwlock_rdlock(lock.inner.get()) }; // According to POSIX, when a thread tries to acquire this read lock // while it already holds the write lock @@ -62,51 +90,61 @@ impl RwLock { // got the write lock more than once, or got a read and a write lock. if r == libc::EAGAIN { panic!("rwlock maximum reader count exceeded"); - } else if r == libc::EDEADLK || (r == 0 && *self.write_locked.get()) { + } else if r == libc::EDEADLK || (r == 0 && unsafe { *lock.write_locked.get() }) { // Above, we make sure to only access `write_locked` when `r == 0` to avoid // data races. if r == 0 { // `pthread_rwlock_rdlock` succeeded when it should not have. - self.raw_unlock(); + unsafe { + lock.raw_unlock(); + } } panic!("rwlock read lock would result in deadlock"); } else { // POSIX does not make guarantees about all the errors that may be returned. // See issue #94705 for more details. assert_eq!(r, 0, "unexpected error during rwlock read lock: {:?}", r); - self.num_readers.fetch_add(1, Ordering::Relaxed); + lock.num_readers.fetch_add(1, Ordering::Relaxed); } } + #[inline] - pub unsafe fn try_read(&self) -> bool { - let r = libc::pthread_rwlock_tryrdlock(self.inner.get()); + pub fn try_read(&self) -> bool { + let lock = &*self.inner; + let r = unsafe { libc::pthread_rwlock_tryrdlock(lock.inner.get()) }; if r == 0 { - if *self.write_locked.get() { + if unsafe { *lock.write_locked.get() } { // `pthread_rwlock_tryrdlock` succeeded when it should not have. - self.raw_unlock(); + unsafe { + lock.raw_unlock(); + } false } else { - self.num_readers.fetch_add(1, Ordering::Relaxed); + lock.num_readers.fetch_add(1, Ordering::Relaxed); true } } else { false } } + #[inline] - pub unsafe fn write(&self) { - let r = libc::pthread_rwlock_wrlock(self.inner.get()); + pub fn write(&self) { + let lock = &*self.inner; + let r = unsafe { libc::pthread_rwlock_wrlock(lock.inner.get()) }; // See comments above for why we check for EDEADLK and write_locked. For the same reason, // we also need to check that there are no readers (tracked in `num_readers`). if r == libc::EDEADLK - || (r == 0 && *self.write_locked.get()) - || self.num_readers.load(Ordering::Relaxed) != 0 + || (r == 0 && unsafe { *lock.write_locked.get() }) + || lock.num_readers.load(Ordering::Relaxed) != 0 { // Above, we make sure to only access `write_locked` when `r == 0` to avoid // data races. if r == 0 { // `pthread_rwlock_wrlock` succeeded when it should not have. - self.raw_unlock(); + unsafe { + lock.raw_unlock(); + } } panic!("rwlock write lock would result in deadlock"); } else { @@ -114,60 +152,44 @@ impl RwLock { // return EDEADLK or 0. We rely on that. debug_assert_eq!(r, 0); } - *self.write_locked.get() = true; + + unsafe { + *lock.write_locked.get() = true; + } } + #[inline] pub unsafe fn try_write(&self) -> bool { - let r = libc::pthread_rwlock_trywrlock(self.inner.get()); + let lock = &*self.inner; + let r = libc::pthread_rwlock_trywrlock(lock.inner.get()); if r == 0 { - if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 { + if *lock.write_locked.get() || lock.num_readers.load(Ordering::Relaxed) != 0 { // `pthread_rwlock_trywrlock` succeeded when it should not have. - self.raw_unlock(); + lock.raw_unlock(); false } else { - *self.write_locked.get() = true; + *lock.write_locked.get() = true; true } } else { false } } - #[inline] - unsafe fn raw_unlock(&self) { - let r = libc::pthread_rwlock_unlock(self.inner.get()); - debug_assert_eq!(r, 0); - } + #[inline] pub unsafe fn read_unlock(&self) { - debug_assert!(!*self.write_locked.get()); - self.num_readers.fetch_sub(1, Ordering::Relaxed); - self.raw_unlock(); - } - #[inline] - pub unsafe fn write_unlock(&self) { - debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0); - debug_assert!(*self.write_locked.get()); - *self.write_locked.get() = false; - self.raw_unlock(); + let lock = &*self.inner; + debug_assert!(!*lock.write_locked.get()); + lock.num_readers.fetch_sub(1, Ordering::Relaxed); + lock.raw_unlock(); } - #[inline] - unsafe fn destroy(&mut self) { - let r = libc::pthread_rwlock_destroy(self.inner.get()); - // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a - // rwlock that was just initialized with - // libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked) - // or pthread_rwlock_init() is called, this behaviour no longer occurs. - if cfg!(target_os = "dragonfly") { - debug_assert!(r == 0 || r == libc::EINVAL); - } else { - debug_assert_eq!(r, 0); - } - } -} -impl Drop for RwLock { #[inline] - fn drop(&mut self) { - unsafe { self.destroy() }; + pub unsafe fn write_unlock(&self) { + let lock = &*self.inner; + debug_assert_eq!(lock.num_readers.load(Ordering::Relaxed), 0); + debug_assert!(*lock.write_locked.get()); + *lock.write_locked.get() = false; + lock.raw_unlock(); } } diff --git a/library/std/src/sys/unsupported/locks/condvar.rs b/library/std/src/sys/unsupported/locks/condvar.rs index 527a26a12bcec..3f0943b50ee4d 100644 --- a/library/std/src/sys/unsupported/locks/condvar.rs +++ b/library/std/src/sys/unsupported/locks/condvar.rs @@ -3,8 +3,6 @@ use crate::time::Duration; pub struct Condvar {} -pub type MovableCondvar = Condvar; - impl Condvar { #[inline] #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] @@ -13,10 +11,10 @@ impl Condvar { } #[inline] - pub unsafe fn notify_one(&self) {} + pub fn notify_one(&self) {} #[inline] - pub unsafe fn notify_all(&self) {} + pub fn notify_all(&self) {} pub unsafe fn wait(&self, _mutex: &Mutex) { panic!("condvar wait not supported") diff --git a/library/std/src/sys/unsupported/locks/mod.rs b/library/std/src/sys/unsupported/locks/mod.rs index 602a2d6231a29..0e0f9eccb2137 100644 --- a/library/std/src/sys/unsupported/locks/mod.rs +++ b/library/std/src/sys/unsupported/locks/mod.rs @@ -1,6 +1,6 @@ mod condvar; mod mutex; mod rwlock; -pub use condvar::{Condvar, MovableCondvar}; -pub use mutex::{MovableMutex, Mutex}; -pub use rwlock::MovableRwLock; +pub use condvar::Condvar; +pub use mutex::Mutex; +pub use rwlock::RwLock; diff --git a/library/std/src/sys/unsupported/locks/mutex.rs b/library/std/src/sys/unsupported/locks/mutex.rs index 87ea475c6e3eb..4a13c55fb8bec 100644 --- a/library/std/src/sys/unsupported/locks/mutex.rs +++ b/library/std/src/sys/unsupported/locks/mutex.rs @@ -5,8 +5,6 @@ pub struct Mutex { locked: Cell, } -pub type MovableMutex = Mutex; - unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} // no threads on this platform @@ -18,7 +16,7 @@ impl Mutex { } #[inline] - pub unsafe fn lock(&self) { + pub fn lock(&self) { assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex"); } @@ -28,7 +26,7 @@ impl Mutex { } #[inline] - pub unsafe fn try_lock(&self) -> bool { + pub fn try_lock(&self) -> bool { self.locked.replace(true) == false } } diff --git a/library/std/src/sys/unsupported/locks/rwlock.rs b/library/std/src/sys/unsupported/locks/rwlock.rs index 5292691b95557..789ef9b29e52a 100644 --- a/library/std/src/sys/unsupported/locks/rwlock.rs +++ b/library/std/src/sys/unsupported/locks/rwlock.rs @@ -5,8 +5,6 @@ pub struct RwLock { mode: Cell, } -pub type MovableRwLock = RwLock; - unsafe impl Send for RwLock {} unsafe impl Sync for RwLock {} // no threads on this platform @@ -18,7 +16,7 @@ impl RwLock { } #[inline] - pub unsafe fn read(&self) { + pub fn read(&self) { let m = self.mode.get(); if m >= 0 { self.mode.set(m + 1); @@ -28,7 +26,7 @@ impl RwLock { } #[inline] - pub unsafe fn try_read(&self) -> bool { + pub fn try_read(&self) -> bool { let m = self.mode.get(); if m >= 0 { self.mode.set(m + 1); @@ -39,14 +37,14 @@ impl RwLock { } #[inline] - pub unsafe fn write(&self) { + pub fn write(&self) { if self.mode.replace(-1) != 0 { rtabort!("rwlock locked for reading") } } #[inline] - pub unsafe fn try_write(&self) -> bool { + pub fn try_write(&self) -> bool { if self.mode.get() == 0 { self.mode.set(-1); true diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 93838390bee6e..d68c3e5f1dfbf 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -55,9 +55,9 @@ cfg_if::cfg_if! { mod futex_condvar; mod futex_mutex; mod futex_rwlock; - pub(crate) use futex_condvar::{Condvar, MovableCondvar}; - pub(crate) use futex_mutex::{Mutex, MovableMutex}; - pub(crate) use futex_rwlock::MovableRwLock; + pub(crate) use futex_condvar::Condvar; + pub(crate) use futex_mutex::Mutex; + pub(crate) use futex_rwlock::RwLock; } #[path = "atomics/futex.rs"] pub mod futex; diff --git a/library/std/src/sys/windows/locks/condvar.rs b/library/std/src/sys/windows/locks/condvar.rs index be9a2abbe35d9..66fafa2c00b00 100644 --- a/library/std/src/sys/windows/locks/condvar.rs +++ b/library/std/src/sys/windows/locks/condvar.rs @@ -8,8 +8,6 @@ pub struct Condvar { inner: UnsafeCell, } -pub type MovableCondvar = Condvar; - unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} @@ -41,12 +39,12 @@ impl Condvar { } #[inline] - pub unsafe fn notify_one(&self) { - c::WakeConditionVariable(self.inner.get()) + pub fn notify_one(&self) { + unsafe { c::WakeConditionVariable(self.inner.get()) } } #[inline] - pub unsafe fn notify_all(&self) { - c::WakeAllConditionVariable(self.inner.get()) + pub fn notify_all(&self) { + unsafe { c::WakeAllConditionVariable(self.inner.get()) } } } diff --git a/library/std/src/sys/windows/locks/mod.rs b/library/std/src/sys/windows/locks/mod.rs index 602a2d6231a29..0e0f9eccb2137 100644 --- a/library/std/src/sys/windows/locks/mod.rs +++ b/library/std/src/sys/windows/locks/mod.rs @@ -1,6 +1,6 @@ mod condvar; mod mutex; mod rwlock; -pub use condvar::{Condvar, MovableCondvar}; -pub use mutex::{MovableMutex, Mutex}; -pub use rwlock::MovableRwLock; +pub use condvar::Condvar; +pub use mutex::Mutex; +pub use rwlock::RwLock; diff --git a/library/std/src/sys/windows/locks/mutex.rs b/library/std/src/sys/windows/locks/mutex.rs index 91207f5f46658..ef2f84082cd5c 100644 --- a/library/std/src/sys/windows/locks/mutex.rs +++ b/library/std/src/sys/windows/locks/mutex.rs @@ -21,9 +21,6 @@ pub struct Mutex { srwlock: UnsafeCell, } -// Windows SRW Locks are movable (while not borrowed). -pub type MovableMutex = Mutex; - unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} @@ -39,13 +36,15 @@ impl Mutex { } #[inline] - pub unsafe fn lock(&self) { - c::AcquireSRWLockExclusive(raw(self)); + pub fn lock(&self) { + unsafe { + c::AcquireSRWLockExclusive(raw(self)); + } } #[inline] - pub unsafe fn try_lock(&self) -> bool { - c::TryAcquireSRWLockExclusive(raw(self)) != 0 + pub fn try_lock(&self) -> bool { + unsafe { c::TryAcquireSRWLockExclusive(raw(self)) != 0 } } #[inline] diff --git a/library/std/src/sys/windows/locks/rwlock.rs b/library/std/src/sys/windows/locks/rwlock.rs index fa5ffe5749f25..e69415baac42b 100644 --- a/library/std/src/sys/windows/locks/rwlock.rs +++ b/library/std/src/sys/windows/locks/rwlock.rs @@ -5,8 +5,6 @@ pub struct RwLock { inner: UnsafeCell, } -pub type MovableRwLock = RwLock; - unsafe impl Send for RwLock {} unsafe impl Sync for RwLock {} @@ -16,20 +14,20 @@ impl RwLock { RwLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) } } #[inline] - pub unsafe fn read(&self) { - c::AcquireSRWLockShared(self.inner.get()) + pub fn read(&self) { + unsafe { c::AcquireSRWLockShared(self.inner.get()) } } #[inline] - pub unsafe fn try_read(&self) -> bool { - c::TryAcquireSRWLockShared(self.inner.get()) != 0 + pub fn try_read(&self) -> bool { + unsafe { c::TryAcquireSRWLockShared(self.inner.get()) != 0 } } #[inline] - pub unsafe fn write(&self) { - c::AcquireSRWLockExclusive(self.inner.get()) + pub fn write(&self) { + unsafe { c::AcquireSRWLockExclusive(self.inner.get()) } } #[inline] - pub unsafe fn try_write(&self) -> bool { - c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 + pub fn try_write(&self) -> bool { + unsafe { c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 } } #[inline] pub unsafe fn read_unlock(&self) { diff --git a/library/std/src/sys_common/condvar.rs b/library/std/src/sys_common/condvar.rs deleted file mode 100644 index 8bc5b24115d16..0000000000000 --- a/library/std/src/sys_common/condvar.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::sys::locks as imp; -use crate::sys_common::mutex::MovableMutex; -use crate::time::Duration; - -mod check; - -type CondvarCheck = ::Check; - -/// An OS-based condition variable. -pub struct Condvar { - inner: imp::MovableCondvar, - check: CondvarCheck, -} - -impl Condvar { - /// Creates a new condition variable for use. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self { inner: imp::MovableCondvar::new(), check: CondvarCheck::new() } - } - - /// Signals one waiter on this condition variable to wake up. - #[inline] - pub fn notify_one(&self) { - unsafe { self.inner.notify_one() }; - } - - /// Awakens all current waiters on this condition variable. - #[inline] - pub fn notify_all(&self) { - unsafe { self.inner.notify_all() }; - } - - /// Waits for a signal on the specified mutex. - /// - /// Behavior is undefined if the mutex is not locked by the current thread. - /// - /// May panic if used with more than one mutex. - #[inline] - pub unsafe fn wait(&self, mutex: &MovableMutex) { - self.check.verify(mutex); - self.inner.wait(mutex.raw()) - } - - /// Waits for a signal on the specified mutex with a timeout duration - /// specified by `dur` (a relative time into the future). - /// - /// Behavior is undefined if the mutex is not locked by the current thread. - /// - /// May panic if used with more than one mutex. - #[inline] - pub unsafe fn wait_timeout(&self, mutex: &MovableMutex, dur: Duration) -> bool { - self.check.verify(mutex); - self.inner.wait_timeout(mutex.raw(), dur) - } -} diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs deleted file mode 100644 index 4ac9e62bf8695..0000000000000 --- a/library/std/src/sys_common/condvar/check.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::ptr; -use crate::sync::atomic::{AtomicPtr, Ordering}; -use crate::sys::locks as imp; -use crate::sys_common::lazy_box::{LazyBox, LazyInit}; -use crate::sys_common::mutex::MovableMutex; - -pub trait CondvarCheck { - type Check; -} - -/// For boxed mutexes, a `Condvar` will check it's only ever used with the same -/// mutex, based on its (stable) address. -impl CondvarCheck for LazyBox { - type Check = SameMutexCheck; -} - -pub struct SameMutexCheck { - addr: AtomicPtr<()>, -} - -#[allow(dead_code)] -impl SameMutexCheck { - pub const fn new() -> Self { - Self { addr: AtomicPtr::new(ptr::null_mut()) } - } - pub fn verify(&self, mutex: &MovableMutex) { - let addr = mutex.raw() as *const imp::Mutex as *const () as *mut _; - // Relaxed is okay here because we never read through `self.addr`, and only use it to - // compare addresses. - match self.addr.compare_exchange( - ptr::null_mut(), - addr, - Ordering::Relaxed, - Ordering::Relaxed, - ) { - Ok(_) => {} // Stored the address - Err(n) if n == addr => {} // Lost a race to store the same address - _ => panic!("attempted to use a condition variable with two mutexes"), - } - } -} - -/// Unboxed mutexes may move, so `Condvar` can not require its address to stay -/// constant. -impl CondvarCheck for imp::Mutex { - type Check = NoCheck; -} - -pub struct NoCheck; - -#[allow(dead_code)] -impl NoCheck { - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self - } - pub fn verify(&self, _: &MovableMutex) {} -} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 8c19f9332dc56..069b13e9d85ea 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -21,16 +21,13 @@ mod tests; pub mod backtrace; -pub mod condvar; pub mod fs; pub mod io; pub mod lazy_box; pub mod memchr; -pub mod mutex; pub mod once; pub mod process; pub mod remutex; -pub mod rwlock; pub mod thread; pub mod thread_info; pub mod thread_local_dtor; diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs deleted file mode 100644 index 98046f20f896a..0000000000000 --- a/library/std/src/sys_common/mutex.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::sys::locks as imp; - -/// An OS-based mutual exclusion lock. -/// -/// This mutex cleans up its resources in its `Drop` implementation, may safely -/// be moved (when not borrowed), and does not cause UB when used reentrantly. -/// -/// This mutex does not implement poisoning. -/// -/// This is either a wrapper around `LazyBox` or `imp::Mutex`, -/// depending on the platform. It is boxed on platforms where `imp::Mutex` may -/// not be moved. -pub struct MovableMutex(imp::MovableMutex); - -unsafe impl Sync for MovableMutex {} - -impl MovableMutex { - /// Creates a new mutex. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self(imp::MovableMutex::new()) - } - - pub(super) fn raw(&self) -> &imp::Mutex { - &self.0 - } - - /// Locks the mutex blocking the current thread until it is available. - #[inline] - pub fn raw_lock(&self) { - unsafe { self.0.lock() } - } - - /// Attempts to lock the mutex without blocking, returning whether it was - /// successfully acquired or not. - #[inline] - pub fn try_lock(&self) -> bool { - unsafe { self.0.try_lock() } - } - - /// Unlocks the mutex. - /// - /// Behavior is undefined if the current thread does not actually hold the - /// mutex. - #[inline] - pub unsafe fn raw_unlock(&self) { - self.0.unlock() - } -} diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs index b448ae3a99777..4c054da64714c 100644 --- a/library/std/src/sys_common/remutex.rs +++ b/library/std/src/sys_common/remutex.rs @@ -1,11 +1,11 @@ #[cfg(all(test, not(target_os = "emscripten")))] mod tests; -use super::mutex as sys; use crate::cell::UnsafeCell; use crate::ops::Deref; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +use crate::sys::locks as sys; /// A re-entrant mutual exclusion /// @@ -39,7 +39,7 @@ use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed}; /// synchronization is left to the mutex, making relaxed memory ordering for /// the `owner` field fine in all cases. pub struct ReentrantMutex { - mutex: sys::MovableMutex, + mutex: sys::Mutex, owner: AtomicUsize, lock_count: UnsafeCell, data: T, @@ -74,7 +74,7 @@ impl ReentrantMutex { /// Creates a new reentrant mutex in an unlocked state. pub const fn new(t: T) -> ReentrantMutex { ReentrantMutex { - mutex: sys::MovableMutex::new(), + mutex: sys::Mutex::new(), owner: AtomicUsize::new(0), lock_count: UnsafeCell::new(0), data: t, @@ -100,7 +100,7 @@ impl ReentrantMutex { if self.owner.load(Relaxed) == this_thread { self.increment_lock_count(); } else { - self.mutex.raw_lock(); + self.mutex.lock(); self.owner.store(this_thread, Relaxed); debug_assert_eq!(*self.lock_count.get(), 0); *self.lock_count.get() = 1; @@ -162,7 +162,7 @@ impl Drop for ReentrantMutexGuard<'_, T> { *self.lock.lock_count.get() -= 1; if *self.lock.lock_count.get() == 0 { self.lock.owner.store(0, Relaxed); - self.lock.mutex.raw_unlock(); + self.lock.mutex.unlock(); } } } diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs deleted file mode 100644 index 042981dac60b4..0000000000000 --- a/library/std/src/sys_common/rwlock.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::sys::locks as imp; - -/// An OS-based reader-writer lock. -/// -/// This rwlock cleans up its resources in its `Drop` implementation and may -/// safely be moved (when not borrowed). -/// -/// This rwlock does not implement poisoning. -/// -/// This is either a wrapper around `LazyBox` or `imp::RwLock`, -/// depending on the platform. It is boxed on platforms where `imp::RwLock` may -/// not be moved. -pub struct MovableRwLock(imp::MovableRwLock); - -impl MovableRwLock { - /// Creates a new reader-writer lock for use. - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> Self { - Self(imp::MovableRwLock::new()) - } - - /// Acquires shared access to the underlying lock, blocking the current - /// thread to do so. - #[inline] - pub fn read(&self) { - unsafe { self.0.read() } - } - - /// Attempts to acquire shared access to this lock, returning whether it - /// succeeded or not. - /// - /// This function does not block the current thread. - #[inline] - pub fn try_read(&self) -> bool { - unsafe { self.0.try_read() } - } - - /// Acquires write access to the underlying lock, blocking the current thread - /// to do so. - #[inline] - pub fn write(&self) { - unsafe { self.0.write() } - } - - /// Attempts to acquire exclusive access to this lock, returning whether it - /// succeeded or not. - /// - /// This function does not block the current thread. - #[inline] - pub fn try_write(&self) -> bool { - unsafe { self.0.try_write() } - } - - /// Unlocks previously acquired shared access to this lock. - /// - /// Behavior is undefined if the current thread does not have shared access. - #[inline] - pub unsafe fn read_unlock(&self) { - self.0.read_unlock() - } - - /// Unlocks previously acquired exclusive access to this lock. - /// - /// Behavior is undefined if the current thread does not currently have - /// exclusive access. - #[inline] - pub unsafe fn write_unlock(&self) { - self.0.write_unlock() - } -} From db9fa273b00eb88535be31ed4308f04c845180a9 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 19 Oct 2022 00:32:33 +0200 Subject: [PATCH 475/482] std: fix double-free of mutex --- library/std/src/sys/unix/locks/pthread_mutex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/locks/pthread_mutex.rs b/library/std/src/sys/unix/locks/pthread_mutex.rs index a1155a808aaf4..8a78bc1fd7399 100644 --- a/library/std/src/sys/unix/locks/pthread_mutex.rs +++ b/library/std/src/sys/unix/locks/pthread_mutex.rs @@ -64,7 +64,7 @@ impl LazyInit for AllocatedMutex { // We're not allowed to pthread_mutex_destroy a locked mutex, // so check first if it's unlocked. if unsafe { libc::pthread_mutex_trylock(mutex.0.get()) == 0 } { - unsafe { libc::pthread_mutex_destroy(mutex.0.get()) }; + unsafe { libc::pthread_mutex_unlock(mutex.0.get()) }; drop(mutex); } else { // The mutex is locked. This happens if a MutexGuard is leaked. From 2d8b250c7c979fda22446e75732c82009a8e3820 Mon Sep 17 00:00:00 2001 From: joboet Date: Sun, 6 Nov 2022 15:31:46 +0100 Subject: [PATCH 476/482] update LLVM submodule to make libunwind work on SGX --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 2a2ea6b49e793..a1232c451fc27 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 2a2ea6b49e79325e0d10d33fac2b10ea3bebcc7c +Subproject commit a1232c451fc27173f8718e05d174b2503ca0b607 From ff19acb422f5cea5efea86058a53f84c5ea710fa Mon Sep 17 00:00:00 2001 From: joboet Date: Sun, 6 Nov 2022 21:44:33 +0100 Subject: [PATCH 477/482] update debuginfo check --- src/test/debuginfo/mutex.rs | 2 +- src/test/debuginfo/rwlock-read.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs index 314ba40b0e3d0..61ec6a81243d5 100644 --- a/src/test/debuginfo/mutex.rs +++ b/src/test/debuginfo/mutex.rs @@ -10,7 +10,7 @@ // // cdb-command:dx m,d // cdb-check:m,d [Type: std::sync::mutex::Mutex] -// cdb-check: [...] inner [Type: std::sys_common::mutex::MovableMutex] +// cdb-check: [...] inner [Type: std::sys::windows::locks::mutex::Mutex] // cdb-check: [...] poison [Type: std::sync::poison::Flag] // cdb-check: [...] data : 0 [Type: core::cell::UnsafeCell] diff --git a/src/test/debuginfo/rwlock-read.rs b/src/test/debuginfo/rwlock-read.rs index ed9aae16b0db1..bc42f92f053d5 100644 --- a/src/test/debuginfo/rwlock-read.rs +++ b/src/test/debuginfo/rwlock-read.rs @@ -16,7 +16,7 @@ // cdb-command:dx r // cdb-check:r [Type: std::sync::rwlock::RwLockReadGuard] // cdb-check: [...] data : NonNull([...]: 0) [Type: core::ptr::non_null::NonNull] -// cdb-check: [...] inner_lock : [...] [Type: std::sys_common::rwlock::MovableRwLock *] +// cdb-check: [...] inner_lock : [...] [Type: std::sys::windows::locks::rwlock::RwLock *] #[allow(unused_variables)] From 8cf5ebbd25e1d14c33990528bef1cf542ba07aba Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 25 Oct 2022 15:07:56 +0000 Subject: [PATCH 478/482] Tweak signatures in rustc_middle::hir::map. --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8a70f41c8a840..837ff0bdf3e35 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -117,7 +117,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( } fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) { - let node = tcx.hir().expect_owner(def_id); + let node = tcx.hir().owner(def_id); match node { hir::OwnerNode::Crate(_) => {} hir::OwnerNode::Item(item) => check_item(tcx, item), diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index dfe52312ff00d..efae266900634 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -163,7 +163,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do // a standard visit. // FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's. - _ => match tcx.hir().expect_owner(owner) { + _ => match tcx.hir().owner(owner) { hir::OwnerNode::Item(item) => levels.visit_item(item), hir::OwnerNode::ForeignItem(item) => levels.visit_foreign_item(item), hir::OwnerNode::TraitItem(item) => levels.visit_trait_item(item), diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 83a4d16d7a925..14f50ae87de06 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -353,6 +353,10 @@ impl<'hir> Map<'hir> { node.node.generics() } + pub fn owner(self, id: OwnerId) -> OwnerNode<'hir> { + self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id)).node + } + pub fn item(self, id: ItemId) -> &'hir Item<'hir> { self.tcx.hir_owner(id.owner_id).unwrap().node.expect_item() } @@ -822,8 +826,11 @@ impl<'hir> Map<'hir> { ) } - pub fn expect_owner(self, id: OwnerId) -> OwnerNode<'hir> { - self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id)).node + pub fn expect_owner(self, def_id: LocalDefId) -> OwnerNode<'hir> { + self.tcx + .hir_owner(OwnerId { def_id }) + .unwrap_or_else(|| bug!("expected owner for {:?}", def_id)) + .node } pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { From 83972eb23104e5e3a836a34c759e54d7f190edbe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 25 Oct 2022 15:08:20 +0000 Subject: [PATCH 479/482] Resolve lifetimes independently for each item-like. --- .../src/collect/lifetimes.rs | 243 +++++------------- compiler/rustc_middle/src/query/mod.rs | 11 +- 2 files changed, 67 insertions(+), 187 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index c64177eea3f83..1fec8f027bd36 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -94,11 +94,6 @@ struct LifetimeContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, map: &'a mut NamedRegionMap, scope: ScopeRef<'a>, - - /// Indicates that we only care about the definition of a trait. This should - /// be false if the `Item` we are resolving lifetimes for is not a trait or - /// we eventually need lifetimes resolve for trait items. - trait_definition_only: bool, } #[derive(Debug)] @@ -166,7 +161,9 @@ enum Scope<'a> { s: ScopeRef<'a>, }, - Root, + Root { + opt_parent_item: Option, + }, } #[derive(Copy, Clone, Debug)] @@ -214,95 +211,58 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("s", &"..") .finish(), Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(), - Scope::Root => f.debug_struct("Root").finish(), + Scope::Root { opt_parent_item } => { + f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish() + } } } } type ScopeRef<'a> = &'a Scope<'a>; -const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root; - pub(crate) fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { - resolve_lifetimes_trait_definition, resolve_lifetimes, - named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), + named_region_map: |tcx, id| tcx.resolve_lifetimes(id).defs.get(&id), is_late_bound_map, object_lifetime_default, - late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), + late_bound_vars_map: |tcx, id| tcx.resolve_lifetimes(id).late_bound_vars.get(&id), ..*providers }; } -/// Like `resolve_lifetimes`, but does not resolve lifetimes for trait items. -/// Also does not generate any diagnostics. -/// -/// This is ultimately a subset of the `resolve_lifetimes` work. It effectively -/// resolves lifetimes only within the trait "header" -- that is, the trait -/// and supertrait list. In contrast, `resolve_lifetimes` resolves all the -/// lifetimes within the trait and its items. There is room to refactor this, -/// for example to resolve lifetimes for each trait item in separate queries, -/// but it's convenient to do the entire trait at once because the lifetimes -/// from the trait definition are in scope within the trait items as well. -/// -/// The reason for this separate call is to resolve what would otherwise -/// be a cycle. Consider this example: -/// -/// ```ignore UNSOLVED (maybe @jackh726 knows what lifetime parameter to give Sub) -/// trait Base<'a> { -/// type BaseItem; -/// } -/// trait Sub<'b>: for<'a> Base<'a> { -/// type SubItem: Sub; -/// } -/// ``` -/// -/// When we resolve `Sub` and all its items, we also have to resolve `Sub`. -/// To figure out the index of `'b`, we have to know about the supertraits -/// of `Sub` so that we can determine that the `for<'a>` will be in scope. -/// (This is because we -- currently at least -- flatten all the late-bound -/// lifetimes into a single binder.) This requires us to resolve the -/// *trait definition* of `Sub`; basically just enough lifetime information -/// to look at the supertraits. -#[instrument(level = "debug", skip(tcx))] -fn resolve_lifetimes_trait_definition( - tcx: TyCtxt<'_>, - local_def_id: LocalDefId, -) -> ResolveLifetimes { - convert_named_region_map(do_resolve(tcx, local_def_id, true)) -} - /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`. /// You should not read the result of this query directly, but rather use /// `named_region_map`, `is_late_bound_map`, etc. #[instrument(level = "debug", skip(tcx))] -fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes { - convert_named_region_map(do_resolve(tcx, local_def_id, false)) -} - -fn do_resolve( - tcx: TyCtxt<'_>, - local_def_id: LocalDefId, - trait_definition_only: bool, -) -> NamedRegionMap { - let item = tcx.hir().expect_item(local_def_id); +fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveLifetimes { let mut named_region_map = NamedRegionMap { defs: Default::default(), late_bound_vars: Default::default() }; let mut visitor = LifetimeContext { tcx, map: &mut named_region_map, - scope: ROOT_SCOPE, - trait_definition_only, + scope: &Scope::Root { opt_parent_item: None }, }; - visitor.visit_item(item); - - named_region_map -} + match tcx.hir().owner(local_def_id) { + hir::OwnerNode::Item(item) => visitor.visit_item(item), + hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), + hir::OwnerNode::TraitItem(item) => { + let scope = + Scope::Root { opt_parent_item: Some(tcx.local_parent(item.owner_id.def_id)) }; + visitor.scope = &scope; + visitor.visit_trait_item(item) + } + hir::OwnerNode::ImplItem(item) => { + let scope = + Scope::Root { opt_parent_item: Some(tcx.local_parent(item.owner_id.def_id)) }; + visitor.scope = &scope; + visitor.visit_impl_item(item) + } + hir::OwnerNode::Crate(_) => {} + } -fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes { let mut rl = ResolveLifetimes::default(); for (hir_id, v) in named_region_map.defs { @@ -319,53 +279,6 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime rl } -/// Given `any` owner (structs, traits, trait methods, etc.), does lifetime resolution. -/// There are two important things this does. -/// First, we have to resolve lifetimes for -/// the entire *`Item`* that contains this owner, because that's the largest "scope" -/// where we can have relevant lifetimes. -/// Second, if we are asking for lifetimes in a trait *definition*, we use `resolve_lifetimes_trait_definition` -/// instead of `resolve_lifetimes`, which does not descend into the trait items and does not emit diagnostics. -/// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner -/// other than the trait itself (like the trait methods or associated types), then we just use the regular -/// `resolve_lifetimes`. -fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: hir::OwnerId) -> &'tcx ResolveLifetimes { - let item_id = item_for(tcx, def_id.def_id); - let local_def_id = item_id.owner_id.def_id; - if item_id.owner_id == def_id { - let item = tcx.hir().item(item_id); - match item.kind { - hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(local_def_id), - _ => tcx.resolve_lifetimes(local_def_id), - } - } else { - tcx.resolve_lifetimes(local_def_id) - } -} - -/// Finds the `Item` that contains the given `LocalDefId` -fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> hir::ItemId { - match tcx.hir().find_by_def_id(local_def_id) { - Some(Node::Item(item)) => { - return item.item_id(); - } - _ => {} - } - let item = { - let hir_id = tcx.hir().local_def_id_to_hir_id(local_def_id); - let mut parent_iter = tcx.hir().parent_iter(hir_id); - loop { - let node = parent_iter.next().map(|n| n.1); - match node { - Some(hir::Node::Item(item)) => break item.item_id(), - Some(hir::Node::Crate(_)) | None => bug!("Called `item_for` on an Item."), - _ => {} - } - } - }; - item -} - fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind { match region { Region::LateBound(_, _, def_id) => { @@ -383,7 +296,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut supertrait_lifetimes = vec![]; loop { match scope { - Scope::Body { .. } | Scope::Root => { + Scope::Body { .. } | Scope::Root { .. } => { break (vec![], BinderScopeType::Normal); } @@ -414,21 +327,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { - type NestedFilter = nested_filter::All; + type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Self::Map { self.tcx.hir() } - // We want to nest trait/impl items in their parent, but nothing else. - fn visit_nested_item(&mut self, _: hir::ItemId) {} - - fn visit_trait_item_ref(&mut self, ii: &'tcx hir::TraitItemRef) { - if !self.trait_definition_only { - intravisit::walk_trait_item_ref(self, ii) - } - } - fn visit_nested_body(&mut self, body: hir::BodyId) { let body = self.tcx.hir().body(body); self.with(Scope::Body { id: body.id(), s: self.scope }, |this| { @@ -557,33 +461,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // their owner, we can keep going until we find the Item that owns that. We then // conservatively add all resolved lifetimes. Otherwise we run into problems in // cases like `type Foo<'a> = impl Bar`. - for (_hir_id, node) in self.tcx.hir().parent_iter(item.owner_id.into()) { - match node { - hir::Node::Item(parent_item) => { - let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes( - item_for(self.tcx, parent_item.owner_id.def_id).owner_id.def_id, - ); - // We need to add *all* deps, since opaque tys may want them from *us* - for (&owner, defs) in resolved_lifetimes.defs.iter() { - defs.iter().for_each(|(&local_id, region)| { - self.map.defs.insert(hir::HirId { owner, local_id }, *region); - }); - } - for (&owner, late_bound_vars) in - resolved_lifetimes.late_bound_vars.iter() - { - late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| { - self.record_late_bound_vars( - hir::HirId { owner, local_id }, - late_bound_vars.clone(), - ); - }); - } - break; - } - hir::Node::Crate(_) => bug!("No Item about an OpaqueTy"), - _ => {} - } + let parent_item = self.tcx.hir().get_parent_item(item.hir_id()); + let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(parent_item); + // We need to add *all* deps, since opaque tys may want them from *us* + for (&owner, defs) in resolved_lifetimes.defs.iter() { + defs.iter().for_each(|(&local_id, region)| { + self.map.defs.insert(hir::HirId { owner, local_id }, *region); + }); + } + for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() { + late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| { + self.record_late_bound_vars( + hir::HirId { owner, local_id }, + late_bound_vars.clone(), + ); + }); } } hir::ItemKind::TyAlias(_, ref generics) @@ -609,7 +501,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: item.hir_id(), lifetimes, scope_type: BinderScopeType::Normal, - s: ROOT_SCOPE, + s: self.scope, where_bound_origin: None, }; self.with(scope, |this| { @@ -766,30 +658,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // Ensure that the parent of the def is an item, not HRTB let parent_id = self.tcx.hir().get_parent_node(hir_id); if !parent_id.is_owner() { - if !self.trait_definition_only { - struct_span_err!( - self.tcx.sess, - lifetime.span, - E0657, - "`impl Trait` can only capture lifetimes \ + struct_span_err!( + self.tcx.sess, + lifetime.span, + E0657, + "`impl Trait` can only capture lifetimes \ bound at the fn or impl level" - ) - .emit(); - } + ) + .emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } if let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy { .. }, .. }) = self.tcx.hir().get(parent_id) { - if !self.trait_definition_only { - let mut err = self.tcx.sess.struct_span_err( + let mut err = self.tcx.sess.struct_span_err( lifetime.span, "higher kinded lifetime bounds on nested opaque types are not supported yet", ); - err.span_note(self.tcx.def_span(def_id), "lifetime declared here"); - err.emit(); - } + err.span_note(self.tcx.def_span(def_id), "lifetime declared here"); + err.emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } } @@ -1193,12 +1081,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>), { let LifetimeContext { tcx, map, .. } = self; - let mut this = LifetimeContext { - tcx: *tcx, - map, - scope: &wrap_scope, - trait_definition_only: self.trait_definition_only, - }; + let mut this = LifetimeContext { tcx: *tcx, map, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope)); { let _enter = span.enter(); @@ -1303,7 +1186,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Root => { + Scope::Root { opt_parent_item } => { + if let Some(parent_item) = opt_parent_item + && let parent_generics = self.tcx.generics_of(parent_item) + && parent_generics.param_def_id_to_index.contains_key(®ion_def_id.to_def_id()) + { + break Some(Region::EarlyBound(region_def_id.to_def_id())); + } break None; } @@ -1417,7 +1306,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { err.emit(); return; } - Scope::Root => break, + Scope::Root { .. } => break, Scope::Binder { s, .. } | Scope::Body { s, .. } | Scope::Elision { s, .. } @@ -1495,7 +1384,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut scope = self.scope; loop { match *scope { - Scope::Root => break false, + Scope::Root { .. } => break false, Scope::Body { .. } => break true, @@ -1732,7 +1621,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Root | Scope::Elision { .. } => break Region::Static, + Scope::Root { .. } | Scope::Elision { .. } => break Region::Static, Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 00242e7eed775..1564cf414bd25 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1614,19 +1614,10 @@ rustc_queries! { desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } } - /// Does lifetime resolution, but does not descend into trait items. This - /// should only be used for resolving lifetimes of on trait definitions, - /// and is used to avoid cycles. Importantly, `resolve_lifetimes` still visits - /// the same lifetimes and is responsible for diagnostics. - /// See `rustc_resolve::late::lifetimes for details. - query resolve_lifetimes_trait_definition(_: LocalDefId) -> ResolveLifetimes { - arena_cache - desc { "resolving lifetimes for a trait definition" } - } /// Does lifetime resolution on items. Importantly, we can't resolve /// lifetimes directly on things like trait methods, because of trait params. /// See `rustc_resolve::late::lifetimes for details. - query resolve_lifetimes(_: LocalDefId) -> ResolveLifetimes { + query resolve_lifetimes(_: hir::OwnerId) -> ResolveLifetimes { arena_cache desc { "resolving lifetimes" } } From f43591bdaf081a95c71ef245412d973c10d29125 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 25 Oct 2022 16:10:19 +0000 Subject: [PATCH 480/482] Resolve lifetimes using the regular logic for RPIT. --- .../src/collect/lifetimes.rs | 73 +++++++++---------- src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs | 3 + .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 39 ++++++++-- .../impl-trait/impl-fn-parsing-ambiguities.rs | 3 +- .../impl-fn-parsing-ambiguities.stderr | 13 +++- src/test/ui/impl-trait/issues/issue-67830.rs | 2 + .../ui/impl-trait/issues/issue-67830.stderr | 20 ++++- .../ui/impl-trait/issues/issue-88236-2.rs | 5 ++ .../ui/impl-trait/issues/issue-88236-2.stderr | 60 ++++++++++++++- src/test/ui/impl-trait/nested-rpit-hrtb.rs | 18 +++-- .../ui/impl-trait/nested-rpit-hrtb.stderr | 64 ++++++++++++++-- 11 files changed, 238 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 1fec8f027bd36..895f32114dc29 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -452,7 +452,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_item(this, item) }); } - hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias, .. + }) => { // Opaque types are visited when we visit the // `TyKind::OpaqueDef`, so that they have the lifetimes from // their parent opaque_ty in scope. @@ -478,6 +480,37 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }); } } + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_), + generics, + .. + }) => { + // We want to start our early-bound indices at the end of the parent scope, + // not including any parent `impl Trait`s. + let mut lifetimes = FxIndexMap::default(); + debug!(?generics.params); + for param in generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => { + let (def_id, reg) = Region::early(self.tcx.hir(), ¶m); + lifetimes.insert(def_id, reg); + } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {} + } + } + + let scope = Scope::Binder { + hir_id: item.hir_id(), + lifetimes, + s: self.scope, + scope_type: BinderScopeType::Normal, + where_bound_origin: None, + }; + self.with(scope, |this| { + let scope = Scope::TraitRefBoundary { s: this.scope }; + this.with(scope, |this| intravisit::walk_item(this, item)) + }); + } hir::ItemKind::TyAlias(_, ref generics) | hir::ItemKind::Enum(_, ref generics) | hir::ItemKind::Struct(_, ref generics) @@ -604,7 +637,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // ^ ^ this gets resolved in the scope of // the opaque_ty generics let opaque_ty = self.tcx.hir().item(item_id); - let (generics, bounds) = match opaque_ty.kind { + match opaque_ty.kind { hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. @@ -625,10 +658,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..), - ref generics, - bounds, .. - }) => (generics, bounds), + }) => {} ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), }; @@ -681,38 +712,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } } - - // We want to start our early-bound indices at the end of the parent scope, - // not including any parent `impl Trait`s. - let mut lifetimes = FxIndexMap::default(); - debug!(?generics.params); - for param in generics.params { - match param.kind { - GenericParamKind::Lifetime { .. } => { - let (def_id, reg) = Region::early(self.tcx.hir(), ¶m); - lifetimes.insert(def_id, reg); - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {} - } - } - self.record_late_bound_vars(ty.hir_id, vec![]); - - let scope = Scope::Binder { - hir_id: ty.hir_id, - lifetimes, - s: self.scope, - scope_type: BinderScopeType::Normal, - where_bound_origin: None, - }; - self.with(scope, |this| { - let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |this| { - this.visit_generics(generics); - for bound in bounds { - this.visit_param_bound(bound); - } - }) - }); } _ => intravisit::walk_ty(self, ty), } diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs index 527a4586fd7e0..06c3d9ad434e4 100644 --- a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs +++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs @@ -4,16 +4,19 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> (impl Debug + '_) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x + //~^ ERROR lifetime may not live long enough } fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x + //~^ ERROR lifetime may not live long enough } fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x + //~^ ERROR lifetime may not live long enough } fn d() -> impl Fn() -> (impl Debug + '_) { diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr index 443ffeb55cdee..b6857a6c4c51d 100644 --- a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/impl-fn-hrtb-bounds.rs:19:38 + --> $DIR/impl-fn-hrtb-bounds.rs:22:38 | LL | fn d() -> impl Fn() -> (impl Debug + '_) { | ^^ expected named lifetime parameter @@ -22,30 +22,57 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { | ^ +error: lifetime may not live long enough + --> $DIR/impl-fn-hrtb-bounds.rs:6:9 + | +LL | |x| x + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is impl Debug + '2 + | has type `&'1 u8` + error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/impl-fn-hrtb-bounds.rs:9:52 + --> $DIR/impl-fn-hrtb-bounds.rs:10:52 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:9:20 + --> $DIR/impl-fn-hrtb-bounds.rs:10:20 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ +error: lifetime may not live long enough + --> $DIR/impl-fn-hrtb-bounds.rs:12:9 + | +LL | |x| x + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is impl Debug + '2 + | has type `&'1 u8` + error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/impl-fn-hrtb-bounds.rs:14:52 + --> $DIR/impl-fn-hrtb-bounds.rs:16:52 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:14:20 + --> $DIR/impl-fn-hrtb-bounds.rs:16:20 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ -error: aborting due to 4 previous errors +error: lifetime may not live long enough + --> $DIR/impl-fn-hrtb-bounds.rs:18:9 + | +LL | |x| x + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is impl Debug + '2 + | has type `&'1 u8` + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs index 3e760710797eb..a4a1f1dcee120 100644 --- a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs +++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs @@ -3,8 +3,9 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> impl Debug + '_ { //~^ ERROR ambiguous `+` in a type - //~^^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x + //~^ ERROR lifetime may not live long enough } fn b() -> impl Fn() -> impl Debug + Send { diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index cf6e5ef7baceb..e18e89700b4e9 100644 --- a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -5,7 +5,7 @@ LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)` error: ambiguous `+` in a type - --> $DIR/impl-fn-parsing-ambiguities.rs:10:24 + --> $DIR/impl-fn-parsing-ambiguities.rs:11:24 | LL | fn b() -> impl Fn() -> impl Debug + Send { | ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)` @@ -22,5 +22,14 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^ -error: aborting due to 3 previous errors +error: lifetime may not live long enough + --> $DIR/impl-fn-parsing-ambiguities.rs:7:9 + | +LL | |x| x + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is impl Debug + '2 + | has type `&'1 u8` + +error: aborting due to 4 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-67830.rs b/src/test/ui/impl-trait/issues/issue-67830.rs index 92f7e005dbf0c..6dc8935c77708 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.rs +++ b/src/test/ui/impl-trait/issues/issue-67830.rs @@ -21,6 +21,8 @@ struct A; fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet Wrap(|a| Some(a).into_iter()) + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-67830.stderr b/src/test/ui/impl-trait/issues/issue-67830.stderr index d3ea8cb0377c7..cbc7cd5420139 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.stderr +++ b/src/test/ui/impl-trait/issues/issue-67830.stderr @@ -10,5 +10,23 @@ note: lifetime declared here LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { | ^^ -error: aborting due to previous error +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-67830.rs:23:5 + | +LL | Wrap(|a| Some(a).into_iter()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-67830.rs:23:5 + | +LL | Wrap(|a| Some(a).into_iter()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` + +error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs index fde8a6704cc45..f4354d1b2aef0 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.rs +++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs @@ -18,11 +18,16 @@ fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet &() + //~^ ERROR implementation of `Hrtb` is not general enough + //~| ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet x + //~^ ERROR implementation of `Hrtb` is not general enough + //~| ERROR implementation of `Hrtb` is not general enough + //~| ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr index 8605d07abe943..99c91d16a6475 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -22,17 +22,71 @@ note: lifetime declared here LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | &() + | ^^^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | &() + | ^^^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/issue-88236-2.rs:23:78 + --> $DIR/issue-88236-2.rs:25:78 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ | note: lifetime declared here - --> $DIR/issue-88236-2.rs:23:45 + --> $DIR/issue-88236-2.rs:25:45 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: aborting due to 3 previous errors +error: lifetime may not live long enough + --> $DIR/issue-88236-2.rs:27:5 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | -- lifetime `'b` defined here +LL | +LL | x + | ^ returning this value requires that `'b` must outlive `'static` + | +help: to declare that `impl for<'a> Hrtb<'a, Assoc = impl Send + 'static>` captures data from argument `x`, you can add an explicit `'b` lifetime bound + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { + | ++++ +help: to declare that `impl Send + 'a` captures data from argument `x`, you can add an explicit `'b` lifetime bound + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> { + | ++++ + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:27:5 + | +LL | x + | ^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:27:5 + | +LL | x + | ^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: aborting due to 8 previous errors diff --git a/src/test/ui/impl-trait/nested-rpit-hrtb.rs b/src/test/ui/impl-trait/nested-rpit-hrtb.rs index abf6a7e956c69..377658b95c987 100644 --- a/src/test/ui/impl-trait/nested-rpit-hrtb.rs +++ b/src/test/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,34 +31,40 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~| ERROR the trait bound `&(): Qux<'static>` is not satisfied -// This should pass. +// This should resolve. fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {} -// This should pass. +// This should resolve. fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'b> {} -// This should pass. +// This should resolve. fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} +//~^ ERROR the trait bound `&(): Qux<'b>` is not satisfied -// This should pass. +// This should resolve. fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} +//~^ ERROR implementation of `Bar` is not general enough -// This should pass. +// This should resolve. fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {} // `'b` is not in scope for the outlives bound. fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} //~^ ERROR use of undeclared lifetime name `'b` [E0261] -// This should pass. +// This should resolve. fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} +//~^ ERROR the trait bound `for<'b> &(): Qux<'b>` is not satisfied // `'b` is not in scope for the outlives bound. fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} //~^ ERROR use of undeclared lifetime name `'b` [E0261] +//~| ERROR implementation of `Bar` is not general enough fn main() {} diff --git a/src/test/ui/impl-trait/nested-rpit-hrtb.stderr b/src/test/ui/impl-trait/nested-rpit-hrtb.stderr index 3dbe6ebadfbfc..fb2a74453574c 100644 --- a/src/test/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/src/test/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:54:77 + --> $DIR/nested-rpit-hrtb.rs:58:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:61:82 + --> $DIR/nested-rpit-hrtb.rs:66:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,18 +65,70 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ +error: implementation of `Bar` is not general enough + --> $DIR/nested-rpit-hrtb.rs:32:78 + | +LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} + | ^^ implementation of `Bar` is not general enough + | + = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` + error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/nested-rpit-hrtb.rs:35:73 + --> $DIR/nested-rpit-hrtb.rs:36:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:35:44 + --> $DIR/nested-rpit-hrtb.rs:36:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ -error: aborting due to 6 previous errors +error[E0277]: the trait bound `&(): Qux<'static>` is not satisfied + --> $DIR/nested-rpit-hrtb.rs:36:64 + | +LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} + | ^^^^^^^^^^^^ the trait `Qux<'static>` is not implemented for `&()` + | + = help: the trait `Qux<'_>` is implemented for `()` + +error[E0277]: the trait bound `&(): Qux<'b>` is not satisfied + --> $DIR/nested-rpit-hrtb.rs:47:79 + | +LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} + | ^^^^^^^^^^^^ the trait `Qux<'b>` is not implemented for `&()` + | + = help: the trait `Qux<'_>` is implemented for `()` + +error: implementation of `Bar` is not general enough + --> $DIR/nested-rpit-hrtb.rs:51:93 + | +LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} + | ^^ implementation of `Bar` is not general enough + | + = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` + +error[E0277]: the trait bound `for<'b> &(): Qux<'b>` is not satisfied + --> $DIR/nested-rpit-hrtb.rs:62:64 + | +LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Qux<'b>` is not implemented for `&()` + | + = help: the trait `Qux<'_>` is implemented for `()` + +error: implementation of `Bar` is not general enough + --> $DIR/nested-rpit-hrtb.rs:66:86 + | +LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} + | ^^ implementation of `Bar` is not general enough + | + = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0261`. +Some errors have detailed explanations: E0261, E0277. +For more information about an error, try `rustc --explain E0261`. From 122d167c02473f2728584635583a0a8e9f7681fb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 11 Nov 2022 10:29:27 +0000 Subject: [PATCH 481/482] Visit opaque types during type collection too. --- compiler/rustc_hir_analysis/src/collect.rs | 41 ++++---- .../ui/associated-type-bounds/duplicate.rs | 3 + .../associated-type-bounds/duplicate.stderr | 98 ++++++++++++------- src/test/ui/async-await/issues/issue-65159.rs | 1 - .../ui/async-await/issues/issue-65159.stderr | 16 +-- .../issue-82126-mismatched-subst-and-hir.rs | 1 - ...ssue-82126-mismatched-subst-and-hir.stderr | 18 +--- .../min_const_generics/macro-fail.rs | 5 +- .../min_const_generics/macro-fail.stderr | 26 +---- ...plicit-hrtb-without-dyn.edition2021.stderr | 11 +-- .../generic-with-implicit-hrtb-without-dyn.rs | 4 +- src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs | 3 - .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 39 ++------ .../impl-trait/impl-fn-parsing-ambiguities.rs | 1 - .../impl-fn-parsing-ambiguities.stderr | 13 +-- src/test/ui/impl-trait/issues/issue-67830.rs | 2 - .../ui/impl-trait/issues/issue-67830.stderr | 20 +--- .../ui/impl-trait/issues/issue-88236-2.rs | 5 - .../ui/impl-trait/issues/issue-88236-2.stderr | 60 +----------- src/test/ui/impl-trait/issues/issue-92305.rs | 3 +- .../ui/impl-trait/issues/issue-92305.stderr | 22 +---- src/test/ui/impl-trait/nested-rpit-hrtb.rs | 6 -- .../ui/impl-trait/nested-rpit-hrtb.stderr | 64 ++---------- 23 files changed, 120 insertions(+), 342 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 4bca16c3a1cce..0e7a5ebf5ab62 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -644,12 +644,6 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } } - // Desugared from `impl Trait`, so visited by the function's return type. - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..), - .. - }) => {} - // Don't call `type_of` on opaque types, since that depends on type // checking function bodies. `check_item_type` ensures that it's called // instead. @@ -657,27 +651,32 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure().generics_of(def_id); tcx.ensure().predicates_of(def_id); tcx.ensure().explicit_item_bounds(def_id); + tcx.ensure().item_bounds(def_id); } - hir::ItemKind::TyAlias(..) - | hir::ItemKind::Static(..) - | hir::ItemKind::Const(..) - | hir::ItemKind::Fn(..) => { + + hir::ItemKind::TyAlias(..) => { tcx.ensure().generics_of(def_id); tcx.ensure().type_of(def_id); tcx.ensure().predicates_of(def_id); - match it.kind { - hir::ItemKind::Fn(..) => tcx.ensure().fn_sig(def_id), - hir::ItemKind::OpaqueTy(..) => tcx.ensure().item_bounds(def_id), - hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => { - if !is_suggestable_infer_ty(ty) { - let mut visitor = HirPlaceholderCollector::default(); - visitor.visit_item(it); - placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr()); - } - } - _ => (), + } + + hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => { + tcx.ensure().generics_of(def_id); + tcx.ensure().type_of(def_id); + tcx.ensure().predicates_of(def_id); + if !is_suggestable_infer_ty(ty) { + let mut visitor = HirPlaceholderCollector::default(); + visitor.visit_item(it); + placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr()); } } + + hir::ItemKind::Fn(..) => { + tcx.ensure().generics_of(def_id); + tcx.ensure().type_of(def_id); + tcx.ensure().predicates_of(def_id); + tcx.ensure().fn_sig(def_id); + } } } diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 6e464f69510ec..f67410986e559 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -132,12 +132,15 @@ where } fn FRPIT1() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] iter::empty() } fn FRPIT2() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] iter::empty() } fn FRPIT3() -> impl Iterator { + //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] iter::empty() } fn FAPIT1(_: impl Iterator) {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index e4f4836f71ab2..c3061327f566e 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -191,7 +191,31 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:143:40 + --> $DIR/duplicate.rs:134:42 + | +LL | fn FRPIT1() -> impl Iterator { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:138:42 + | +LL | fn FRPIT2() -> impl Iterator { + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:142:45 + | +LL | fn FRPIT3() -> impl Iterator { + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified + --> $DIR/duplicate.rs:146:40 | LL | fn FAPIT1(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -199,7 +223,7 @@ LL | fn FAPIT1(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:145:40 + --> $DIR/duplicate.rs:148:40 | LL | fn FAPIT2(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -207,7 +231,7 @@ LL | fn FAPIT2(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:147:43 + --> $DIR/duplicate.rs:150:43 | LL | fn FAPIT3(_: impl Iterator) {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -215,7 +239,7 @@ LL | fn FAPIT3(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:150:35 + --> $DIR/duplicate.rs:153:35 | LL | type TAI1> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -223,7 +247,7 @@ LL | type TAI1> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:152:35 + --> $DIR/duplicate.rs:155:35 | LL | type TAI2> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -231,7 +255,7 @@ LL | type TAI2> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:154:38 + --> $DIR/duplicate.rs:157:38 | LL | type TAI3> = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -239,7 +263,7 @@ LL | type TAI3> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:158:29 + --> $DIR/duplicate.rs:161:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -247,7 +271,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:163:29 + --> $DIR/duplicate.rs:166:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -255,7 +279,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:168:32 + --> $DIR/duplicate.rs:171:32 | LL | T: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -263,7 +287,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:172:36 + --> $DIR/duplicate.rs:175:36 | LL | type ETAI1> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -271,7 +295,7 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:174:36 + --> $DIR/duplicate.rs:177:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -279,7 +303,7 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:176:39 + --> $DIR/duplicate.rs:179:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -287,7 +311,7 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:178:40 + --> $DIR/duplicate.rs:181:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -295,7 +319,7 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:180:40 + --> $DIR/duplicate.rs:183:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -303,7 +327,7 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:182:43 + --> $DIR/duplicate.rs:185:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -311,7 +335,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:185:36 + --> $DIR/duplicate.rs:188:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -319,7 +343,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:187:36 + --> $DIR/duplicate.rs:190:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -327,7 +351,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:189:39 + --> $DIR/duplicate.rs:192:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -335,7 +359,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:191:34 + --> $DIR/duplicate.rs:194:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -343,7 +367,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:193:34 + --> $DIR/duplicate.rs:196:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -351,7 +375,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:195:37 + --> $DIR/duplicate.rs:198:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -359,7 +383,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:199:29 + --> $DIR/duplicate.rs:202:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -367,7 +391,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:205:29 + --> $DIR/duplicate.rs:208:29 | LL | T: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -375,7 +399,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:211:32 + --> $DIR/duplicate.rs:214:32 | LL | T: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -383,7 +407,7 @@ LL | T: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:217:32 + --> $DIR/duplicate.rs:220:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -391,7 +415,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:217:32 + --> $DIR/duplicate.rs:220:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -399,7 +423,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:224:32 + --> $DIR/duplicate.rs:227:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -407,7 +431,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:224:32 + --> $DIR/duplicate.rs:227:32 | LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here @@ -415,7 +439,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:231:35 + --> $DIR/duplicate.rs:234:35 | LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -423,7 +447,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:231:35 + --> $DIR/duplicate.rs:234:35 | LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here @@ -431,7 +455,7 @@ LL | Self: Iterator, | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:249:40 + --> $DIR/duplicate.rs:252:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -439,7 +463,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:251:44 + --> $DIR/duplicate.rs:254:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -447,7 +471,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:253:43 + --> $DIR/duplicate.rs:256:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -455,7 +479,7 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:237:34 + --> $DIR/duplicate.rs:240:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -463,7 +487,7 @@ LL | type A: Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:241:34 + --> $DIR/duplicate.rs:244:34 | LL | type A: Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -471,13 +495,13 @@ LL | type A: Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:245:37 + --> $DIR/duplicate.rs:248:37 | LL | type A: Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here | | | `Item` bound here first -error: aborting due to 60 previous errors +error: aborting due to 63 previous errors For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs index 1dbf5db6c32ed..df2ca025705d3 100644 --- a/src/test/ui/async-await/issues/issue-65159.rs +++ b/src/test/ui/async-await/issues/issue-65159.rs @@ -6,7 +6,6 @@ async fn copy() -> Result<()> //~^ ERROR this enum takes 2 generic arguments { Ok(()) - //~^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr index 9918f569cbc89..45f5ec40cd758 100644 --- a/src/test/ui/async-await/issues/issue-65159.stderr +++ b/src/test/ui/async-await/issues/issue-65159.stderr @@ -16,18 +16,6 @@ help: add missing generic argument LL | async fn copy() -> Result<(), E> | +++ -error[E0282]: type annotations needed - --> $DIR/issue-65159.rs:8:5 - | -LL | Ok(()) - | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` - | -help: consider specifying the generic arguments - | -LL | Ok::<(), E>(()) - | +++++++++ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs index 2c8a700bc2ea3..dd0320bc53ba7 100644 --- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -17,7 +17,6 @@ async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> { //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied LockedMarket(generator.lock().unwrap().buy()) - //~^ ERROR cannot return value referencing temporary } struct LockedMarket(T); diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr index 4bd0667304397..d2b927fb664c6 100644 --- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr @@ -7,7 +7,7 @@ LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> | expected 0 lifetime arguments | note: struct defined here, with 0 lifetime parameters - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket(T); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> | ^^^^^^^^^^^^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket(T); | ^^^^^^^^^^^^ - @@ -28,16 +28,6 @@ help: add missing generic argument LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_, T> { | +++ -error[E0515]: cannot return value referencing temporary value - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5 - | -LL | LockedMarket(generator.lock().unwrap().buy()) - | ^^^^^^^^^^^^^-------------------------^^^^^^^ - | | | - | | temporary value created here - | returns a value referencing data owned by the current function - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0515. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.rs b/src/test/ui/const-generics/min_const_generics/macro-fail.rs index f83518fc9d476..7fb69032e6fc4 100644 --- a/src/test/ui/const-generics/min_const_generics/macro-fail.rs +++ b/src/test/ui/const-generics/min_const_generics/macro-fail.rs @@ -14,7 +14,6 @@ impl Marker for Example {} fn make_marker() -> impl Marker { //~^ ERROR: type provided when a constant was expected Example:: - //~^ ERROR: type provided when a constant was expected } fn from_marker(_: impl Marker<{ @@ -34,9 +33,7 @@ fn main() { }>; let _fail = Example::; - //~^ ERROR: type provided when a constant was expected let _fail = Example::; - //~^ ERROR: type provided when a constant was expected - //~| ERROR unexpected end of macro invocation + //~^ ERROR unexpected end of macro invocation } diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr index d5dd70d9b489c..2b75c19774842 100644 --- a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr @@ -1,5 +1,5 @@ error: expected type, found `{` - --> $DIR/macro-fail.rs:29:27 + --> $DIR/macro-fail.rs:28:27 | LL | fn make_marker() -> impl Marker { | ---------------------- @@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` - --> $DIR/macro-fail.rs:29:27 + --> $DIR/macro-fail.rs:28:27 | LL | Example:: | ---------------------- @@ -46,7 +46,7 @@ LL | let _fail = Example::; = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation - --> $DIR/macro-fail.rs:39:25 + --> $DIR/macro-fail.rs:37:25 | LL | macro_rules! gimme_a_const { | -------------------------- when calling this macro @@ -60,24 +60,6 @@ error[E0747]: type provided when a constant was expected LL | fn make_marker() -> impl Marker { | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:16:13 - | -LL | Example:: - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:36:25 - | -LL | let _fail = Example::; - | ^^^^^^^^^^^^^^^^^ - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:39:25 - | -LL | let _fail = Example::; - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr index 88e2520bf4b24..30fbba168689b 100644 --- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr +++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr @@ -9,13 +9,6 @@ help: add `dyn` keyword before this trait LL | fn ice() -> impl AsRef { | +++ -error[E0277]: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied - --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13 - | -LL | fn ice() -> impl AsRef { - | ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not implemented for `()` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0277, E0782. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0782`. diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs index 5a922697f6ff9..bed81c4bca76e 100644 --- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs +++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs @@ -4,8 +4,8 @@ #![allow(warnings)] fn ice() -> impl AsRef { - //~^ ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277] - //[edition2021]~| ERROR: trait objects must include the `dyn` keyword [E0782] + //[edition2015]~^ ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277] + //[edition2021]~^^ ERROR: trait objects must include the `dyn` keyword [E0782] todo!() } diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs index 06c3d9ad434e4..527a4586fd7e0 100644 --- a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs +++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs @@ -4,19 +4,16 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> (impl Debug + '_) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x - //~^ ERROR lifetime may not live long enough } fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x - //~^ ERROR lifetime may not live long enough } fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x - //~^ ERROR lifetime may not live long enough } fn d() -> impl Fn() -> (impl Debug + '_) { diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr index b6857a6c4c51d..443ffeb55cdee 100644 --- a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/impl-fn-hrtb-bounds.rs:22:38 + --> $DIR/impl-fn-hrtb-bounds.rs:19:38 | LL | fn d() -> impl Fn() -> (impl Debug + '_) { | ^^ expected named lifetime parameter @@ -22,57 +22,30 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { | ^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:6:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/impl-fn-hrtb-bounds.rs:10:52 + --> $DIR/impl-fn-hrtb-bounds.rs:9:52 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:10:20 + --> $DIR/impl-fn-hrtb-bounds.rs:9:20 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:12:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/impl-fn-hrtb-bounds.rs:16:52 + --> $DIR/impl-fn-hrtb-bounds.rs:14:52 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:16:20 + --> $DIR/impl-fn-hrtb-bounds.rs:14:20 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:18:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs index a4a1f1dcee120..61303a5b2cb4a 100644 --- a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs +++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs @@ -5,7 +5,6 @@ fn a() -> impl Fn(&u8) -> impl Debug + '_ { //~^ ERROR ambiguous `+` in a type //~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet |x| x - //~^ ERROR lifetime may not live long enough } fn b() -> impl Fn() -> impl Debug + Send { diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index e18e89700b4e9..cf6e5ef7baceb 100644 --- a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -5,7 +5,7 @@ LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)` error: ambiguous `+` in a type - --> $DIR/impl-fn-parsing-ambiguities.rs:11:24 + --> $DIR/impl-fn-parsing-ambiguities.rs:10:24 | LL | fn b() -> impl Fn() -> impl Debug + Send { | ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)` @@ -22,14 +22,5 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^ -error: lifetime may not live long enough - --> $DIR/impl-fn-parsing-ambiguities.rs:7:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-67830.rs b/src/test/ui/impl-trait/issues/issue-67830.rs index 6dc8935c77708..92f7e005dbf0c 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.rs +++ b/src/test/ui/impl-trait/issues/issue-67830.rs @@ -21,8 +21,6 @@ struct A; fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet Wrap(|a| Some(a).into_iter()) - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-67830.stderr b/src/test/ui/impl-trait/issues/issue-67830.stderr index cbc7cd5420139..d3ea8cb0377c7 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.stderr +++ b/src/test/ui/impl-trait/issues/issue-67830.stderr @@ -10,23 +10,5 @@ note: lifetime declared here LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { | ^^ -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - -error: aborting due to 3 previous errors +error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs index f4354d1b2aef0..fde8a6704cc45 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.rs +++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs @@ -18,16 +18,11 @@ fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet &() - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet x - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough - //~| ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr index 99c91d16a6475..8605d07abe943 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -22,71 +22,17 @@ note: lifetime declared here LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/issue-88236-2.rs:25:78 + --> $DIR/issue-88236-2.rs:23:78 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ | note: lifetime declared here - --> $DIR/issue-88236-2.rs:25:45 + --> $DIR/issue-88236-2.rs:23:45 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: lifetime may not live long enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | -- lifetime `'b` defined here -LL | -LL | x - | ^ returning this value requires that `'b` must outlive `'static` - | -help: to declare that `impl for<'a> Hrtb<'a, Assoc = impl Send + 'static>` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { - | ++++ -help: to declare that `impl Send + 'a` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> { - | ++++ - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: aborting due to 8 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-92305.rs b/src/test/ui/impl-trait/issues/issue-92305.rs index 1518c116b3185..4a89238d07e60 100644 --- a/src/test/ui/impl-trait/issues/issue-92305.rs +++ b/src/test/ui/impl-trait/issues/issue-92305.rs @@ -4,11 +4,10 @@ use std::iter; fn f(data: &[T]) -> impl Iterator { //~^ ERROR: missing generics for struct `Vec` [E0107] - iter::empty() //~ ERROR: type annotations needed [E0282] + iter::empty() } fn g(data: &[T], target: T) -> impl Iterator> { - //~^ ERROR: type annotations needed [E0282] f(data).filter(|x| x == target) } diff --git a/src/test/ui/impl-trait/issues/issue-92305.stderr b/src/test/ui/impl-trait/issues/issue-92305.stderr index e8575b76b0930..34d5c2d61dc41 100644 --- a/src/test/ui/impl-trait/issues/issue-92305.stderr +++ b/src/test/ui/impl-trait/issues/issue-92305.stderr @@ -14,24 +14,6 @@ help: add missing generic argument LL | fn f(data: &[T]) -> impl Iterator> { | ~~~~~~ -error[E0282]: type annotations needed - --> $DIR/issue-92305.rs:7:5 - | -LL | iter::empty() - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` - | -help: consider specifying the generic argument - | -LL | iter::empty::() - | +++++ - -error[E0282]: type annotations needed - --> $DIR/issue-92305.rs:10:35 - | -LL | fn g(data: &[T], target: T) -> impl Iterator> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/impl-trait/nested-rpit-hrtb.rs b/src/test/ui/impl-trait/nested-rpit-hrtb.rs index 377658b95c987..a5db10d3a220c 100644 --- a/src/test/ui/impl-trait/nested-rpit-hrtb.rs +++ b/src/test/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,11 +31,9 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet -//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet -//~| ERROR the trait bound `&(): Qux<'static>` is not satisfied // This should resolve. fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {} @@ -45,11 +43,9 @@ fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized // This should resolve. fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} -//~^ ERROR the trait bound `&(): Qux<'b>` is not satisfied // This should resolve. fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} -//~^ ERROR implementation of `Bar` is not general enough // This should resolve. fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {} @@ -60,11 +56,9 @@ fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> // This should resolve. fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} -//~^ ERROR the trait bound `for<'b> &(): Qux<'b>` is not satisfied // `'b` is not in scope for the outlives bound. fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} //~^ ERROR use of undeclared lifetime name `'b` [E0261] -//~| ERROR implementation of `Bar` is not general enough fn main() {} diff --git a/src/test/ui/impl-trait/nested-rpit-hrtb.stderr b/src/test/ui/impl-trait/nested-rpit-hrtb.stderr index fb2a74453574c..3dbe6ebadfbfc 100644 --- a/src/test/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/src/test/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:58:77 + --> $DIR/nested-rpit-hrtb.rs:54:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:66:82 + --> $DIR/nested-rpit-hrtb.rs:61:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,70 +65,18 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:32:78 - | -LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` - error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/nested-rpit-hrtb.rs:36:73 + --> $DIR/nested-rpit-hrtb.rs:35:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:36:44 + --> $DIR/nested-rpit-hrtb.rs:35:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ -error[E0277]: the trait bound `&(): Qux<'static>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:36:64 - | -LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} - | ^^^^^^^^^^^^ the trait `Qux<'static>` is not implemented for `&()` - | - = help: the trait `Qux<'_>` is implemented for `()` - -error[E0277]: the trait bound `&(): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:47:79 - | -LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} - | ^^^^^^^^^^^^ the trait `Qux<'b>` is not implemented for `&()` - | - = help: the trait `Qux<'_>` is implemented for `()` - -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:51:93 - | -LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` - -error[E0277]: the trait bound `for<'b> &(): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:62:64 - | -LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} - | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Qux<'b>` is not implemented for `&()` - | - = help: the trait `Qux<'_>` is implemented for `()` - -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:66:86 - | -LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` - -error: aborting due to 12 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0261, E0277. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. From 86833262df08a5ea5468cd436ea200e5bb2408fa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 11 Nov 2022 10:32:49 +0000 Subject: [PATCH 482/482] Clean-up formatting. --- compiler/rustc_hir_analysis/src/collect/lifetimes.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 895f32114dc29..6ee7aa9cdac6b 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -693,8 +693,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.tcx.sess, lifetime.span, E0657, - "`impl Trait` can only capture lifetimes \ - bound at the fn or impl level" + "`impl Trait` can only capture lifetimes bound at the fn or impl level" ) .emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap()); @@ -704,9 +703,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) = self.tcx.hir().get(parent_id) { let mut err = self.tcx.sess.struct_span_err( - lifetime.span, - "higher kinded lifetime bounds on nested opaque types are not supported yet", - ); + lifetime.span, + "higher kinded lifetime bounds on nested opaque types are not supported yet", + ); err.span_note(self.tcx.def_span(def_id), "lifetime declared here"); err.emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap());