From e7b8d13714f087dbc0bdeb30db2c3b17ea71b99e Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 14:55:15 -0300 Subject: [PATCH 01/11] Ignore println newline in foreign format hints --- compiler/rustc_builtin_macros/src/format.rs | 4 +++- .../format-foreign-dollar-without-spec.stderr | 14 ++++++-------- tests/ui/macros/issue-92267.stderr | 14 ++++++-------- .../trailing-percent-format-hint-issue-158216.rs | 7 +++++++ ...railing-percent-format-hint-issue-158216.stderr | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 tests/ui/macros/trailing-percent-format-hint-issue-158216.rs create mode 100644 tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 007251ff3df05..89ea581d34d60 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -607,6 +607,8 @@ fn make_format_args( // If there's a lot of unused arguments, // let's check if this format arguments looks like another syntax (printf / shell). let detect_foreign_fmt = unused.len() > args.explicit_args().len() / 2; + let foreign_fmt_str = + if append_newline { fmt_str.strip_suffix('\n').unwrap_or(fmt_str) } else { fmt_str }; report_missing_placeholders( ecx, unused, @@ -616,7 +618,7 @@ fn make_format_args( &invalid_refs, detect_foreign_fmt, str_style, - fmt_str, + foreign_fmt_str, uncooked_fmt_str.1.as_str(), fmt_span, ); diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.stderr b/tests/ui/macros/format-foreign-dollar-without-spec.stderr index d5a07c50f00d0..87d86061188af 100644 --- a/tests/ui/macros/format-foreign-dollar-without-spec.stderr +++ b/tests/ui/macros/format-foreign-dollar-without-spec.stderr @@ -2,15 +2,13 @@ error: argument never used --> $DIR/format-foreign-dollar-without-spec.rs:3:25 | LL | println!("%65536$", 1); - | ^ argument never used + | --------- ^ argument never used + | | + | formatting specifier missing | -note: format specifiers use curly braces, and the conversion specifier ` - ` is unknown or unsupported - --> $DIR/format-foreign-dollar-without-spec.rs:3:15 +help: format specifiers use curly braces, consider adding a format specifier | -LL | println!("%65536$", 1); - | ^^^^^^^^ - = note: printf formatting is not supported; see the documentation for `std::fmt` +LL | println!("%65536${}", 1); + | ++ error: aborting due to 1 previous error - diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 4259815328b30..8f8d345f51b5f 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -2,15 +2,13 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | LL | pub fn main() { println!("🦀%%%", 0) } - | ^ argument never used + | ------- ^ argument never used + | | + | formatting specifier missing | -note: format specifiers use curly braces, and the conversion specifier ` - ` is unknown or unsupported - --> $DIR/issue-92267.rs:3:30 +help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%", 0) } - | ^^ - = note: printf formatting is not supported; see the documentation for `std::fmt` +LL | pub fn main() { println!("🦀%%%{}", 0) } + | ++ error: aborting due to 1 previous error - diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs b/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs new file mode 100644 index 0000000000000..bebea2dfe48c6 --- /dev/null +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.rs @@ -0,0 +1,7 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib + +pub fn f(x: f64) { + println!("{x:>8.2}%", "foo"); + //~^ ERROR argument never used +} diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr new file mode 100644 index 0000000000000..2b18d0193441d --- /dev/null +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr @@ -0,0 +1,14 @@ +error: argument never used + --> $DIR/trailing-percent-format-hint-issue-158216.rs:5:27 + | +LL | println!("{x:>8.2}%", "foo"); + | ----------- ^^^^^ argument never used + | | + | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | println!("{x:>8.2}%{}", "foo"); + | ++ + +error: aborting due to 1 previous error From 56dfba726240149fc2e67d4ac37f2d72ebbf0e1c Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 16:50:20 -0300 Subject: [PATCH 02/11] Update foreign format UI baselines --- tests/ui/macros/format-foreign-dollar-without-spec.stderr | 1 + tests/ui/macros/issue-92267.stderr | 5 +++-- .../macros/trailing-percent-format-hint-issue-158216.stderr | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.stderr b/tests/ui/macros/format-foreign-dollar-without-spec.stderr index 87d86061188af..c4c241048abb0 100644 --- a/tests/ui/macros/format-foreign-dollar-without-spec.stderr +++ b/tests/ui/macros/format-foreign-dollar-without-spec.stderr @@ -12,3 +12,4 @@ LL | println!("%65536${}", 1); | ++ error: aborting due to 1 previous error + diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 8f8d345f51b5f..7bbbb28cdacad 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -1,14 +1,15 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | -LL | pub fn main() { println!("🦀%%%", 0) } +LL | pub fn main() { println!("🦀%%%", 0) } //~ ERROR argument never used | ------- ^ argument never used | | | formatting specifier missing | help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%{}", 0) } +LL | pub fn main() { println!("🦀%%%{}", 0) } //~ ERROR argument never used | ++ error: aborting due to 1 previous error + diff --git a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr index 2b18d0193441d..b5c120f939b40 100644 --- a/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr +++ b/tests/ui/macros/trailing-percent-format-hint-issue-158216.stderr @@ -12,3 +12,4 @@ LL | println!("{x:>8.2}%{}", "foo"); | ++ error: aborting due to 1 previous error + From 356c63f036093b4e6e3a8bf4102c106f84f5e21c Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 17:59:29 -0300 Subject: [PATCH 03/11] Correct issue 92267 UI baseline --- tests/ui/macros/issue-92267.stderr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 7bbbb28cdacad..8f8d345f51b5f 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -1,15 +1,14 @@ error: argument never used --> $DIR/issue-92267.rs:3:34 | -LL | pub fn main() { println!("🦀%%%", 0) } //~ ERROR argument never used +LL | pub fn main() { println!("🦀%%%", 0) } | ------- ^ argument never used | | | formatting specifier missing | help: format specifiers use curly braces, consider adding a format specifier | -LL | pub fn main() { println!("🦀%%%{}", 0) } //~ ERROR argument never used +LL | pub fn main() { println!("🦀%%%{}", 0) } | ++ error: aborting due to 1 previous error - From 2a86b91480a420a5bfcdfc3cbb733fc390ab8e72 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Sun, 21 Jun 2026 18:38:02 -0300 Subject: [PATCH 04/11] Update issue 92267 stderr ending --- tests/ui/macros/issue-92267.stderr | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/macros/issue-92267.stderr b/tests/ui/macros/issue-92267.stderr index 8f8d345f51b5f..2318d5d565a1d 100644 --- a/tests/ui/macros/issue-92267.stderr +++ b/tests/ui/macros/issue-92267.stderr @@ -12,3 +12,4 @@ LL | pub fn main() { println!("🦀%%%{}", 0) } | ++ error: aborting due to 1 previous error + From 68632812fe6be9b70f0ae945e74a274ef80b8517 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sun, 21 Jun 2026 12:58:34 +0200 Subject: [PATCH 05/11] Split `resolve_ident_in_module_non_globs_unadjusted` into local and external `module` variants. --- compiler/rustc_resolve/src/ident.rs | 103 ++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2e69405811db4..86d740a93f651 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -23,9 +23,9 @@ use crate::late::{ use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind, - Determinacy, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, LocalModule, Module, - ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, - Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, + Determinacy, ExternModule, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl, + LocalModule, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, + Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics, }; #[derive(Copy, Clone)] @@ -608,21 +608,36 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|f| Finalize { used: Used::Scope, ..f }), ) }; - let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( - module, - ident, - orig_ident_span, - ns, - adjusted_parent_scope, - if matches!(scope_set, ScopeSet::Module(..)) { - Shadowing::Unrestricted - } else { - Shadowing::Restricted - }, - adjusted_finalize, - ignore_decl, - ignore_import, - ); + let shadowing = if matches!(scope_set, ScopeSet::Module(..)) { + Shadowing::Unrestricted + } else { + Shadowing::Restricted + }; + let decl = if module.is_local() { + self.reborrow().resolve_ident_in_local_module_non_globs_unadjusted( + module.expect_local(), + ident, + orig_ident_span, + ns, + adjusted_parent_scope, + shadowing, + adjusted_finalize, + ignore_decl, + ignore_import, + ) + } else { + self.reborrow().resolve_ident_in_extern_module_non_globs_unadjusted( + module.expect_extern(), + ident, + orig_ident_span, + ns, + adjusted_parent_scope, + shadowing, + adjusted_finalize, + ignore_decl, + ) + }; + match decl { Ok(decl) => { if let Some(lint_id) = derive_fallback_lint_id { @@ -1078,10 +1093,49 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`. - fn resolve_ident_in_module_non_globs_unadjusted<'r>( + /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in an external `module`. + fn resolve_ident_in_extern_module_non_globs_unadjusted<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, - module: Module<'ra>, + module: ExternModule<'ra>, + ident: IdentKey, + orig_ident_span: Span, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + shadowing: Shadowing, + finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. + ignore_decl: Option>, + ) -> Result, ControlFlow> { + let key = BindingKey::new(ident, ns); + let resolution = + &*self.resolution(module.to_module(), key).ok_or(ControlFlow::Continue(Determined))?; + + let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl); + + if let Some(finalize) = finalize { + return self.get_mut().finalize_module_binding( + ident, + orig_ident_span, + binding, + parent_scope, + finalize, + shadowing, + ); + } + + // Items and single imports are not shadowable, if we have one, then it's determined. + if let Some(binding) = binding { + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); + return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; + } + Err(ControlFlow::Continue(Determined)) + } + + /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in a local `module`. + fn resolve_ident_in_local_module_non_globs_unadjusted<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + module: LocalModule<'ra>, ident: IdentKey, orig_ident_span: Span, ns: Namespace, @@ -1098,7 +1152,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // doesn't need to be mutable. It will fail when there is a cycle of imports, and without // the exclusive access infinite recursion will crash the compiler with stack overflow. let resolution = &*self - .resolution_or_default(module, key, orig_ident_span) + .resolution_or_default(module.to_module(), key, orig_ident_span) .try_borrow_mut_unchecked() .map_err(|_| ControlFlow::Continue(Determined))?; @@ -1121,11 +1175,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; } - // In extern modules everything is determined from the start. - if !module.is_local() { - return Err(ControlFlow::Continue(Determined)); - }; - // Check if one of single imports can still define the name, block if it can. if self.reborrow().single_import_can_define_name( &resolution, From 0eb146cbab32a8082c2b43df7abaf6ef1113b42d Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:27:27 +0000 Subject: [PATCH 06/11] Extract all instance shim variants into new `ShimKind` enum They tend to have similar handling -- e.g., they should be the only input to the `mir_shims` query -- so it's cleaner to group them together. This will also make potential future refactorings easier, such as only carrying `GenericArgsRef` for instances that actually use it (e.g., `Item`) but not others (e.g., `CloneShim`). Many of the shim variants still have `Shim` at the end of their names. To make the refactoring easier and keep the diff clean, I will trim those suffixes off in the next commit. --- .../rustc_codegen_cranelift/src/abi/mod.rs | 6 +- .../rustc_codegen_cranelift/src/constant.rs | 2 +- .../src/back/symbol_export.rs | 18 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../rustc_const_eval/src/interpret/call.rs | 26 +- .../rustc_const_eval/src/interpret/step.rs | 2 +- .../src/middle/codegen_fn_attrs.rs | 11 +- .../src/middle/exported_symbols.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 8 +- compiler/rustc_middle/src/mir/pretty.rs | 8 +- compiler/rustc_middle/src/mir/visit.rs | 30 +-- compiler/rustc_middle/src/mono.rs | 30 +-- compiler/rustc_middle/src/queries.rs | 4 +- compiler/rustc_middle/src/query/keys.rs | 6 + compiler/rustc_middle/src/ty/instance.rs | 237 +++++++++++------- compiler/rustc_middle/src/ty/mod.rs | 21 +- compiler/rustc_middle/src/ty/print/mod.rs | 57 +++-- .../rustc_mir_transform/src/coroutine/drop.rs | 2 +- .../rustc_mir_transform/src/coroutine/mod.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 33 +-- .../rustc_mir_transform/src/inline/cycle.rs | 26 +- compiler/rustc_mir_transform/src/shim.rs | 88 +++---- .../src/shim/async_destructor_ctor.rs | 20 +- compiler/rustc_monomorphize/src/collector.rs | 34 +-- .../rustc_monomorphize/src/partitioning.rs | 60 ++--- .../src/unstable/convert/stable/ty.rs | 13 +- .../rustc_public_bridge/src/context/impls.rs | 2 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 7 +- .../rustc_sanitizers/src/kcfi/typeid/mod.rs | 5 +- compiler/rustc_symbol_mangling/src/legacy.rs | 21 +- compiler/rustc_symbol_mangling/src/v0.rs | 32 ++- compiler/rustc_ty_utils/src/abi.rs | 40 +-- compiler/rustc_ty_utils/src/instance.rs | 59 +++-- 34 files changed, 502 insertions(+), 416 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 0eb493036ce51..8f965a5ef7b12 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -16,9 +16,9 @@ use rustc_abi::{CanonAbi, ExternAbi, X86Call}; use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{ShimKind, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; @@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, // it is `func returning noop future` - InstanceKind::DropGlue(_, None) => { + InstanceKind::Shim(ShimKind::DropGlue(_, None)) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -725,7 +725,7 @@ pub(crate) fn codegen_drop<'tcx>( let ret_block = fx.get_block(target); // AsyncDropGlueCtorShim can't be here - if let ty::InstanceKind::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_instance.def { // we don't actually need to drop anything fx.bcx.ins().jump(ret_block, &[]); } else { diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index c986666f9c46e..a83bfd1cbad42 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 014fd5cf3a0e5..40d5c3b07059f 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -11,7 +11,9 @@ use rustc_middle::middle::exported_symbols::{ ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, }; use rustc_middle::query::LocalCrate; -use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, GenericArgKind, GenericArgsRef, Instance, ShimKind, SymbolName, Ty, TyCtxt, +}; use rustc_middle::util::Providers; use rustc_session::config::CrateType; use rustc_span::Span; @@ -332,7 +334,10 @@ fn exported_generic_symbols_provider_local<'tcx>( )); } } - MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => { + MonoItem::Fn(Instance { + def: InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))), + args, + }) => { // A little sanity-check assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty))); @@ -356,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>( } } MonoItem::Fn(Instance { - def: InstanceKind::AsyncDropGlueCtorShim(_, ty), + def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)), args, }) => { // A little sanity-check @@ -371,7 +376,10 @@ fn exported_generic_symbols_provider_local<'tcx>( }, )); } - MonoItem::Fn(Instance { def: InstanceKind::AsyncDropGlue(def, ty), args: _ }) => { + MonoItem::Fn(Instance { + def: InstanceKind::Shim(ShimKind::AsyncDropGlue(def, ty)), + args: _, + }) => { symbols.push(( ExportedSymbol::AsyncDropGlue(def, ty), SymbolExportInfo { @@ -578,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }, instantiating_crate, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d4932adeda1f9..8d8b950a125ea 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -618,7 +618,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = self.monomorphize(ty); let drop_fn = Instance::resolve_drop_glue(bx.tcx(), ty); - if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = drop_fn.def { // we don't actually need to drop anything. return helper.funclet_br(self, bx, target, mergeable_succ, &[]); } @@ -934,7 +934,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match instance.def { // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, // it is `func returning noop future` - ty::InstanceKind::DropGlue(_, None) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { // Empty drop glue; a no-op. let target = target.unwrap(); return helper.funclet_br(self, bx, target, mergeable_succ, &[]); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index deb8ca12b059d..c1ee7c02e874e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -665,7 +665,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }; let fn_ptr = bx.get_fn_addr(instance); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 85da687d8af37..0236b49e497e4 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -428,7 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Determine whether this is a non-capturing closure. That's relevant as their first // argument can be skipped (and that's the only kind of argument skipping we allow). let is_non_capturing_closure = - (matches!(instance.def, ty::InstanceKind::ClosureOnceShim { .. }) + (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. })) || self.tcx.is_closure_like(def_id)) && { let arg = &callee_fn_abi.args[0]; @@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::FutureDropPollShim(..) + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) | ty::InstanceKind::Item(_) => { // We need MIR for this fn. // Note that this can be an intrinsic, if we are executing its fallback body. diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b865cafa38647..1aeaaee3a251c 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -607,7 +607,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { enter_trace_span!(M, resolve::resolve_drop_glue, ty = ?place.layout.ty); Instance::resolve_drop_glue(*self.tcx, place.layout.ty) }; - if let ty::InstanceKind::DropGlue(_, None) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) = instance.def { // This is the branch we enter if and only if the dropped type has no drop glue // whatsoever. This can happen as a result of monomorphizing a drop of a // generic. In order to make sure that generic and non-generic code behaves diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 9b78c31871fd7..eefb346d174b4 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -8,7 +8,7 @@ use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; use crate::mono::Visibility; -use crate::ty::{InstanceKind, TyCtxt}; +use crate::ty::{InstanceKind, ShimKind, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { pub fn codegen_instance_attrs( @@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> { // // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, // and therefore can be skipped here. - if let InstanceKind::ReifyShim(_, _) = instance_kind + if let InstanceKind::Shim(ShimKind::ReifyShim(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { @@ -54,8 +54,11 @@ impl<'tcx> TyCtxt<'tcx> { } // Ensure closure shims have the optimization properties of their closure applied to them. - if let InstanceKind::ClosureOnceShim { call_once: _, closure, track_caller: _ } = - instance_kind + if let InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once: _, + closure, + track_caller: _, + }) = instance_kind { let closure_attrs = self.codegen_fn_attrs(closure); attrs.to_mut().optimize = closure_attrs.optimize; diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index fb770076f0a26..5942f9dfa1def 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -75,7 +75,7 @@ impl<'tcx> ExportedSymbol<'tcx> { tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) } ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { - def: ty::InstanceKind::ThreadLocalShim(def_id), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), args: ty::GenericArgs::empty(), }), ExportedSymbol::NoDefId(symbol_name) => symbol_name, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c12e72d1dce0f..23e6fc15c2ede 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -32,8 +32,8 @@ use crate::mir::interpret::{AllocRange, Scalar}; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::{ - self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypeVisitableExt, - TypingEnv, UserTypeAnnotationIndex, + self, GenericArg, GenericArgsRef, Instance, InstanceKind, List, ShimKind, Ty, TyCtxt, + TypeVisitableExt, TypingEnv, UserTypeAnnotationIndex, }; mod basic_blocks; @@ -131,6 +131,10 @@ impl<'tcx> MirSource<'tcx> { MirSource { instance, promoted: None } } + pub fn from_shim(shim: ShimKind<'tcx>) -> Self { + MirSource { instance: InstanceKind::Shim(shim), promoted: None } + } + #[inline] pub fn def_id(&self) -> DefId { self.instance.def_id() diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 942c36f343343..1c7d261dd5978 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -218,7 +218,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { // All drop shims have the same DefId, so we have to add the type // to get unique file names. let shim_disambiguator = match source.instance { - ty::InstanceKind::DropGlue(_, Some(ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) => { // Unfortunately, pretty-printed types are not very filename-friendly. // We do some filtering. let mut s = ".".to_owned(); @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) => { let mut s = ".".to_owned(); s.extend(ty.to_string().chars().filter_map(|c| match c { ' ' => None, @@ -238,7 +238,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::AsyncDropGlue(_, ty) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) => { let ty::Coroutine(_, args) = ty.kind() else { bug!(); }; @@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::FutureDropPollShim(_, proxy_cor, impl_cor) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, proxy_cor, impl_cor)) => { let mut s = ".".to_owned(); s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { ' ' => None, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index fb89e9ac884a0..35c47b761c5d4 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -347,27 +347,27 @@ macro_rules! make_mir_visitor { ty::InstanceKind::Item(_def_id) => {} ty::InstanceKind::Intrinsic(_def_id) - | ty::InstanceKind::VTableShim(_def_id) - | ty::InstanceKind::ReifyShim(_def_id, _) + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_def_id, _)) | ty::InstanceKind::Virtual(_def_id, _) - | ty::InstanceKind::ThreadLocalShim(_def_id) - | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ } - | ty::InstanceKind::ConstructCoroutineInClosureShim { + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, receiver_by_ref: _, - } - | ty::InstanceKind::DropGlue(_def_id, None) => {} - - ty::InstanceKind::FnPtrShim(_def_id, ty) - | ty::InstanceKind::DropGlue(_def_id, Some(ty)) - | ty::InstanceKind::CloneShim(_def_id, ty) - | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) - | ty::InstanceKind::AsyncDropGlue(_def_id, ty) - | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, ty) => { + }) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, None)) => {} + + ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, Some(ty))) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_def_id, ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - ty::InstanceKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty)) => { self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); } diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 2c1a9d1ed7bfb..054b3e9a49680 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -22,7 +22,7 @@ use tracing::debug; use crate::dep_graph::dep_node::{make_compile_codegen_unit, make_compile_mono_item}; use crate::dep_graph::{DepNode, WorkProduct, WorkProductId}; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::ty::{self, GenericArgs, Instance, InstanceKind, SymbolName, Ty, TyCtxt}; +use crate::ty::{self, GenericArgs, Instance, InstanceKind, ShimKind, SymbolName, Ty, TyCtxt}; /// Describes how a monomorphization will be instantiated in object files. #[derive(PartialEq)] @@ -173,7 +173,7 @@ impl<'tcx> MonoItem<'tcx> { // incrementality (which wants small CGUs with as many things GloballyShared as possible). // The heuristics implemented here do better than a completely naive approach in the // compiler benchmark suite, but there is no reason to believe they are optimal. - if let InstanceKind::DropGlue(_, Some(ty)) = instance.def { + if let InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) = instance.def { if tcx.sess.opts.optimize == OptLevel::No { return InstantiationMode::GloballyShared { may_conflict: false }; } @@ -523,20 +523,20 @@ impl<'tcx> CodegenUnit<'tcx> { match item { MonoItem::Fn(ref instance) => match instance.def { InstanceKind::Item(def) => def.as_local().map(|_| def), - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::Intrinsic(..) - | InstanceKind::FnPtrShim(..) + InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) - | InstanceKind::AsyncDropGlue(..) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => None, + | InstanceKind::Shim(ShimKind::VTableShim(..)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => None, }, MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id), MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.to_def_id()), diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index d4817888468fa..9370890c399ec 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1400,10 +1400,10 @@ rustc_queries! { } /// Generates a MIR body for the shim. - query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { + query mir_shims(key: ty::ShimKind<'tcx>) -> &'tcx mir::Body<'tcx> { arena_cache desc { - "generating MIR shim for `{}`, instance={:?}", + "generating MIR shim for `{}`, kind={:?}", tcx.def_path_str(key.def_id()), key } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 346a26a685317..bbb92ee7e716b 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -63,6 +63,12 @@ impl QueryKey for () { } } +impl<'tcx> QueryKey for ty::ShimKind<'tcx> { + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.def_id()) + } +} + impl<'tcx> QueryKey for ty::InstanceKind<'tcx> { fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8734d2cde8152..2fc2a4a23c88c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -75,6 +75,22 @@ pub enum InstanceKind<'tcx> { /// caller. Intrinsic(DefId), + /// Dynamic dispatch to `::fn`. + /// + /// This `InstanceKind` may have a callable MIR as the default implementation. + /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. + /// *This means we might not know exactly what is being called.* + /// + /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more + /// details on that). + Virtual(DefId, usize), + + Shim(ShimKind<'tcx>), +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable, Lift)] +pub enum ShimKind<'tcx> { /// `::method` where `method` receives unsizeable `self: Self` (part of the /// `unsized_fn_params` feature). /// @@ -106,16 +122,6 @@ pub enum InstanceKind<'tcx> { /// `DefId` is `FnTrait::call_*`. FnPtrShim(DefId, Ty<'tcx>), - /// Dynamic dispatch to `::fn`. - /// - /// This `InstanceKind` may have a callable MIR as the default implementation. - /// Calls to `Virtual` instances must be codegen'd as virtual calls through the vtable. - /// *This means we might not know exactly what is being called.* - /// - /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more - /// details on that). - Virtual(DefId, usize), - /// `<[FnMut/Fn closure] as FnOnce>::call_once`. /// /// The `DefId` is the ID of the `call_once` method in `FnOnce`. @@ -228,10 +234,12 @@ impl<'tcx> Instance<'tcx> { InstanceKind::Item(def) => tcx .upstream_monomorphizations_for(def) .and_then(|monos| monos.get(&self.args).cloned()), - InstanceKind::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args), - InstanceKind::AsyncDropGlue(_, _) => None, - InstanceKind::FutureDropPollShim(_, _, _) => None, - InstanceKind::AsyncDropGlueCtorShim(_, _) => { + InstanceKind::Shim(ShimKind::DropGlue(_, Some(_))) => { + tcx.upstream_drop_glue_for(self.args) + } + InstanceKind::Shim(ShimKind::AsyncDropGlue(_, _)) => None, + InstanceKind::Shim(ShimKind::FutureDropPollShim(_, _, _)) => None, + InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, _)) => { tcx.upstream_async_drop_glue_for(self.args) } _ => None, @@ -244,45 +252,18 @@ impl<'tcx> InstanceKind<'tcx> { pub fn def_id(self) -> DefId { match self { InstanceKind::Item(def_id) - | InstanceKind::VTableShim(def_id) - | InstanceKind::ReifyShim(def_id, _) - | InstanceKind::FnPtrShim(def_id, _) | InstanceKind::Virtual(def_id, _) - | InstanceKind::Intrinsic(def_id) - | InstanceKind::ThreadLocalShim(def_id) - | InstanceKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } - | ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id: def_id, - receiver_by_ref: _, - } - | InstanceKind::DropGlue(def_id, _) - | InstanceKind::CloneShim(def_id, _) - | InstanceKind::FnPtrAddrShim(def_id, _) - | InstanceKind::FutureDropPollShim(def_id, _, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | InstanceKind::Intrinsic(def_id) => def_id, + InstanceKind::Shim(shim) => shim.def_id(), } } /// Returns the `DefId` of instances which might not require codegen locally. pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { - ty::InstanceKind::Item(def) => Some(def), - ty::InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::FutureDropPollShim(def_id, ..) - | InstanceKind::ThreadLocalShim(def_id) => Some(def_id), - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::Virtual(..) - | InstanceKind::Intrinsic(..) - | InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::FnPtrAddrShim(..) => None, + InstanceKind::Item(def) => Some(def), + InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => None, + InstanceKind::Shim(shim) => shim.def_id_if_not_guaranteed_local_codegen(), } } @@ -293,31 +274,28 @@ impl<'tcx> InstanceKind<'tcx> { /// `generates_cgu_internal_copy` for more information. pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; - let def_id = match *self { - ty::InstanceKind::Item(def) => def, - ty::InstanceKind::DropGlue(_, Some(ty)) => return ty.is_array(), - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => return ty.is_coroutine(), - ty::InstanceKind::FutureDropPollShim(_, _, _) => return false, - ty::InstanceKind::AsyncDropGlue(_, _) => return false, - ty::InstanceKind::ThreadLocalShim(_) => return false, - _ => return true, - }; - matches!( - tcx.def_key(def_id).disambiguated_data.data, - DefPathData::Ctor | DefPathData::Closure - ) + match *self { + InstanceKind::Item(def_id) => matches!( + tcx.def_key(def_id).disambiguated_data.data, + DefPathData::Ctor | DefPathData::Closure + ), + InstanceKind::Shim(shim) => shim.requires_inline(), + InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => true, + } } pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) - | InstanceKind::VTableShim(def_id) => { + | InstanceKind::Shim(ShimKind::VTableShim(def_id)) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } - InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller } => { - track_caller - } + InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once: _, + closure: _, + track_caller, + }) => track_caller, _ => false, } } @@ -330,22 +308,79 @@ impl<'tcx> InstanceKind<'tcx> { /// body should perform necessary instantiations. pub fn has_polymorphic_mir_body(&self) -> bool { match *self { - InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::DropGlue(_, Some(_)) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlue(_, _) => false, - InstanceKind::AsyncDropGlueCtorShim(_, _) => false, - InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::Item(_) - | InstanceKind::Intrinsic(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::Virtual(..) - | InstanceKind::VTableShim(..) => true, + InstanceKind::Item(_) | InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) => true, + InstanceKind::Shim(shim) => shim.has_polymorphic_mir_body(), + } + } +} + +impl<'tcx> ShimKind<'tcx> { + #[inline] + pub fn def_id(self) -> DefId { + match self { + ShimKind::VTableShim(def_id) + | ShimKind::ReifyShim(def_id, _) + | ShimKind::FnPtrShim(def_id, _) + | ShimKind::ThreadLocalShim(def_id) + | ShimKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } + | ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id: def_id, + receiver_by_ref: _, + } + | ShimKind::DropGlue(def_id, _) + | ShimKind::CloneShim(def_id, _) + | ShimKind::FnPtrAddrShim(def_id, _) + | ShimKind::FutureDropPollShim(def_id, _, _) + | ShimKind::AsyncDropGlue(def_id, _) + | ShimKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + } + } + + /// Returns the `DefId` of instances which might not require codegen locally. + pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { + match self { + ShimKind::DropGlue(def_id, Some(_)) + | ShimKind::AsyncDropGlueCtorShim(def_id, _) + | ShimKind::AsyncDropGlue(def_id, _) + | ShimKind::FutureDropPollShim(def_id, ..) + | ShimKind::ThreadLocalShim(def_id) => Some(def_id), + ShimKind::VTableShim(..) + | ShimKind::ReifyShim(..) + | ShimKind::FnPtrShim(..) + | ShimKind::ClosureOnceShim { .. } + | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::DropGlue(..) + | ShimKind::CloneShim(..) + | ShimKind::FnPtrAddrShim(..) => None, + } + } + + pub fn requires_inline(&self) -> bool { + match self { + ShimKind::DropGlue(_, Some(ty)) => ty.is_array(), + ShimKind::AsyncDropGlueCtorShim(_, ty) => ty.is_coroutine(), + ShimKind::FutureDropPollShim(_, _, _) => false, + ShimKind::AsyncDropGlue(_, _) => false, + ShimKind::ThreadLocalShim(_) => false, + _ => true, + } + } + + pub fn has_polymorphic_mir_body(&self) -> bool { + match *self { + ShimKind::CloneShim(..) + | ShimKind::ThreadLocalShim(..) + | ShimKind::FnPtrAddrShim(..) + | ShimKind::FnPtrShim(..) + | ShimKind::DropGlue(_, Some(_)) + | ShimKind::FutureDropPollShim(..) + | ShimKind::AsyncDropGlue(_, _) => false, + ShimKind::AsyncDropGlueCtorShim(_, _) => false, + ShimKind::ClosureOnceShim { .. } + | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::DropGlue(..) + | ShimKind::ReifyShim(..) + | ShimKind::VTableShim(..) => true, } } } @@ -416,7 +451,11 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { continue; } else { return Instance { - def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + poll_def_id, + first_cor, + cor_ty, + )), args: proxy_args, }; } @@ -426,12 +465,16 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { }; if first_cor != cor_ty { return Instance { - def: ty::InstanceKind::FutureDropPollShim(poll_def_id, first_cor, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + poll_def_id, + first_cor, + cor_ty, + )), args: proxy_args, }; } else { return Instance { - def: ty::InstanceKind::AsyncDropGlue(poll_def_id, cor_ty), + def: ty::InstanceKind::Shim(ShimKind::AsyncDropGlue(poll_def_id, cor_ty)), args: child_args, }; } @@ -599,11 +642,11 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceKind::ReifyShim(def, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); } InstanceKind::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); - resolved.def = InstanceKind::ReifyShim(def_id, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)); } _ if tcx.sess.is_sanitizer_kcfi_enabled() => { // Reify `::call`-like method implementations @@ -611,7 +654,10 @@ impl<'tcx> Instance<'tcx> { // Reroute through a reify via the *unresolved* instance. The resolved one can't // be directly reified because it's closure-like. The reify can handle the // unresolved instance. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } + resolved = Instance { + def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + args, + } // Reify `Trait::method` implementations if the trait is dyn-compatible. } else if let Some(assoc) = tcx.opt_associated_item(def_id) && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = @@ -620,7 +666,8 @@ impl<'tcx> Instance<'tcx> { { // If this function could also go in a vtable, we need to `ReifyShim` it with // KCFI because it can only attach one type per function. - resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason) + resolved.def = + InstanceKind::Shim(ShimKind::ReifyShim(resolved.def_id(), reason)) } } _ => {} @@ -645,7 +692,7 @@ impl<'tcx> Instance<'tcx> { if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - return Instance { def: InstanceKind::VTableShim(def_id), args }; + return Instance { def: InstanceKind::Shim(ShimKind::VTableShim(def_id)), args }; } let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); @@ -688,19 +735,22 @@ impl<'tcx> Instance<'tcx> { // Create a shim for the `FnOnce/FnMut/Fn` method we are calling // - unlike functions, invoking a closure always goes through a // trait. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }; + resolved = Instance { + def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + args, + }; } else { debug!( " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceKind::ReifyShim(def, reason); + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); } } } InstanceKind::Virtual(def_id, _) => { debug!(" => vtable fn pointer created for virtual call"); - resolved.def = InstanceKind::ReifyShim(def_id, reason) + resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)) } _ => {} } @@ -770,8 +820,11 @@ impl<'tcx> Instance<'tcx> { .def_id; let track_caller = tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); - let def = - ty::InstanceKind::ClosureOnceShim { call_once, closure: closure_did, track_caller }; + let def = ty::InstanceKind::Shim(ShimKind::ClosureOnceShim { + call_once, + closure: closure_did, + track_caller, + }); let self_ty = Ty::new_closure(tcx, closure_did, args); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 10a5f380d4c80..8e51007edfdfe 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -85,7 +85,7 @@ pub use self::context::{ CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, }; pub use self::fold::*; -pub use self::instance::{Instance, InstanceKind, ReifyReason}; +pub use self::instance::{Instance, InstanceKind, ReifyReason, ShimKind}; pub(crate) use self::list::RawList; pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::opaque_types::OpaqueTypeKey; @@ -1802,20 +1802,9 @@ impl<'tcx> TyCtxt<'tcx> { _ => self.optimized_mir(def), } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::Intrinsic(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) - | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance), + ty::InstanceKind::Intrinsic(..) => bug!("intrinsics have no instance MIR"), + ty::InstanceKind::Virtual(..) => bug!("virtual dispatches have no instance MIR"), + ty::InstanceKind::Shim(shim) => self.mir_shims(shim), }; assert!( @@ -1941,7 +1930,7 @@ impl<'tcx> TyCtxt<'tcx> { if args[0].has_placeholders() || args[0].has_non_region_param() { return Err(self.layout_error(LayoutError::TooGeneric(ty()))); } - let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); + let instance = ShimKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); self.mir_shims(instance) .coroutine_layout_raw() .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty()))) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 29875a3530c15..0552bf1dd1636 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -367,35 +367,44 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::Instance<'tcx> { cx.print_def_path(self.def_id(), self.args)?; match self.def { ty::InstanceKind::Item(_) => {} - ty::InstanceKind::VTableShim(_) => cx.write_str(" - shim(vtable)")?, - ty::InstanceKind::ReifyShim(_, None) => cx.write_str(" - shim(reify)")?, - ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { - cx.write_str(" - shim(reify-fnptr)")? - } - ty::InstanceKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { - cx.write_str(" - shim(reify-vtable)")? - } - ty::InstanceKind::ThreadLocalShim(_) => cx.write_str(" - shim(tls)")?, ty::InstanceKind::Intrinsic(_) => cx.write_str(" - intrinsic")?, ty::InstanceKind::Virtual(_, num) => cx.write_str(&format!(" - virtual#{num}"))?, - ty::InstanceKind::FnPtrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::ClosureOnceShim { .. } => cx.write_str(" - shim")?, - ty::InstanceKind::ConstructCoroutineInClosureShim { .. } => cx.write_str(" - shim")?, - ty::InstanceKind::DropGlue(_, None) => cx.write_str(" - shim(None)")?, - ty::InstanceKind::DropGlue(_, Some(ty)) => { - cx.write_str(&format!(" - shim(Some({ty}))"))? + ty::InstanceKind::Shim(shim) => { + cx.write_str(" - ")?; + shim.print(cx)?; } - ty::InstanceKind::CloneShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { - cx.write_str(&format!(" - dropshim({proxy_ty}-{impl_ty})"))? + } + Ok(()) + } +} + +impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::ShimKind<'tcx> { + fn print(&self, cx: &mut P) -> Result<(), PrintError> { + match self { + ty::ShimKind::VTableShim(_) => cx.write_str("shim(vtable)"), + ty::ShimKind::ReifyShim(_, None) => cx.write_str("shim(reify)"), + ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { + cx.write_str("shim(reify-fnptr)") } - ty::InstanceKind::AsyncDropGlue(_, ty) => cx.write_str(&format!(" - shim({ty})"))?, - ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) => { - cx.write_str(&format!(" - shim(Some({ty}))"))? + ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { + cx.write_str("shim(reify-vtable)") } - }; - Ok(()) + ty::ShimKind::ThreadLocalShim(_) => cx.write_str("shim(tls)"), + ty::ShimKind::FnPtrShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::ClosureOnceShim { .. } => cx.write_str("shim"), + ty::ShimKind::ConstructCoroutineInClosureShim { .. } => cx.write_str("shim"), + ty::ShimKind::DropGlue(_, None) => cx.write_str("shim(None)"), + ty::ShimKind::DropGlue(_, Some(ty)) => cx.write_str(&format!("shim(Some({ty}))")), + ty::ShimKind::CloneShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { + cx.write_str(&format!("dropshim({proxy_ty}-{impl_ty})")) + } + ty::ShimKind::AsyncDropGlue(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::AsyncDropGlueCtorShim(_, ty) => { + cx.write_str(&format!("shim(Some({ty}))")) + } + } } } diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 5be6887e937a1..41b973476af94 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -206,7 +206,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( // Update the body's def to become the drop glue. let coroutine_instance = body.source.instance; let drop_glue = tcx.require_lang_item(LangItem::DropGlue, body.span); - let drop_instance = InstanceKind::DropGlue(drop_glue, Some(coroutine_ty)); + let drop_instance = InstanceKind::Shim(ShimKind::DropGlue(drop_glue, Some(coroutine_ty))); // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible // filename. diff --git a/compiler/rustc_mir_transform/src/coroutine/mod.rs b/compiler/rustc_mir_transform/src/coroutine/mod.rs index bb57ca1cd90a7..53283680c0966 100644 --- a/compiler/rustc_mir_transform/src/coroutine/mod.rs +++ b/compiler/rustc_mir_transform/src/coroutine/mod.rs @@ -71,7 +71,7 @@ use rustc_index::{Idx, IndexVec, indexvec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{ - self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt, + self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, ShimKind, Ty, TyCtxt, }; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::always_storage_live_locals; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index df71cd48a77fe..a1575a21e9073 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -15,7 +15,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{ - self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, + self, Instance, InstanceKind, ShimKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, }; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::Spanned; @@ -739,18 +739,21 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // the correct param-env for types being dropped. Stall resolving // the MIR for this instance until all of its const params are // substituted. - InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { + InstanceKind::Shim(ShimKind::DropGlue(_, Some(ty))) + if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => + { debug!("still needs substitution"); return Err("implementation limitation -- HACK for dropping polymorphic type"); } - InstanceKind::AsyncDropGlue(_, ty) | InstanceKind::AsyncDropGlueCtorShim(_, ty) => { + InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)) => { return if ty.still_further_specializable() { Err("still needs substitution") } else { Ok(()) }; } - InstanceKind::FutureDropPollShim(_, ty, ty2) => { + InstanceKind::Shim(ShimKind::FutureDropPollShim(_, ty, ty2)) => { return if ty.still_further_specializable() || ty2.still_further_specializable() { Err("still needs substitution") } else { @@ -762,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue // inlining a second time. - InstanceKind::VTableShim(_) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::ThreadLocalShim(..) - | InstanceKind::FnPtrAddrShim(..) => return Ok(()), + InstanceKind::Shim(ShimKind::VTableShim(_)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Ok(()), } if inliner.tcx().is_constructor(callee_def_id) { @@ -1370,8 +1373,8 @@ fn try_instance_mir<'tcx>( tcx: TyCtxt<'tcx>, instance: InstanceKind<'tcx>, ) -> Result<&'tcx Body<'tcx>, &'static str> { - if let ty::InstanceKind::DropGlue(_, Some(ty)) | ty::InstanceKind::AsyncDropGlueCtorShim(_, ty) = - instance + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) = instance && let ty::Adt(def, args) = ty.kind() { let fields = def.all_fields(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 9d031b6548021..0fd1a5f240758 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -4,7 +4,7 @@ use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::limit::Limit; use rustc_middle::mir::TerminatorKind; -use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, ShimKind, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use tracing::{instrument, trace}; @@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause // a cycle that way - InstanceKind::VTableShim(_) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::ThreadLocalShim { .. } - | InstanceKind::CloneShim(..) => {} + InstanceKind::Shim(ShimKind::VTableShim(_)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::ThreadLocalShim { .. }) + | InstanceKind::Shim(ShimKind::CloneShim(..)) => {} // This shim does not call any other functions, thus there can be no recursion. - InstanceKind::FnPtrAddrShim(..) => return false, + InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return false, // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. - InstanceKind::DropGlue(..) - | InstanceKind::FutureDropPollShim(..) - | InstanceKind::AsyncDropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => { + InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { if callee.has_param() { return false; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 6d9b8feea05f4..d6061edb74ce3 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -31,16 +31,15 @@ pub(super) fn provide(providers: &mut Providers) { providers.mir_shims = make_shim; } -fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> { - debug!("make_shim({:?})", instance); +fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { + debug!("make_shim({:?})", shim); - let mut result = match instance { - ty::InstanceKind::Item(..) => bug!("item {:?} passed to make_shim", instance), - ty::InstanceKind::VTableShim(def_id) => { + let mut result = match shim { + ty::ShimKind::VTableShim(def_id) => { let adjustment = Adjustment::Deref { source: DerefSource::MutPtr }; - build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id)) + build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id)) } - ty::InstanceKind::FnPtrShim(def_id, ty) => { + ty::ShimKind::FnPtrShim(def_id, ty) => { let trait_ = tcx.parent(def_id); // Supports `Fn` or `async Fn` traits. let adjustment = match tcx @@ -53,17 +52,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< None => bug!("fn pointer {:?} is not an fn", ty), }; - build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect(ty)) + build_call_shim(tcx, shim, Some(adjustment), CallKind::Indirect(ty)) } // We are generating a call back to our def-id, which the // codegen backend knows to turn to an actual call, be it // a virtual call, or a direct call to a function for which // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). - ty::InstanceKind::ReifyShim(def_id, _) => { - build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) + ty::ShimKind::ReifyShim(def_id, _) => { + build_call_shim(tcx, shim, None, CallKind::Direct(def_id)) } - ty::InstanceKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { + ty::ShimKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) @@ -72,15 +71,15 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< .unwrap() .def_id; - build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) + build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::InstanceKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id, receiver_by_ref, } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), - ty::InstanceKind::DropGlue(def_id, ty) => { + ty::ShimKind::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end // of this function. Is this intentional? if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) { @@ -110,7 +109,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args).skip_norm_wip(); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); pm::run_passes( tcx, @@ -129,10 +128,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id)) } - ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance), - ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), - ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), - ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { + ty::ShimKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, shim), + ty::ShimKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), + ty::ShimKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), + ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { let mut body = async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); @@ -148,10 +147,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< pm::Optimizations::Allowed, ); run_optimization_passes(tcx, &mut body); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::AsyncDropGlue(def_id, ty) => { + ty::ShimKind::AsyncDropGlue(def_id, ty) => { let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty); // Main pass required here is StateTransform to convert sync drop ladder @@ -170,23 +169,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< Some(MirPhase::Runtime(RuntimePhase::PostCleanup)), ); run_optimization_passes(tcx, &mut body); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => { + ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty) => { let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); - debug!("make_shim({:?}) = {:?}", instance, body); + debug!("make_shim({:?}) = {:?}", shim, body); return body; } - ty::InstanceKind::Virtual(..) => { - bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance) - } - ty::InstanceKind::Intrinsic(_) => { - bug!("creating shims from intrinsics ({:?}) is unsupported", instance) - } }; - debug!("make_shim({:?}) = untransformed {:?}", instance, result); + debug!("make_shim({:?}) = untransformed {:?}", shim, result); deref_finder(tcx, &mut result, false); @@ -211,7 +204,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< Some(MirPhase::Runtime(RuntimePhase::Optimized)), ); - debug!("make_shim({:?}) = {:?}", instance, result); + debug!("make_shim({:?}) = {:?}", shim, result); result } @@ -300,7 +293,7 @@ pub fn build_drop_shim<'tcx>( } block(&mut blocks, TerminatorKind::Return); - let source = MirSource::from_instance(ty::InstanceKind::DropGlue(def_id, ty)); + let source = MirSource::from_shim(ty::ShimKind::DropGlue(def_id, ty)); let mut body = new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); @@ -480,11 +473,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } } -fn build_thread_local_shim<'tcx>( - tcx: TyCtxt<'tcx>, - instance: ty::InstanceKind<'tcx>, -) -> Body<'tcx> { - let def_id = instance.def_id(); +fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { + let def_id = shim.def_id(); let span = tcx.def_span(def_id); let source_info = SourceInfo::outermost(span); @@ -502,7 +492,7 @@ fn build_thread_local_shim<'tcx>( )]); new_body( - MirSource::from_instance(instance), + MirSource::from_shim(shim), blocks, IndexVec::from_raw(vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]), 0, @@ -565,7 +555,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { } fn into_mir(self) -> Body<'tcx> { - let source = MirSource::from_instance(ty::InstanceKind::CloneShim( + let source = MirSource::from_shim(ty::ShimKind::CloneShim( self.def_id, self.sig.inputs_and_output[0], )); @@ -776,14 +766,14 @@ impl<'tcx> CloneShimBuilder<'tcx> { #[instrument(level = "debug", skip(tcx), ret)] fn build_call_shim<'tcx>( tcx: TyCtxt<'tcx>, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, rcvr_adjustment: Option, call_kind: CallKind<'tcx>, ) -> Body<'tcx> { // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used // to instantiate into the signature of the shim. It is not necessary for users of this // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`). - let (sig_args, untuple_args) = if let ty::InstanceKind::FnPtrShim(_, ty) = instance { + let (sig_args, untuple_args) = if let ty::ShimKind::FnPtrShim(_, ty) = shim { let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); let untuple_args = sig.inputs(); @@ -796,12 +786,12 @@ fn build_call_shim<'tcx>( (None, None) }; - let def_id = instance.def_id(); + let def_id = shim.def_id(); let sig = tcx.fn_sig(def_id); let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); - assert_eq!(sig_args.is_some(), !instance.has_polymorphic_mir_body()); + assert_eq!(sig_args.is_some(), !shim.has_polymorphic_mir_body()); let mut sig = if let Some(sig_args) = sig_args { sig.instantiate(tcx, &sig_args).skip_norm_wip() } else { @@ -830,14 +820,14 @@ fn build_call_shim<'tcx>( DerefSource::MutRef => Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty), DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty), }, - Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {instance:?}"), + Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {shim:?}"), }; sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } // FIXME: Avoid having to adjust the signature both here and in // `fn_sig_for_fn_abi`. - if let ty::InstanceKind::VTableShim(..) = instance { + if let ty::ShimKind::VTableShim(..) = shim { // Modify fn(self, ...) to fn(self: *mut Self, ...) let mut inputs_and_output = sig.inputs_and_output.to_vec(); let self_arg = &mut inputs_and_output[0]; @@ -995,7 +985,7 @@ fn build_call_shim<'tcx>( } let mut body = - new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span); + new_body(MirSource::from_shim(shim), blocks, local_decls, sig.inputs().len(), span); if let ExternAbi::RustCall = sig.abi() { body.spread_arg = Some(Local::new(sig.inputs().len())); @@ -1119,7 +1109,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), false, ); - let source = MirSource::from_instance(ty::InstanceKind::FnPtrAddrShim(def_id, self_ty)); + let source = MirSource::from_shim(ty::ShimKind::FnPtrAddrShim(def_id, self_ty)); new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) } @@ -1218,7 +1208,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( false, ); - let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim { + let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id, receiver_by_ref, }); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index da88247800372..b23ab7842d51f 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -106,7 +106,7 @@ pub(super) fn build_async_drop_shim<'tcx>( ); block(&mut blocks, TerminatorKind::Return); - let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlue(def_id, ty)); + let source = MirSource::from_shim(ty::ShimKind::AsyncDropGlue(def_id, ty)); let mut body = new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); @@ -175,17 +175,17 @@ pub(super) fn build_future_drop_poll_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, ) -> Body<'tcx> { - let instance = ty::InstanceKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); + let shim = ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { - bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", instance); + bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", shim); }; let span = tcx.def_span(def_id); if tcx.is_async_drop_in_place_coroutine(*coroutine_def_id) { - build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, instance) + build_adrop_for_adrop_shim(tcx, proxy_ty, impl_ty, span, shim) } else { - build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, instance) + build_adrop_for_coroutine_shim(tcx, proxy_ty, impl_ty, span, shim) } } @@ -198,16 +198,16 @@ fn build_adrop_for_coroutine_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, span: Span, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, ) -> Body<'tcx> { let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else { - bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance); + bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", shim); }; let source_info = SourceInfo::outermost(span); let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); let mut body: Body<'tcx> = EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip(); - body.source.instance = instance; + body.source.instance = ty::InstanceKind::Shim(shim); body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); @@ -291,7 +291,7 @@ fn build_adrop_for_adrop_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, span: Span, - instance: ty::InstanceKind<'tcx>, + shim: ty::ShimKind<'tcx>, ) -> Body<'tcx> { let source_info = SourceInfo::outermost(span); let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty); @@ -413,7 +413,7 @@ fn build_adrop_for_adrop_shim<'tcx>( false, )); - let source = MirSource::from_instance(instance); + let source = MirSource::from_shim(shim); let mut body = new_body(source, blocks, locals, sig.inputs().len(), span); body.phase = MirPhase::Runtime(RuntimePhase::Initial); return body; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 0421edc543151..7c4fce02ff005 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -226,8 +226,8 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ - self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, - TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, + self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, ShimKind, Ty, TyCtxt, + TypeFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; @@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>( used_items.push(respan( starting_item.span, MonoItem::Fn(Instance { - def: InstanceKind::ThreadLocalShim(def_id), + def: InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)), args: GenericArgs::empty(), }), )); @@ -1013,10 +1013,10 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } - ty::InstanceKind::ThreadLocalShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { bug!("{:?} being reified", instance); } - ty::InstanceKind::DropGlue(_, None) => { + ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { // Don't need to emit noop drop glue if we are calling directly. // // Note that we also optimize away the call to visit_instance_use in vtable construction @@ -1025,18 +1025,18 @@ fn visit_instance_use<'tcx>( output.push(create_fn_mono_item(tcx, instance, source)); } } - ty::InstanceKind::DropGlue(_, Some(_)) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(_, _) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) - | ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::Item(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) => { + ty::InstanceKind::Item(..) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) => { output.push(create_fn_mono_item(tcx, instance, source)); } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index aee7153419883..79b47c8e5944d 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -115,7 +115,7 @@ use rustc_middle::mono::{ MonoItemPartitions, Visibility, }; use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths}; -use rustc_middle::ty::{self, InstanceKind, TyCtxt}; +use rustc_middle::ty::{self, InstanceKind, ShimKind, TyCtxt}; use rustc_middle::util::Providers; use rustc_session::CodegenUnits; use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; @@ -630,20 +630,22 @@ fn characteristic_def_id_of_mono_item<'tcx>( MonoItem::Fn(instance) => { let def_id = match instance.def { ty::InstanceKind::Item(def) => def, - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::Intrinsic(..) - | ty::InstanceKind::DropGlue(..) + ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) => return None, + | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + .. + }) + | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) => return None, }; // If this is a method, we want to put it into the same module as @@ -794,27 +796,27 @@ fn mono_item_visibility<'tcx>( let def_id = match instance.def { InstanceKind::Item(def_id) - | InstanceKind::DropGlue(def_id, Some(_)) - | InstanceKind::FutureDropPollShim(def_id, _, _) - | InstanceKind::AsyncDropGlue(def_id, _) - | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | InstanceKind::Shim(ShimKind::DropGlue(def_id, Some(_))) + | InstanceKind::Shim(ShimKind::FutureDropPollShim(def_id, _, _)) + | InstanceKind::Shim(ShimKind::AsyncDropGlue(def_id, _)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(def_id, _)) => def_id, // We match the visibility of statics here - InstanceKind::ThreadLocalShim(def_id) => { + InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)) => { return static_visibility(tcx, can_be_internalized, def_id); } // These are all compiler glue and such, never exported, always hidden. - InstanceKind::VTableShim(..) - | InstanceKind::ReifyShim(..) - | InstanceKind::FnPtrShim(..) + InstanceKind::Shim(ShimKind::VTableShim(..)) + | InstanceKind::Shim(ShimKind::ReifyShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrShim(..)) | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) - | InstanceKind::ClosureOnceShim { .. } - | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::DropGlue(..) - | InstanceKind::CloneShim(..) - | InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden, + | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::CloneShim(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Visibility::Hidden, }; // Both the `start_fn` lang item and `main` itself should not be exported, @@ -1331,8 +1333,8 @@ pub(crate) fn provide(providers: &mut Providers) { // "Normal" functions size estimate: the number of // statements, plus one for the terminator. InstanceKind::Item(..) - | InstanceKind::DropGlue(..) - | InstanceKind::AsyncDropGlueCtorShim(..) => { + | InstanceKind::Shim(ShimKind::DropGlue(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { let mir = tcx.instance_mir(instance.def); mir.basic_blocks .iter() diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 4218c21f508d3..5807d79c8e03c 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -990,18 +990,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { ty::InstanceKind::Virtual(_def_id, idx) => { crate::mir::mono::InstanceKind::Virtual { idx } } - ty::InstanceKind::VTableShim(..) - | ty::InstanceKind::ReifyShim(..) - | ty::InstanceKind::FnPtrAddrShim(..) - | ty::InstanceKind::ClosureOnceShim { .. } - | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::ThreadLocalShim(..) - | ty::InstanceKind::DropGlue(..) - | ty::InstanceKind::CloneShim(..) - | ty::InstanceKind::FnPtrShim(..) - | ty::InstanceKind::FutureDropPollShim(..) - | ty::InstanceKind::AsyncDropGlue(..) - | ty::InstanceKind::AsyncDropGlueCtorShim(..) => crate::mir::mono::InstanceKind::Shim, + ty::InstanceKind::Shim(..) => crate::mir::mono::InstanceKind::Shim, }; crate::mir::mono::Instance { def, kind } } diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index c309df59e9eca..87a8661edeb65 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -645,7 +645,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { /// Check if this is an empty DropGlue shim. pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool { - matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None))) } /// Convert a non-generic crate item into an instance. diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 0810e327b63e3..6284754016aec 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -310,7 +310,7 @@ pub(crate) fn transform_instance<'tcx>( // FIXME: account for async-drop-glue if (matches!(instance.def, ty::InstanceKind::Virtual(..)) && tcx.is_lang_item(instance.def_id(), LangItem::DropGlue)) - || matches!(instance.def, ty::InstanceKind::DropGlue(..)) + || matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..))) { // Adjust the type ids of DropGlues // @@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>( tcx.types.unit }; instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); - } else if let ty::InstanceKind::VTableShim(def_id) = instance.def + } else if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(def_id)) = instance.def && let Some(trait_id) = tcx.trait_of_assoc(def_id) { // Adjust the type ids of VTableShims to the type id expected in the call sites for the @@ -461,7 +461,8 @@ pub(crate) fn transform_instance<'tcx>( fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { match instance.def { - ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => { + ty::InstanceKind::Item(def_id) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(def_id, _)) => { tcx.opt_associated_item(def_id).map(|item| item.def_id) } _ => None, diff --git a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs index 3243e23fcf981..7df5ec9088a9c 100644 --- a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs +++ b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs @@ -6,7 +6,7 @@ use std::hash::Hasher; -use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, Ty, TyCtxt}; +use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, ShimKind, Ty, TyCtxt}; use rustc_target::callconv::FnAbi; use twox_hash::XxHash64; @@ -46,7 +46,8 @@ pub fn typeid_for_instance<'tcx>( // // This was implemented for KCFI support in #123106 and #123052 (which introduced the // ReifyReason). The tracking issue for KCFI support for Rust is #123479. - if matches!(instance.def, InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr))) { + if matches!(instance.def, InstanceKind::Shim(ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr)))) + { options.insert(TypeIdOptions::USE_CONCRETE_SELF); } // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index c13300a735c3c..d67b603b73a68 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -62,13 +62,13 @@ pub(super) fn mangle<'tcx>( let mut p = LegacySymbolMangler { tcx, path: SymbolPath::new(), keep_within_component: false }; p.print_def_path( def_id, - if let ty::InstanceKind::DropGlue(_, _) - | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) - | ty::InstanceKind::FutureDropPollShim(_, _, _) = instance.def + if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) = instance.def { // Add the name of the dropped type to the symbol name &*instance.args - } else if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + } else if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { let ty::Coroutine(_, cor_args) = ty.kind() else { bug!(); }; @@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>( .unwrap(); match instance.def { - ty::InstanceKind::ThreadLocalShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { p.write_str("{{tls-shim}}").unwrap(); } - ty::InstanceKind::VTableShim(..) => { + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) => { p.write_str("{{vtable-shim}}").unwrap(); } - ty::InstanceKind::ReifyShim(_, reason) => { + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, reason)) => { p.write_str("{{reify-shim").unwrap(); match reason { Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(), @@ -98,14 +98,17 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } => { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref, + .. + }) => { p.write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" }) .unwrap(); } _ => {} } - if let ty::InstanceKind::FutureDropPollShim(..) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) = instance.def { let _ = p.write_str("{{drop-shim}}"); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c6624a7820559..b2f5ea1873807 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -49,25 +49,31 @@ pub(super) fn mangle<'tcx>( // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. let shim_kind = match instance.def { - ty::InstanceKind::ThreadLocalShim(_) => Some("tls"), - ty::InstanceKind::VTableShim(_) => Some("vtable"), - ty::InstanceKind::ReifyShim(_, None) => Some("reify"), - ty::InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"), - ty::InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"), + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_)) => Some("tls"), + ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_)) => Some("vtable"), + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, None)) => Some("reify"), + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr))) => { + Some("reify_fnptr") + } + ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::Vtable))) => { + Some("reify_vtable") + } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: true, .. } => { - Some("by_move") - } - ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { - Some("by_ref") - } - ty::InstanceKind::FutureDropPollShim(_, _, _) => Some("drop"), + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref: true, + .. + }) => Some("by_move"), + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref: false, + .. + }) => Some("by_ref"), + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) => Some("drop"), _ => None, }; - if let ty::InstanceKind::AsyncDropGlue(_, ty) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, ty)) = instance.def { let ty::Coroutine(_, cor_args) = ty.kind() else { bug!(); }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e782557d126bf..d26750f255198 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -10,7 +10,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, }; -use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Unnormalized}; +use rustc_middle::ty::{self, InstanceKind, ShimKind, Ty, TyCtxt, Unnormalized}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_target::callconv::{ @@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>( instance: ty::Instance<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> ty::FnSig<'tcx> { - if let InstanceKind::ThreadLocalShim(..) = instance.def { + if let InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) = instance.def { return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); } @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - if let ty::InstanceKind::VTableShim(..) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) = instance.def { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); @@ -82,22 +82,23 @@ fn fn_sig_for_fn_abi<'tcx>( // a separate def-id for these bodies. let mut coroutine_kind = args.as_coroutine_closure().kind(); - let env_ty = - if let InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } = - instance.def - { - coroutine_kind = ty::ClosureKind::FnOnce; - - // Implementations of `FnMut` and `Fn` for coroutine-closures - // still take their receiver by ref. - if receiver_by_ref { - Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) - } else { - coroutine_ty - } + let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { + receiver_by_ref, + .. + }) = instance.def + { + coroutine_kind = ty::ClosureKind::FnOnce; + + // Implementations of `FnMut` and `Fn` for coroutine-closures + // still take their receiver by ref. + if receiver_by_ref { + Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) } else { - tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) - }; + coroutine_ty + } + } else { + tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased) + }; let sig = tcx.instantiate_bound_regions_with_erased(sig); @@ -264,7 +265,8 @@ impl<'tcx> FnAbiDesc<'tcx> { ) -> Self { let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); - let is_tls_shim_call = matches!(instance.def, ty::InstanceKind::ThreadLocalShim(_)); + let is_tls_shim_call = + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_))); Self { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7386afbe53771..25edafce89f13 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -38,16 +38,16 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_lang_item(def_id, LangItem::DropGlue) { let ty = args.type_at(0); - if ty.needs_drop(tcx, typing_env) { + let shim = if ty.needs_drop(tcx, typing_env) { debug!(" => nontrivial drop glue"); match *ty.kind() { ty::Coroutine(coroutine_def_id, ..) => { // FIXME: sync drop of coroutine with async drop (generate both versions?) // Currently just ignored if tcx.optimized_mir(coroutine_def_id).coroutine_drop_async().is_some() { - ty::InstanceKind::DropGlue(def_id, None) + ty::ShimKind::DropGlue(def_id, None) } else { - ty::InstanceKind::DropGlue(def_id, Some(ty)) + ty::ShimKind::DropGlue(def_id, Some(ty)) } } ty::Closure(..) @@ -57,14 +57,15 @@ fn resolve_instance_raw<'tcx>( | ty::Dynamic(..) | ty::Array(..) | ty::Slice(..) - | ty::UnsafeBinder(..) => ty::InstanceKind::DropGlue(def_id, Some(ty)), + | ty::UnsafeBinder(..) => ty::ShimKind::DropGlue(def_id, Some(ty)), // Drop shims can only be built from ADTs. _ => return Ok(None), } } else { debug!(" => trivial drop glue"); - ty::InstanceKind::DropGlue(def_id, None) - } + ty::ShimKind::DropGlue(def_id, None) + }; + ty::InstanceKind::Shim(shim) } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { let ty = args.type_at(0); @@ -82,14 +83,14 @@ fn resolve_instance_raw<'tcx>( _ => return Ok(None), } debug!(" => nontrivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) } else { debug!(" => trivial async drop glue ctor"); - ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) } } else if tcx.is_async_drop_in_place_coroutine(def_id) { let ty = args.type_at(0); - ty::InstanceKind::AsyncDropGlue(def_id, ty) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(def_id, ty)) } else { debug!(" => free item"); ty::InstanceKind::Item(def_id) @@ -279,7 +280,10 @@ fn resolve_associated_item<'tcx>( }; Some(Instance { - def: ty::InstanceKind::CloneShim(trait_item_id, self_ty), + def: ty::InstanceKind::Shim(ty::ShimKind::CloneShim( + trait_item_id, + self_ty, + )), args: rcvr_args, }) } else { @@ -296,7 +300,10 @@ fn resolve_associated_item<'tcx>( return Ok(None); } Some(Instance { - def: ty::InstanceKind::FnPtrAddrShim(trait_item_id, self_ty), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim( + trait_item_id, + self_ty, + )), args: rcvr_args, }) } else { @@ -326,7 +333,10 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + trait_item_id, + rcvr_args.type_at(0), + )), args: rcvr_args, }), ty::CoroutineClosure(coroutine_closure_def_id, args) => { @@ -339,10 +349,12 @@ fn resolve_associated_item<'tcx>( Some(Instance::new_raw(coroutine_closure_def_id, args)) } else { Some(Instance { - def: ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, - }, + def: ty::InstanceKind::Shim( + ty::ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, + }, + ), args, }) } @@ -362,10 +374,12 @@ fn resolve_associated_item<'tcx>( // If we're computing `AsyncFnOnce` for a by-ref closure then // construct a new body that has the right return types. Some(Instance { - def: ty::InstanceKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref: false, - }, + def: ty::InstanceKind::Shim( + ty::ShimKind::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + receiver_by_ref: false, + }, + ), args, }) } else { @@ -376,7 +390,10 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + trait_item_id, + rcvr_args.type_at(0), + )), args: rcvr_args, }), _ => bug!( From c329a0e6c966eda4b696f104a2a839841af9a5a4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:39:32 +0000 Subject: [PATCH 07/11] Strip vestigial `Shim` suffix from `ShimKind` variants --- .../rustc_codegen_cranelift/src/constant.rs | 2 +- .../src/back/symbol_export.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../rustc_const_eval/src/interpret/call.rs | 22 ++-- .../src/middle/codegen_fn_attrs.rs | 4 +- .../src/middle/exported_symbols.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 +- compiler/rustc_middle/src/mir/visit.rs | 20 +-- compiler/rustc_middle/src/mono.rs | 20 +-- compiler/rustc_middle/src/ty/instance.rs | 116 +++++++++--------- compiler/rustc_middle/src/ty/print/mod.rs | 26 ++-- compiler/rustc_mir_transform/src/inline.rs | 22 ++-- .../rustc_mir_transform/src/inline/cycle.rs | 20 +-- compiler/rustc_mir_transform/src/shim.rs | 39 +++--- .../src/shim/async_destructor_ctor.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 22 ++-- .../rustc_monomorphize/src/partitioning.rs | 44 ++++--- .../cfi/typeid/itanium_cxx_abi/transform.rs | 5 +- .../rustc_sanitizers/src/kcfi/typeid/mod.rs | 3 +- compiler/rustc_symbol_mangling/src/legacy.rs | 14 +-- compiler/rustc_symbol_mangling/src/v0.rs | 16 +-- compiler/rustc_ty_utils/src/abi.rs | 8 +- compiler/rustc_ty_utils/src/instance.rs | 19 ++- 23 files changed, 212 insertions(+), 224 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index a83bfd1cbad42..829e7d0dfb59c 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 40d5c3b07059f..dfc8c8be5c03f 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -361,7 +361,7 @@ fn exported_generic_symbols_provider_local<'tcx>( } } MonoItem::Fn(Instance { - def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)), + def: InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)), args, }) => { // A little sanity-check @@ -586,7 +586,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }, instantiating_crate, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index c1ee7c02e874e..5dc4617717c11 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -665,7 +665,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }; let fn_ptr = bx.get_fn_addr(instance); diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 0236b49e497e4..44420b7148478 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -428,7 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Determine whether this is a non-capturing closure. That's relevant as their first // argument can be skipped (and that's the only kind of argument skipping we allow). let is_non_capturing_closure = - (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. })) + (matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. })) || self.tcx.is_closure_like(def_id)) && { let arg = &callee_fn_abi.args[0]; @@ -652,18 +652,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } } - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) + ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Item(_) => { // We need MIR for this fn. // Note that this can be an intrinsic, if we are executing its fallback body. diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index eefb346d174b4..713c6597c1966 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -33,7 +33,7 @@ impl<'tcx> TyCtxt<'tcx> { // // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, // and therefore can be skipped here. - if let InstanceKind::Shim(ShimKind::ReifyShim(_, _)) = instance_kind + if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { @@ -54,7 +54,7 @@ impl<'tcx> TyCtxt<'tcx> { } // Ensure closure shims have the optimization properties of their closure applied to them. - if let InstanceKind::Shim(ShimKind::ClosureOnceShim { + if let InstanceKind::Shim(ShimKind::ClosureOnce { call_once: _, closure, track_caller: _, diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 5942f9dfa1def..e23ad3c832ef7 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -75,7 +75,7 @@ impl<'tcx> ExportedSymbol<'tcx> { tcx.symbol_name(ty::Instance::resolve_async_drop_in_place_poll(tcx, def_id, ty)) } ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(def_id)), + def: ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(def_id)), args: ty::GenericArgs::empty(), }), ExportedSymbol::NoDefId(symbol_name) => symbol_name, diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 1c7d261dd5978..beab1b1a08e1a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) => { let mut s = ".".to_owned(); s.extend(ty.to_string().chars().filter_map(|c| match c { ' ' => None, @@ -251,7 +251,7 @@ impl<'a, 'tcx> MirDumper<'a, 'tcx> { })); s } - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, proxy_cor, impl_cor)) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, proxy_cor, impl_cor)) => { let mut s = ".".to_owned(); s.extend(proxy_cor.to_string().chars().filter_map(|c| match c { ' ' => None, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 35c47b761c5d4..921c54b2828c2 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -347,27 +347,27 @@ macro_rules! make_mir_visitor { ty::InstanceKind::Item(_def_id) => {} ty::InstanceKind::Intrinsic(_def_id) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_def_id)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_def_id, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(_def_id, _)) | ty::InstanceKind::Virtual(_def_id, _) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_def_id)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { call_once: _def_id, closure: _, track_caller: _ }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_def_id)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { call_once: _def_id, closure: _, track_caller: _ }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id: _def_id, receiver_by_ref: _, }) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, None)) => {} - ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(_def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::FnPtr(_def_id, ty)) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_def_id, Some(ty))) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(_def_id, ty)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(_def_id, ty)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(_def_id, ty)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_def_id, ty)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_def_id, ty)) => { + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_def_id, ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_def_id, proxy_ty, impl_ty)) => { + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_def_id, proxy_ty, impl_ty)) => { self.visit_ty($(& $mutability)? *proxy_ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *impl_ty, TyContext::Location(location)); } diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 054b3e9a49680..6df67257a2ea7 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -525,18 +525,18 @@ impl<'tcx> CodegenUnit<'tcx> { InstanceKind::Item(def) => def.as_local().map(|_| def), InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) - | InstanceKind::Shim(ShimKind::VTableShim(..)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::VTable(..)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::ThreadLocal(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => None, + | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => None, }, MonoItem::Static(def_id) => def_id.as_local().map(|_| def_id), MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.to_def_id()), diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 2fc2a4a23c88c..30c299aa82b1a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -96,7 +96,7 @@ pub enum ShimKind<'tcx> { /// /// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` - /// and dereference the argument to call the original function. - VTableShim(DefId), + VTable(DefId), /// `fn()` pointer where the function itself cannot be turned into a pointer. /// @@ -115,12 +115,12 @@ pub enum ShimKind<'tcx> { /// /// This field will only be populated if we are compiling in a mode that needs these shims /// to be separable, currently only when KCFI is enabled. - ReifyShim(DefId, Option), + Reify(DefId, Option), /// `::call_*` (generated `FnTrait` implementation for `fn()` pointers). /// /// `DefId` is `FnTrait::call_*`. - FnPtrShim(DefId, Ty<'tcx>), + FnPtr(DefId, Ty<'tcx>), /// `<[FnMut/Fn closure] as FnOnce>::call_once`. /// @@ -128,14 +128,14 @@ pub enum ShimKind<'tcx> { /// /// This generates a body that will just borrow the (owned) self type, /// and dispatch to the `FnMut::call_mut` instance for the closure. - ClosureOnceShim { call_once: DefId, closure: DefId, track_caller: bool }, + ClosureOnce { call_once: DefId, closure: DefId, track_caller: bool }, /// `<[FnMut/Fn coroutine-closure] as FnOnce>::call_once` /// /// The body generated here differs significantly from the `ClosureOnceShim`, /// since we need to generate a distinct coroutine type that will move the /// closure's upvars *out* of the closure. - ConstructCoroutineInClosureShim { + ConstructCoroutineInClosure { coroutine_closure_def_id: DefId, // Whether the generated MIR body takes the coroutine by-ref. This is // because the signature of `<{async fn} as FnMut>::call_mut` is: @@ -148,10 +148,10 @@ pub enum ShimKind<'tcx> { /// Compiler-generated accessor for thread locals which returns a reference to the thread local /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking /// native support. - ThreadLocalShim(DefId), + ThreadLocal(DefId), /// Proxy shim for async drop of future (def_id, proxy_cor_ty, impl_cor_ty) - FutureDropPollShim(DefId, Ty<'tcx>, Ty<'tcx>), + FutureDropPoll(DefId, Ty<'tcx>, Ty<'tcx>), /// `core::ptr::drop_glue::`. /// @@ -168,20 +168,20 @@ pub enum ShimKind<'tcx> { /// Additionally, arrays, tuples, and closures get a `Clone` shim even if they aren't `Copy`. /// /// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl. - CloneShim(DefId, Ty<'tcx>), + Clone(DefId, Ty<'tcx>), /// Compiler-generated `::addr` implementation. /// /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types. /// /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`. - FnPtrAddrShim(DefId, Ty<'tcx>), + FnPtrAddr(DefId, Ty<'tcx>), /// `core::future::async_drop::async_drop_in_place::<'_, T>`. /// /// The `DefId` is for `core::future::async_drop::async_drop_in_place`, the `Ty` /// is the type `T`. - AsyncDropGlueCtorShim(DefId, Ty<'tcx>), + AsyncDropGlueCtor(DefId, Ty<'tcx>), /// `core::future::async_drop::async_drop_in_place::<'_, T>::{closure}`. /// @@ -238,8 +238,8 @@ impl<'tcx> Instance<'tcx> { tcx.upstream_drop_glue_for(self.args) } InstanceKind::Shim(ShimKind::AsyncDropGlue(_, _)) => None, - InstanceKind::Shim(ShimKind::FutureDropPollShim(_, _, _)) => None, - InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, _)) => { + InstanceKind::Shim(ShimKind::FutureDropPoll(_, _, _)) => None, + InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, _)) => { tcx.upstream_async_drop_glue_for(self.args) } _ => None, @@ -288,10 +288,10 @@ impl<'tcx> InstanceKind<'tcx> { match *self { InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) - | InstanceKind::Shim(ShimKind::VTableShim(def_id)) => { + | InstanceKind::Shim(ShimKind::VTable(def_id)) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } - InstanceKind::Shim(ShimKind::ClosureOnceShim { + InstanceKind::Shim(ShimKind::ClosureOnce { call_once: _, closure: _, track_caller, @@ -318,21 +318,21 @@ impl<'tcx> ShimKind<'tcx> { #[inline] pub fn def_id(self) -> DefId { match self { - ShimKind::VTableShim(def_id) - | ShimKind::ReifyShim(def_id, _) - | ShimKind::FnPtrShim(def_id, _) - | ShimKind::ThreadLocalShim(def_id) - | ShimKind::ClosureOnceShim { call_once: def_id, closure: _, track_caller: _ } - | ShimKind::ConstructCoroutineInClosureShim { + ShimKind::VTable(def_id) + | ShimKind::Reify(def_id, _) + | ShimKind::FnPtr(def_id, _) + | ShimKind::ThreadLocal(def_id) + | ShimKind::ClosureOnce { call_once: def_id, closure: _, track_caller: _ } + | ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id: def_id, receiver_by_ref: _, } | ShimKind::DropGlue(def_id, _) - | ShimKind::CloneShim(def_id, _) - | ShimKind::FnPtrAddrShim(def_id, _) - | ShimKind::FutureDropPollShim(def_id, _, _) + | ShimKind::Clone(def_id, _) + | ShimKind::FnPtrAddr(def_id, _) + | ShimKind::FutureDropPoll(def_id, _, _) | ShimKind::AsyncDropGlue(def_id, _) - | ShimKind::AsyncDropGlueCtorShim(def_id, _) => def_id, + | ShimKind::AsyncDropGlueCtor(def_id, _) => def_id, } } @@ -340,47 +340,47 @@ impl<'tcx> ShimKind<'tcx> { pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { ShimKind::DropGlue(def_id, Some(_)) - | ShimKind::AsyncDropGlueCtorShim(def_id, _) + | ShimKind::AsyncDropGlueCtor(def_id, _) | ShimKind::AsyncDropGlue(def_id, _) - | ShimKind::FutureDropPollShim(def_id, ..) - | ShimKind::ThreadLocalShim(def_id) => Some(def_id), - ShimKind::VTableShim(..) - | ShimKind::ReifyShim(..) - | ShimKind::FnPtrShim(..) - | ShimKind::ClosureOnceShim { .. } - | ShimKind::ConstructCoroutineInClosureShim { .. } + | ShimKind::FutureDropPoll(def_id, ..) + | ShimKind::ThreadLocal(def_id) => Some(def_id), + ShimKind::VTable(..) + | ShimKind::Reify(..) + | ShimKind::FnPtr(..) + | ShimKind::ClosureOnce { .. } + | ShimKind::ConstructCoroutineInClosure { .. } | ShimKind::DropGlue(..) - | ShimKind::CloneShim(..) - | ShimKind::FnPtrAddrShim(..) => None, + | ShimKind::Clone(..) + | ShimKind::FnPtrAddr(..) => None, } } pub fn requires_inline(&self) -> bool { match self { ShimKind::DropGlue(_, Some(ty)) => ty.is_array(), - ShimKind::AsyncDropGlueCtorShim(_, ty) => ty.is_coroutine(), - ShimKind::FutureDropPollShim(_, _, _) => false, + ShimKind::AsyncDropGlueCtor(_, ty) => ty.is_coroutine(), + ShimKind::FutureDropPoll(_, _, _) => false, ShimKind::AsyncDropGlue(_, _) => false, - ShimKind::ThreadLocalShim(_) => false, + ShimKind::ThreadLocal(_) => false, _ => true, } } pub fn has_polymorphic_mir_body(&self) -> bool { match *self { - ShimKind::CloneShim(..) - | ShimKind::ThreadLocalShim(..) - | ShimKind::FnPtrAddrShim(..) - | ShimKind::FnPtrShim(..) + ShimKind::Clone(..) + | ShimKind::ThreadLocal(..) + | ShimKind::FnPtrAddr(..) + | ShimKind::FnPtr(..) | ShimKind::DropGlue(_, Some(_)) - | ShimKind::FutureDropPollShim(..) + | ShimKind::FutureDropPoll(..) | ShimKind::AsyncDropGlue(_, _) => false, - ShimKind::AsyncDropGlueCtorShim(_, _) => false, - ShimKind::ClosureOnceShim { .. } - | ShimKind::ConstructCoroutineInClosureShim { .. } + ShimKind::AsyncDropGlueCtor(_, _) => false, + ShimKind::ClosureOnce { .. } + | ShimKind::ConstructCoroutineInClosure { .. } | ShimKind::DropGlue(..) - | ShimKind::ReifyShim(..) - | ShimKind::VTableShim(..) => true, + | ShimKind::Reify(..) + | ShimKind::VTable(..) => true, } } } @@ -451,7 +451,7 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { continue; } else { return Instance { - def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( poll_def_id, first_cor, cor_ty, @@ -465,7 +465,7 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { }; if first_cor != cor_ty { return Instance { - def: ty::InstanceKind::Shim(ShimKind::FutureDropPollShim( + def: ty::InstanceKind::Shim(ShimKind::FutureDropPoll( poll_def_id, first_cor, cor_ty, @@ -642,11 +642,11 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); } InstanceKind::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)); } _ if tcx.sess.is_sanitizer_kcfi_enabled() => { // Reify `::call`-like method implementations @@ -655,7 +655,7 @@ impl<'tcx> Instance<'tcx> { // be directly reified because it's closure-like. The reify can handle the // unresolved instance. resolved = Instance { - def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), args, } // Reify `Trait::method` implementations if the trait is dyn-compatible. @@ -667,7 +667,7 @@ impl<'tcx> Instance<'tcx> { // If this function could also go in a vtable, we need to `ReifyShim` it with // KCFI because it can only attach one type per function. resolved.def = - InstanceKind::Shim(ShimKind::ReifyShim(resolved.def_id(), reason)) + InstanceKind::Shim(ShimKind::Reify(resolved.def_id(), reason)) } } _ => {} @@ -692,7 +692,7 @@ impl<'tcx> Instance<'tcx> { if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - return Instance { def: InstanceKind::Shim(ShimKind::VTableShim(def_id)), args }; + return Instance { def: InstanceKind::Shim(ShimKind::VTable(def_id)), args }; } let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); @@ -736,7 +736,7 @@ impl<'tcx> Instance<'tcx> { // - unlike functions, invoking a closure always goes through a // trait. resolved = Instance { - def: InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)), + def: InstanceKind::Shim(ShimKind::Reify(def_id, reason)), args, }; } else { @@ -744,13 +744,13 @@ impl<'tcx> Instance<'tcx> { " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def, reason)); + resolved.def = InstanceKind::Shim(ShimKind::Reify(def, reason)); } } } InstanceKind::Virtual(def_id, _) => { debug!(" => vtable fn pointer created for virtual call"); - resolved.def = InstanceKind::Shim(ShimKind::ReifyShim(def_id, reason)) + resolved.def = InstanceKind::Shim(ShimKind::Reify(def_id, reason)) } _ => {} } @@ -820,7 +820,7 @@ impl<'tcx> Instance<'tcx> { .def_id; let track_caller = tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); - let def = ty::InstanceKind::Shim(ShimKind::ClosureOnceShim { + let def = ty::InstanceKind::Shim(ShimKind::ClosureOnce { call_once, closure: closure_did, track_caller, diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 0552bf1dd1636..bec1ffc642769 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -381,29 +381,27 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::Instance<'tcx> { impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::ShimKind<'tcx> { fn print(&self, cx: &mut P) -> Result<(), PrintError> { match self { - ty::ShimKind::VTableShim(_) => cx.write_str("shim(vtable)"), - ty::ShimKind::ReifyShim(_, None) => cx.write_str("shim(reify)"), - ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::FnPtr)) => { + ty::ShimKind::VTable(_) => cx.write_str("shim(vtable)"), + ty::ShimKind::Reify(_, None) => cx.write_str("shim(reify)"), + ty::ShimKind::Reify(_, Some(ty::ReifyReason::FnPtr)) => { cx.write_str("shim(reify-fnptr)") } - ty::ShimKind::ReifyShim(_, Some(ty::ReifyReason::Vtable)) => { + ty::ShimKind::Reify(_, Some(ty::ReifyReason::Vtable)) => { cx.write_str("shim(reify-vtable)") } - ty::ShimKind::ThreadLocalShim(_) => cx.write_str("shim(tls)"), - ty::ShimKind::FnPtrShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::ClosureOnceShim { .. } => cx.write_str("shim"), - ty::ShimKind::ConstructCoroutineInClosureShim { .. } => cx.write_str("shim"), + ty::ShimKind::ThreadLocal(_) => cx.write_str("shim(tls)"), + ty::ShimKind::FnPtr(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::ClosureOnce { .. } => cx.write_str("shim"), + ty::ShimKind::ConstructCoroutineInClosure { .. } => cx.write_str("shim"), ty::ShimKind::DropGlue(_, None) => cx.write_str("shim(None)"), ty::ShimKind::DropGlue(_, Some(ty)) => cx.write_str(&format!("shim(Some({ty}))")), - ty::ShimKind::CloneShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::FnPtrAddrShim(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::FutureDropPollShim(_, proxy_ty, impl_ty) => { + ty::ShimKind::Clone(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FnPtrAddr(_, ty) => cx.write_str(&format!("shim({ty})")), + ty::ShimKind::FutureDropPoll(_, proxy_ty, impl_ty) => { cx.write_str(&format!("dropshim({proxy_ty}-{impl_ty})")) } ty::ShimKind::AsyncDropGlue(_, ty) => cx.write_str(&format!("shim({ty})")), - ty::ShimKind::AsyncDropGlueCtorShim(_, ty) => { - cx.write_str(&format!("shim(Some({ty}))")) - } + ty::ShimKind::AsyncDropGlueCtor(_, ty) => cx.write_str(&format!("shim(Some({ty}))")), } } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index a1575a21e9073..e4ce2fb1ad3d2 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -746,14 +746,14 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( return Err("implementation limitation -- HACK for dropping polymorphic type"); } InstanceKind::Shim(ShimKind::AsyncDropGlue(_, ty)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(_, ty)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(_, ty)) => { return if ty.still_further_specializable() { Err("still needs substitution") } else { Ok(()) }; } - InstanceKind::Shim(ShimKind::FutureDropPollShim(_, ty, ty2)) => { + InstanceKind::Shim(ShimKind::FutureDropPoll(_, ty, ty2)) => { return if ty.still_further_specializable() || ty2.still_further_specializable() { Err("still needs substitution") } else { @@ -765,15 +765,15 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue // inlining a second time. - InstanceKind::Shim(ShimKind::VTableShim(_)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + InstanceKind::Shim(ShimKind::VTable(_)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Ok(()), + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::ThreadLocal(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Ok(()), } if inliner.tcx().is_constructor(callee_def_id) { @@ -1374,7 +1374,7 @@ fn try_instance_mir<'tcx>( instance: InstanceKind<'tcx>, ) -> Result<&'tcx Body<'tcx>, &'static str> { if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(ty))) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, ty)) = instance + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, ty)) = instance && let ty::Adt(def, args) = ty.kind() { let fields = def.all_fields(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 0fd1a5f240758..ee63dd966baf6 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -26,24 +26,24 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause // a cycle that way - InstanceKind::Shim(ShimKind::VTableShim(_)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) - | InstanceKind::Shim(ShimKind::ThreadLocalShim { .. }) - | InstanceKind::Shim(ShimKind::CloneShim(..)) => {} + InstanceKind::Shim(ShimKind::VTable(_)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) + | InstanceKind::Shim(ShimKind::ThreadLocal { .. }) + | InstanceKind::Shim(ShimKind::Clone(..)) => {} // This shim does not call any other functions, thus there can be no recursion. - InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return false, + InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return false, // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(..)) + | InstanceKind::Shim(ShimKind::FutureDropPoll(..)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { if callee.has_param() { return false; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index d6061edb74ce3..436b99811ae60 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -35,11 +35,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { debug!("make_shim({:?})", shim); let mut result = match shim { - ty::ShimKind::VTableShim(def_id) => { + ty::ShimKind::VTable(def_id) => { let adjustment = Adjustment::Deref { source: DerefSource::MutPtr }; build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id)) } - ty::ShimKind::FnPtrShim(def_id, ty) => { + ty::ShimKind::FnPtr(def_id, ty) => { let trait_ = tcx.parent(def_id); // Supports `Fn` or `async Fn` traits. let adjustment = match tcx @@ -59,10 +59,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { // a virtual call, or a direct call to a function for which // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). - ty::ShimKind::ReifyShim(def_id, _) => { + ty::ShimKind::Reify(def_id, _) => { build_call_shim(tcx, shim, None, CallKind::Direct(def_id)) } - ty::ShimKind::ClosureOnceShim { call_once: _, closure: _, track_caller: _ } => { + ty::ShimKind::ClosureOnce { call_once: _, closure: _, track_caller: _ } => { let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) @@ -74,10 +74,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut)) } - ty::ShimKind::ConstructCoroutineInClosureShim { - coroutine_closure_def_id, - receiver_by_ref, - } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref } => { + build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref) + } ty::ShimKind::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end @@ -128,10 +127,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id)) } - ty::ShimKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, shim), - ty::ShimKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), - ty::ShimKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), - ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty) => { + ty::ShimKind::ThreadLocal(..) => build_thread_local_shim(tcx, shim), + ty::ShimKind::Clone(def_id, ty) => build_clone_shim(tcx, def_id, ty), + ty::ShimKind::FnPtrAddr(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), + ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty) => { let mut body = async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty); @@ -173,7 +172,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> { return body; } - ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty) => { + ty::ShimKind::AsyncDropGlueCtor(def_id, ty) => { let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty); debug!("make_shim({:?}) = {:?}", shim, body); return body; @@ -555,10 +554,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { } fn into_mir(self) -> Body<'tcx> { - let source = MirSource::from_shim(ty::ShimKind::CloneShim( - self.def_id, - self.sig.inputs_and_output[0], - )); + let source = + MirSource::from_shim(ty::ShimKind::Clone(self.def_id, self.sig.inputs_and_output[0])); new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span) } @@ -773,7 +770,7 @@ fn build_call_shim<'tcx>( // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used // to instantiate into the signature of the shim. It is not necessary for users of this // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`). - let (sig_args, untuple_args) = if let ty::ShimKind::FnPtrShim(_, ty) = shim { + let (sig_args, untuple_args) = if let ty::ShimKind::FnPtr(_, ty) = shim { let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); let untuple_args = sig.inputs(); @@ -827,7 +824,7 @@ fn build_call_shim<'tcx>( // FIXME: Avoid having to adjust the signature both here and in // `fn_sig_for_fn_abi`. - if let ty::ShimKind::VTableShim(..) = shim { + if let ty::ShimKind::VTable(..) = shim { // Modify fn(self, ...) to fn(self: *mut Self, ...) let mut inputs_and_output = sig.inputs_and_output.to_vec(); let self_arg = &mut inputs_and_output[0]; @@ -1109,7 +1106,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), false, ); - let source = MirSource::from_shim(ty::ShimKind::FnPtrAddrShim(def_id, self_ty)); + let source = MirSource::from_shim(ty::ShimKind::FnPtrAddr(def_id, self_ty)); new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) } @@ -1208,7 +1205,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( false, ); - let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosureShim { + let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref, }); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index b23ab7842d51f..f6217f1234bfc 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -175,7 +175,7 @@ pub(super) fn build_future_drop_poll_shim<'tcx>( proxy_ty: Ty<'tcx>, impl_ty: Ty<'tcx>, ) -> Body<'tcx> { - let shim = ty::ShimKind::FutureDropPollShim(def_id, proxy_ty, impl_ty); + let shim = ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty); let ty::Coroutine(coroutine_def_id, _) = impl_ty.kind() else { bug!("build_future_drop_poll_shim not for coroutine impl type: ({:?})", shim); }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 7c4fce02ff005..20aaeba4c8c65 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -447,7 +447,7 @@ fn collect_items_rec<'tcx>( used_items.push(respan( starting_item.span, MonoItem::Fn(Instance { - def: InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)), + def: InstanceKind::Shim(ShimKind::ThreadLocal(def_id)), args: GenericArgs::empty(), }), )); @@ -1013,7 +1013,7 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { bug!("{:?} being reified", instance); } ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => { @@ -1027,16 +1027,16 @@ fn visit_instance_use<'tcx>( } ty::InstanceKind::Item(..) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, Some(_))) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) => { + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) => { output.push(create_fn_mono_item(tcx, instance, source)); } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 79b47c8e5944d..bf4a2bdd15107 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -632,20 +632,18 @@ fn characteristic_def_id_of_mono_item<'tcx>( ty::InstanceKind::Item(def) => def, ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::Virtual(..) - | ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnceShim { .. }) - | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { - .. - }) + | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) + | ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { .. }) | ty::InstanceKind::Shim(ty::ShimKind::DropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::CloneShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim(..)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) + | ty::InstanceKind::Shim(ty::ShimKind::Clone(..)) + | ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr(..)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(..)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(..)) => return None, + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(..)) => return None, }; // If this is a method, we want to put it into the same module as @@ -797,26 +795,26 @@ fn mono_item_visibility<'tcx>( let def_id = match instance.def { InstanceKind::Item(def_id) | InstanceKind::Shim(ShimKind::DropGlue(def_id, Some(_))) - | InstanceKind::Shim(ShimKind::FutureDropPollShim(def_id, _, _)) + | InstanceKind::Shim(ShimKind::FutureDropPoll(def_id, _, _)) | InstanceKind::Shim(ShimKind::AsyncDropGlue(def_id, _)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(def_id, _)) => def_id, + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(def_id, _)) => def_id, // We match the visibility of statics here - InstanceKind::Shim(ShimKind::ThreadLocalShim(def_id)) => { + InstanceKind::Shim(ShimKind::ThreadLocal(def_id)) => { return static_visibility(tcx, can_be_internalized, def_id); } // These are all compiler glue and such, never exported, always hidden. - InstanceKind::Shim(ShimKind::VTableShim(..)) - | InstanceKind::Shim(ShimKind::ReifyShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrShim(..)) + InstanceKind::Shim(ShimKind::VTable(..)) + | InstanceKind::Shim(ShimKind::Reify(..)) + | InstanceKind::Shim(ShimKind::FnPtr(..)) | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) - | InstanceKind::Shim(ShimKind::ClosureOnceShim { .. }) - | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { .. }) + | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) + | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::CloneShim(..)) - | InstanceKind::Shim(ShimKind::FnPtrAddrShim(..)) => return Visibility::Hidden, + | InstanceKind::Shim(ShimKind::Clone(..)) + | InstanceKind::Shim(ShimKind::FnPtrAddr(..)) => return Visibility::Hidden, }; // Both the `start_fn` lang item and `main` itself should not be exported, @@ -1334,7 +1332,7 @@ pub(crate) fn provide(providers: &mut Providers) { // statements, plus one for the terminator. InstanceKind::Item(..) | InstanceKind::Shim(ShimKind::DropGlue(..)) - | InstanceKind::Shim(ShimKind::AsyncDropGlueCtorShim(..)) => { + | InstanceKind::Shim(ShimKind::AsyncDropGlueCtor(..)) => { let mir = tcx.instance_mir(instance.def); mir.basic_blocks .iter() diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 6284754016aec..e901e1cf98e7e 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -364,7 +364,7 @@ pub(crate) fn transform_instance<'tcx>( tcx.types.unit }; instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1)); - } else if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(def_id)) = instance.def + } else if let ty::InstanceKind::Shim(ty::ShimKind::VTable(def_id)) = instance.def && let Some(trait_id) = tcx.trait_of_assoc(def_id) { // Adjust the type ids of VTableShims to the type id expected in the call sites for the @@ -461,8 +461,7 @@ pub(crate) fn transform_instance<'tcx>( fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { match instance.def { - ty::InstanceKind::Item(def_id) - | ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim(def_id, _)) => { + ty::InstanceKind::Item(def_id) | ty::InstanceKind::Shim(ty::ShimKind::FnPtr(def_id, _)) => { tcx.opt_associated_item(def_id).map(|item| item.def_id) } _ => None, diff --git a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs index 7df5ec9088a9c..23aa088c68ffa 100644 --- a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs +++ b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs @@ -46,8 +46,7 @@ pub fn typeid_for_instance<'tcx>( // // This was implemented for KCFI support in #123106 and #123052 (which introduced the // ReifyReason). The tracking issue for KCFI support for Rust is #123479. - if matches!(instance.def, InstanceKind::Shim(ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr)))) - { + if matches!(instance.def, InstanceKind::Shim(ShimKind::Reify(_, Some(ReifyReason::FnPtr)))) { options.insert(TypeIdOptions::USE_CONCRETE_SELF); } // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index d67b603b73a68..2513e7f958a21 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -63,8 +63,8 @@ pub(super) fn mangle<'tcx>( p.print_def_path( def_id, if let ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(_, _)) - | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) = instance.def + | ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(_, _)) + | ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) = instance.def { // Add the name of the dropped type to the symbol name &*instance.args @@ -81,13 +81,13 @@ pub(super) fn mangle<'tcx>( .unwrap(); match instance.def { - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(..)) => { p.write_str("{{tls-shim}}").unwrap(); } - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) => { + ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) => { p.write_str("{{vtable-shim}}").unwrap(); } - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, reason)) => { + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, reason)) => { p.write_str("{{reify-shim").unwrap(); match reason { Some(ReifyReason::FnPtr) => p.write_str("-fnptr").unwrap(), @@ -98,7 +98,7 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref, .. }) => { @@ -108,7 +108,7 @@ pub(super) fn mangle<'tcx>( _ => {} } - if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(..)) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(..)) = instance.def { let _ = p.write_str("{{drop-shim}}"); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index b2f5ea1873807..b259774468c91 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -49,27 +49,27 @@ pub(super) fn mangle<'tcx>( // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. let shim_kind = match instance.def { - ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_)) => Some("tls"), - ty::InstanceKind::Shim(ty::ShimKind::VTableShim(_)) => Some("vtable"), - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, None)) => Some("reify"), - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::FnPtr))) => { + ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_)) => Some("tls"), + ty::InstanceKind::Shim(ty::ShimKind::VTable(_)) => Some("vtable"), + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, None)) => Some("reify"), + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::FnPtr))) => { Some("reify_fnptr") } - ty::InstanceKind::Shim(ty::ShimKind::ReifyShim(_, Some(ReifyReason::Vtable))) => { + ty::InstanceKind::Shim(ty::ShimKind::Reify(_, Some(ReifyReason::Vtable))) => { Some("reify_vtable") } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref: true, .. }) => Some("by_move"), - ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Shim(ty::ShimKind::ConstructCoroutineInClosure { receiver_by_ref: false, .. }) => Some("by_ref"), - ty::InstanceKind::Shim(ty::ShimKind::FutureDropPollShim(_, _, _)) => Some("drop"), + ty::InstanceKind::Shim(ty::ShimKind::FutureDropPoll(_, _, _)) => Some("drop"), _ => None, }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d26750f255198..1d24dba913bcb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -38,7 +38,7 @@ fn fn_sig_for_fn_abi<'tcx>( instance: ty::Instance<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> ty::FnSig<'tcx> { - if let InstanceKind::Shim(ShimKind::ThreadLocalShim(..)) = instance.def { + if let InstanceKind::Shim(ShimKind::ThreadLocal(..)) = instance.def { return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); } @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - if let ty::InstanceKind::Shim(ty::ShimKind::VTableShim(..)) = instance.def { + if let ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) = instance.def { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); @@ -82,7 +82,7 @@ fn fn_sig_for_fn_abi<'tcx>( // a separate def-id for these bodies. let mut coroutine_kind = args.as_coroutine_closure().kind(); - let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosureShim { + let env_ty = if let InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { receiver_by_ref, .. }) = instance.def @@ -266,7 +266,7 @@ impl<'tcx> FnAbiDesc<'tcx> { let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..)); let is_tls_shim_call = - matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocalShim(_))); + matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::ThreadLocal(_))); Self { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 25edafce89f13..34a3a96f89c40 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -83,10 +83,10 @@ fn resolve_instance_raw<'tcx>( _ => return Ok(None), } debug!(" => nontrivial async drop glue ctor"); - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) } else { debug!(" => trivial async drop glue ctor"); - ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtorShim(def_id, ty)) + ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlueCtor(def_id, ty)) } } else if tcx.is_async_drop_in_place_coroutine(def_id) { let ty = args.type_at(0); @@ -280,10 +280,7 @@ fn resolve_associated_item<'tcx>( }; Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::CloneShim( - trait_item_id, - self_ty, - )), + def: ty::InstanceKind::Shim(ty::ShimKind::Clone(trait_item_id, self_ty)), args: rcvr_args, }) } else { @@ -300,7 +297,7 @@ fn resolve_associated_item<'tcx>( return Ok(None); } Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrAddr( trait_item_id, self_ty, )), @@ -333,7 +330,7 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( trait_item_id, rcvr_args.type_at(0), )), @@ -350,7 +347,7 @@ fn resolve_associated_item<'tcx>( } else { Some(Instance { def: ty::InstanceKind::Shim( - ty::ShimKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref: target_kind != ty::ClosureKind::FnOnce, }, @@ -375,7 +372,7 @@ fn resolve_associated_item<'tcx>( // construct a new body that has the right return types. Some(Instance { def: ty::InstanceKind::Shim( - ty::ShimKind::ConstructCoroutineInClosureShim { + ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref: false, }, @@ -390,7 +387,7 @@ fn resolve_associated_item<'tcx>( Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind)) } ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { - def: ty::InstanceKind::Shim(ty::ShimKind::FnPtrShim( + def: ty::InstanceKind::Shim(ty::ShimKind::FnPtr( trait_item_id, rcvr_args.type_at(0), )), From d06469a60bcee336a64499d0f799cb8f02903643 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 18 Jun 2026 22:43:45 +0000 Subject: [PATCH 08/11] Remove `MirSource::from_instance` helper that is only used in one place It used to be much more prevalent before I extracted shims as their own enum. --- compiler/rustc_middle/src/mir/mod.rs | 4 ---- compiler/rustc_mir_transform/src/coroutine/by_move_body.rs | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 23e6fc15c2ede..3facba24d3fd7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -127,10 +127,6 @@ impl<'tcx> MirSource<'tcx> { MirSource { instance: InstanceKind::Item(def_id), promoted: None } } - pub fn from_instance(instance: InstanceKind<'tcx>) -> Self { - MirSource { instance, promoted: None } - } - pub fn from_shim(shim: ShimKind<'tcx>) -> Self { MirSource { instance: InstanceKind::Shim(shim), promoted: None } } diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 411f090e34921..5933892ecd886 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -223,8 +223,10 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( None, &mut PerParentDisambiguatorState::new(parent_def_id), ); - by_move_body.source = - mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); + by_move_body.source = mir::MirSource { + instance: InstanceKind::Item(body_def.def_id().to_def_id()), + promoted: None, + }; if let Some(dumper) = MirDumper::new(tcx, "built", &by_move_body) { dumper.set_disambiguator(&"after").dump_mir(&by_move_body); From 7d42183eeb7f5d9b46a7a7caa79f8a8fe8073c07 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 22 Jun 2026 23:58:33 +0300 Subject: [PATCH 09/11] Add support for infers in delegation's generics --- compiler/rustc_ast_lowering/src/delegation.rs | 97 +- .../src/delegation/generics.rs | 498 ++++--- .../rustc_ast_lowering/src/diagnostics.rs | 9 + compiler/rustc_ast_lowering/src/lib.rs | 3 + compiler/rustc_hir/src/hir.rs | 28 +- compiler/rustc_hir_analysis/src/delegation.rs | 240 ++- .../rustc_hir_analysis/src/diagnostics.rs | 8 - .../src/hir_ty_lowering/generics.rs | 44 +- tests/pretty/delegation-self-rename.pp | 13 +- .../generics/free-fn-to-trait-infer.rs | 19 - .../generics/free-fn-to-trait-infer.stderr | 27 - .../generics/free-to-trait-static-reuse.rs | 8 - .../free-to-trait-static-reuse.stderr | 107 +- .../generics/generics-gen-args-errors.rs | 13 +- .../generics/generics-gen-args-errors.stderr | 210 ++- tests/ui/delegation/generics/infers.rs | 356 +++++ tests/ui/delegation/generics/infers.stderr | 1296 +++++++++++++++++ .../generics/trait-impl-wrong-args-count.rs | 5 + .../trait-impl-wrong-args-count.stderr | 122 +- .../unelided-lifetime-in-sig-ice-156848.rs | 6 +- ...unelided-lifetime-in-sig-ice-156848.stderr | 27 - tests/ui/delegation/self-ty-ice-156388.rs | 3 +- tests/ui/delegation/self-ty-ice-156388.stderr | 10 +- tests/ui/delegation/target-expr.rs | 1 - tests/ui/delegation/target-expr.stderr | 21 +- .../ui/delegation/unsupported.current.stderr | 10 +- tests/ui/delegation/unsupported.next.stderr | 10 +- tests/ui/delegation/unsupported.rs | 1 - 28 files changed, 2416 insertions(+), 776 deletions(-) delete mode 100644 tests/ui/delegation/generics/free-fn-to-trait-infer.rs delete mode 100644 tests/ui/delegation/generics/free-fn-to-trait-infer.stderr create mode 100644 tests/ui/delegation/generics/infers.rs create mode 100644 tests/ui/delegation/generics/infers.stderr delete mode 100644 tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 3ead3b86cb591..fc466246bf137 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -194,7 +194,7 @@ impl<'hir> LoweringContext<'_, 'hir> { return self.generate_delegation_error(span, delegation); } - let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); + let mut generics = self.uplift_delegation_generics(delegation, sig_id); let (body_id, call_expr_id, unused_target_expr) = self.lower_delegation_body( delegation, @@ -404,10 +404,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationInfo { call_expr_id, call_path_res: self.get_resolution_id(call_path_node_id), - child_args_segment_id: generics.child.args_segment_id, - parent_args_segment_id: generics.parent.args_segment_id, - self_ty_id: generics.self_ty_id, - propagate_self_ty: generics.propagate_self_ty, + child_seg_id: generics.child.args_segment_id, + child_seg_id_for_sig: generics.child.segment_id_for_sig(), + parent_seg_id_for_sig: generics.parent.segment_id_for_sig(), + self_ty_propagation_kind: generics.self_ty_propagation_kind, group_id: { let id = match source { DelegationSource::Single => None, @@ -625,20 +625,40 @@ impl<'hir> LoweringContext<'_, 'hir> { }), ); - hir::QPath::Resolved(ty, self.arena.alloc(new_path)) - } - hir::QPath::TypeRelative(ty, segment) => { - let segment = self.process_segment(span, segment, &mut generics.child); + // Explicitly create `Self` self-type in case of infers or static + // free-to-trait reuses. + let ty = match generics.self_ty_propagation_kind { + Some(hir::DelegationSelfTyPropagationKind::SelfParam) => { + let self_param = generics.parent.generics.find_self_param(); + let path = self.create_generic_arg_path(self_param); + let kind = hir::TyKind::Path(path); + + let ty = match ty { + Some(ty) => hir::Ty { kind, ..ty.clone() }, + None => hir::Ty { kind, hir_id: self.next_id(), span }, + }; + + Some(&*self.arena.alloc(ty)) + } + _ => ty, + }; - hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) + hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } + hir::QPath::TypeRelative(..) => unreachable!("until inherent methods are supported"), }; - generics.self_ty_id = match new_path { - hir::QPath::Resolved(ty, _) => ty, - hir::QPath::TypeRelative(ty, _) => Some(ty), + if let Some(hir::DelegationSelfTyPropagationKind::SelfTy(id)) = + generics.self_ty_propagation_kind.as_mut() + { + *id = match new_path { + hir::QPath::Resolved(ty, _) => { + ty.expect("must contain self type as `SelfTy` propagation kind is specified") + } + hir::QPath::TypeRelative(ty, _) => ty, + } + .hir_id; } - .map(|ty| ty.hir_id); let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span)); let args = self.arena.alloc_from_iter(args); @@ -662,25 +682,38 @@ impl<'hir> LoweringContext<'_, 'hir> { segment: &hir::PathSegment<'hir>, result: &mut GenericsGenerationResult<'hir>, ) -> hir::PathSegment<'hir> { - let details = result.generics.args_propagation_details(); - - // Always uplift generic params, because if they are not empty then they - // should be generated in delegation. - let generics = result.generics.into_hir_generics(self, span); - let segment = if details.should_propagate { - let args = generics.into_generic_args(self, span); - - // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). - let args = if args.is_empty() { None } else { Some(args) }; - - hir::PathSegment { args, ..segment.clone() } - } else { - segment.clone() - }; + let infer_indices = result.generics.infer_indices(); + result.generics.into_hir_generics(self, span); + + let mut segment = segment.clone(); + let mut args_iter = result.generics.create_args_iterator(); + + let new_args = segment + .args + .filter(|args| !args.is_empty()) + .map(|args| { + self.arena.alloc_from_iter(args.args.iter().enumerate().map(|(idx, arg)| { + if infer_indices.contains(&idx) { + args_iter.next(self, |_| arg.hir_id()).expect("arg must exist for infer") + } else { + *arg + } + })) + }) + .unwrap_or_else(|| self.arena.alloc_from_iter(args_iter.consume_all(self))); + + // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). + segment.args = (!new_args.is_empty()).then(|| { + &*self.arena.alloc(hir::GenericArgs { + args: new_args, + constraints: &[], + parenthesized: hir::GenericArgsParentheses::No, + span_ext: segment.args.map_or(span, |args| args.span_ext), + }) + }); - if details.use_args_in_sig_inheritance { - result.args_segment_id = Some(segment.hir_id); - } + result.args_segment_id = segment.hir_id; + result.use_for_sig_inheritance = !result.generics.is_trait_impl(); segment } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index f8e3528750035..79a3961c22a53 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -1,6 +1,7 @@ use hir::HirId; use hir::def::{DefKind, Res}; use rustc_ast::*; +use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::GenericParamDefKind; @@ -9,21 +10,7 @@ use rustc_span::symbol::kw; use rustc_span::{Ident, Span, sym}; use crate::LoweringContext; - -#[derive(Clone, Copy)] -pub(super) enum DelegationGenericsKind { - /// User-specified args are present: `reuse foo::;`. - UserSpecified, - /// The default case when no user-specified args are present: `reuse Trait::foo;`. - Default, - /// In free-to-trait reuse, when user specified args for trait `reuse Trait::::foo;` - /// in this case we need to both generate `Self` and process user args. - SelfAndUserSpecified, - /// In delegations from trait impl to other entities like free functions or trait functions, - /// we want to generate a function whose generics matches generics of signature function - /// in trait. - TraitImpl(bool /* Has user-specified args */), -} +use crate::diagnostics::DelegationInfersMismatch; #[derive(Debug, Clone, Copy)] pub(super) enum GenericsPosition { @@ -31,30 +18,30 @@ pub(super) enum GenericsPosition { Child, } +#[derive(Debug)] +pub(super) enum GenericArgSlot { + UserSpecified, + Generate(T, Option /* Infer arg index from AST */), +} + pub(super) struct DelegationGenerics { - generics: T, - kind: DelegationGenericsKind, + data: T, pos: GenericsPosition, + trait_impl: bool, } -impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { - fn default(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { - DelegationGenerics { generics, pos, kind: DelegationGenericsKind::Default } - } - - fn user_specified(generics: &'hir [ty::GenericParamDef], pos: GenericsPosition) -> Self { - DelegationGenerics { generics, pos, kind: DelegationGenericsKind::UserSpecified } - } +type TyGenerics<'hir> = Vec>; - fn trait_impl( - generics: &'hir [ty::GenericParamDef], - user_specified: bool, +impl<'hir> DelegationGenerics> { + fn generate_all( + params: &'hir [ty::GenericParamDef], pos: GenericsPosition, + trait_impl: bool, ) -> Self { DelegationGenerics { - generics, + data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(), pos, - kind: DelegationGenericsKind::TraitImpl(user_specified), + trait_impl, } } } @@ -70,103 +57,176 @@ impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { /// (i.e., method call scenarios), in such a case this approach helps /// a lot as if `into_hir_generics` will not be called then uplifting will not happen. pub(super) enum HirOrTyGenerics<'hir> { - Ty(DelegationGenerics<&'hir [ty::GenericParamDef]>), + Ty(DelegationGenerics>), Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), } pub(super) struct GenericsGenerationResult<'hir> { pub(super) generics: HirOrTyGenerics<'hir>, - pub(super) args_segment_id: Option, + pub(super) args_segment_id: HirId, + pub(super) use_for_sig_inheritance: bool, +} + +impl GenericsGenerationResult<'_> { + pub(super) fn segment_id_for_sig(&self) -> Option { + self.use_for_sig_inheritance.then(|| self.args_segment_id) + } } pub(super) struct GenericsGenerationResults<'hir> { pub(super) parent: GenericsGenerationResult<'hir>, pub(super) child: GenericsGenerationResult<'hir>, - pub(super) self_ty_id: Option, - pub(super) propagate_self_ty: bool, + pub(super) self_ty_propagation_kind: Option, } -pub(super) struct GenericArgsPropagationDetails { - pub(super) should_propagate: bool, - pub(super) use_args_in_sig_inheritance: bool, +pub(super) struct DelegationGenericArgsIterator<'hir> { + index: usize = Default::default(), + params: &'hir [hir::GenericParam<'hir>], } -impl DelegationGenericsKind { - fn args_propagation_details(self) -> GenericArgsPropagationDetails { - match self { - DelegationGenericsKind::UserSpecified - | DelegationGenericsKind::SelfAndUserSpecified => GenericArgsPropagationDetails { - should_propagate: false, - use_args_in_sig_inheritance: true, - }, - DelegationGenericsKind::TraitImpl(user_specified) => GenericArgsPropagationDetails { - should_propagate: !user_specified, - use_args_in_sig_inheritance: false, - }, - DelegationGenericsKind::Default => GenericArgsPropagationDetails { - should_propagate: true, - use_args_in_sig_inheritance: false, - }, +/// During generic args propagation we need to create generic args +/// (and their `HirId`s) on demand, as some of generic args can not be used +/// and in this case an assert of an unseen `HirId` will be triggered. Moreover, +/// when replacing infers with generated generic params we should reuse existing +/// `HirId` of replaced infer, thus this iterator abstracts the way `HirId`s are +/// created for new generic args. +impl<'hir> DelegationGenericArgsIterator<'hir> { + pub(super) fn next( + &mut self, + ctx: &mut LoweringContext<'_, 'hir>, + hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId, + ) -> Option> { + let p = loop { + if self.index >= self.params.len() { + return None; + } + + let p = self.params[self.index]; + self.index += 1; + + // Skip self generic arg, we do not need to propagate it. + if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { + continue; + } + + break p; + }; + + let hir_id = hir_id_factory(ctx); + + Some(match p.kind { + hir::GenericParamKind::Lifetime { .. } => { + hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime { + hir_id, + ident: p.name.ident(), + kind: hir::LifetimeKind::Param(p.def_id), + source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full }, + syntax: hir::LifetimeSyntax::ExplicitBound, + })) + } + hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty { + hir_id, + span: p.span, + kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)), + })), + hir::GenericParamKind::Const { .. } => { + hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg { + hir_id, + kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)), + span: p.span, + })) + } + }) + } + + pub(super) fn consume_all( + mut self, + ctx: &mut LoweringContext<'_, 'hir>, + ) -> Vec> { + let mut args = vec![]; + while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) { + args.push(arg); } + + args } } impl<'hir> HirOrTyGenerics<'hir> { - pub(super) fn into_hir_generics( - &mut self, - ctx: &mut LoweringContext<'_, 'hir>, - span: Span, - ) -> &mut HirOrTyGenerics<'hir> { + pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) { if let HirOrTyGenerics::Ty(ty) = self { let rename_self = matches!(ty.pos, GenericsPosition::Child); - let params = ctx.uplift_delegation_generic_params(span, ty.generics, rename_self); + let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self); *self = HirOrTyGenerics::Hir(DelegationGenerics { - generics: params, - kind: ty.kind, + data: params, pos: ty.pos, + trait_impl: ty.trait_impl, }); } - - self } fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { match self { HirOrTyGenerics::Ty(_) => hir::Generics::empty(), - HirOrTyGenerics::Hir(hir) => hir.generics, + HirOrTyGenerics::Hir(hir) => hir.data, } } - pub(super) fn into_generic_args( - &self, - ctx: &mut LoweringContext<'_, 'hir>, - span: Span, - ) -> &'hir hir::GenericArgs<'hir> { + pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> { match self { HirOrTyGenerics::Ty(_) => { - bug!("Attempting to get generic args before uplifting to HIR") + bug!("attempting to get generic args before uplifting to HIR") } HirOrTyGenerics::Hir(hir) => { - let add_lifetimes = matches!(hir.pos, GenericsPosition::Parent); - ctx.create_generics_args_from_params(hir.generics.params, add_lifetimes, span) + DelegationGenericArgsIterator { params: hir.data.params, .. } } } } - pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { + pub(super) fn infer_indices(&self) -> FxHashSet { match self { - HirOrTyGenerics::Ty(ty) => ty.kind.args_propagation_details(), - HirOrTyGenerics::Hir(hir) => hir.kind.args_propagation_details(), + HirOrTyGenerics::Ty(ty) => ty + .data + .iter() + .flat_map(|slot| match slot { + GenericArgSlot::Generate(_, Some(idx)) => Some(*idx), + _ => None, + }) + .collect(), + HirOrTyGenerics::Hir(_) => bug!("accessed infer indices on uplifted generics"), + } + } + + pub(super) fn is_trait_impl(&self) -> bool { + match self { + HirOrTyGenerics::Ty(ty) => ty.trait_impl, + HirOrTyGenerics::Hir(hir) => hir.trait_impl, + } + } + + pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> { + match self { + HirOrTyGenerics::Ty(_) => { + bug!("accessed ty-level generics while searching for uplifted `Self` param") + } + HirOrTyGenerics::Hir(hir) => hir + .data + .params + .iter() + .find(|p| p.name.ident().name == kw::SelfUpper) + .expect("`Self` generic param is not found while expected"), } } } impl<'hir> GenericsGenerationResult<'hir> { - fn new( - generics: DelegationGenerics<&'hir [ty::GenericParamDef]>, - ) -> GenericsGenerationResult<'hir> { - GenericsGenerationResult { generics: HirOrTyGenerics::Ty(generics), args_segment_id: None } + fn new(generics: DelegationGenerics>) -> GenericsGenerationResult<'hir> { + GenericsGenerationResult { + generics: HirOrTyGenerics::Ty(generics), + args_segment_id: HirId::INVALID, + use_for_sig_inheritance: false, + } } } @@ -208,13 +268,30 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, delegation: &Delegation, sig_id: DefId, - is_method: bool, ) -> GenericsGenerationResults<'hir> { let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id)); let segments = &delegation.path.segments; let len = segments.len(); - let child_user_specified = segments[len - 1].args.is_some(); + + let get_user_args = |idx: usize| -> Option<&AngleBracketedArgs> { + let segment = &segments[idx]; + + let Some(args) = segment.args.as_ref() else { return None }; + let GenericArgs::AngleBracketed(args) = args else { + self.tcx.dcx().span_delayed_bug( + segment.span(), + "expected angle-bracketed generic args in delegation segment", + ); + + return None; + }; + + // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`, + // the same logic applied when we call function `fn f(t: T)` + // like that `f::<>(())`, in HIR no `<>` will be generated. + (!args.args.is_empty()).then(|| args) + }; let sig_params = &self.tcx.generics_of(sig_id).own_params[..]; @@ -223,23 +300,15 @@ impl<'hir> LoweringContext<'_, 'hir> { if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) { // Considering parent generics, during signature inheritance // we will take those args that are in trait impl header trait ref. - let parent = DelegationGenerics::trait_impl(&[], true, GenericsPosition::Parent); - let parent = GenericsGenerationResult::new(parent); + let parent = + DelegationGenerics { data: vec![], pos: GenericsPosition::Child, trait_impl: true }; - let child = DelegationGenerics::trait_impl( - sig_params, - child_user_specified, - GenericsPosition::Child, - ); + let parent = GenericsGenerationResult::new(parent); + let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true); let child = GenericsGenerationResult::new(child); - return GenericsGenerationResults { - parent, - child, - self_ty_id: None, - propagate_self_ty: false, - }; + return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }; } let delegation_in_free_ctx = @@ -248,7 +317,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let sig_parent = self.tcx.parent(sig_id); let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait); let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait; - let generate_self = free_to_trait_delegation && is_method && delegation.qself.is_none(); + + let qself_is_infer = + delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer()); + + let qself_is_none = delegation.qself.is_none(); + + let generate_self = free_to_trait_delegation && (qself_is_none || qself_is_infer); let can_add_generics_to_parent = len >= 2 && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| { @@ -256,57 +331,137 @@ impl<'hir> LoweringContext<'_, 'hir> { }); let parent_generics = if can_add_generics_to_parent { - let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params[..]; - - if segments[len - 2].args.is_some() { - if generate_self { - // Take only first Self parameter, it is trait so Self must be present. - DelegationGenerics { - kind: DelegationGenericsKind::SelfAndUserSpecified, - generics: &sig_parent_params[..1], - pos: GenericsPosition::Parent, - } - } else { - DelegationGenerics::user_specified(&[], GenericsPosition::Parent) + let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params; + + if let Some(args) = get_user_args(len - 2) { + DelegationGenerics { + data: self.create_slots_from_args( + args, + &sig_parent_params[usize::from(!generate_self)..], + generate_self, + ), + pos: GenericsPosition::Parent, + trait_impl: false, } } else { - let skip_self = usize::from(!generate_self); - DelegationGenerics::default( - &sig_parent_params[skip_self..], + DelegationGenerics::generate_all( + &sig_parent_params[usize::from(!generate_self)..], GenericsPosition::Parent, + false, ) } } else { - DelegationGenerics::default(&[], GenericsPosition::Parent) + DelegationGenerics { data: vec![], pos: GenericsPosition::Parent, trait_impl: false } }; - let child_generics = if child_user_specified { + let child_generics = if let Some(args) = get_user_args(len - 1) { let synth_params_index = sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len()); - DelegationGenerics::user_specified( - &sig_params[synth_params_index..], - GenericsPosition::Child, - ) + let mut slots = + self.create_slots_from_args(args, &sig_params[..synth_params_index], false); + + for synth_param in &sig_params[synth_params_index..] { + slots.push(GenericArgSlot::Generate(synth_param, None)); + } + + DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl: false } } else { - DelegationGenerics::default(sig_params, GenericsPosition::Child) + DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false) }; GenericsGenerationResults { parent: GenericsGenerationResult::new(parent_generics), child: GenericsGenerationResult::new(child_generics), - self_ty_id: None, - propagate_self_ty: free_to_trait_delegation && !generate_self, + self_ty_propagation_kind: match free_to_trait_delegation { + true => Some(match qself_is_none { + true => hir::DelegationSelfTyPropagationKind::SelfParam, + false => match qself_is_infer { + true => hir::DelegationSelfTyPropagationKind::SelfParam, + // HirId is filled during generic args propagation. + false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID), + }, + }), + false => None, + }, + } + } + + /// Generates generic argument slots for user-specified `args` and + /// generic `params` of the signature function. This function checks whether + /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in + /// user-specified args, and if so we add `Generate` slot meaning we have to + /// generate generic param for delegation and propagate it instead of this infer. + /// We zip over user-specified args and signature generic params, so if there are more + /// infers than generic params then we will not process all infers thus not generating + /// more generic params then needed (anyway it is an error). + fn create_slots_from_args( + &self, + args: &AngleBracketedArgs, + params: &'hir [ty::GenericParamDef], + add_first_self: bool, + ) -> TyGenerics<'hir> { + let mut slots = vec![]; + if add_first_self { + slots.push(GenericArgSlot::Generate(¶ms[0], None)); + } + + let params = ¶ms[usize::from(add_first_self)..]; + for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() { + let AngleBracketedArg::Arg(arg) = arg else { continue }; + + let is_infer = match arg { + GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime, + GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(), + GenericArg::Const(_) => false, + }; + + // If `'_` is used instead of `_` (or vice versa) we emit a meaningful + // error instead of processing this infer or leaving it as is for signature + // inheritance. + if is_infer + && matches!( + (arg, ¶m.kind), + ( + GenericArg::Lifetime(_), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } + ) | ( + GenericArg::Type(_) | GenericArg::Const(_), + GenericParamDefKind::Lifetime { .. } + ) + ) + { + let (actual, expected) = if matches!(arg, GenericArg::Lifetime(..)) { + (kw::UnderscoreLifetime, kw::Underscore) + } else { + (kw::Underscore, kw::UnderscoreLifetime) + }; + + self.tcx.dcx().emit_err(DelegationInfersMismatch { + span: arg.span(), + actual, + expected, + }); + } + + slots.push(match is_infer { + true => GenericArgSlot::Generate(param, Some(idx)), + false => GenericArgSlot::UserSpecified, + }); } + + slots } fn uplift_delegation_generic_params( &mut self, span: Span, - params: &'hir [ty::GenericParamDef], + params: &[GenericArgSlot<&ty::GenericParamDef>], rename_self: bool, ) -> &'hir hir::Generics<'hir> { - let params = self.arena.alloc_from_iter(params.iter().map(|p| { + let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| { + let GenericArgSlot::Generate(p, _) = p else { return None }; + let def_kind = match p.kind { GenericParamDefKind::Lifetime => DefKind::LifetimeParam, GenericParamDefKind::Type { .. } => DefKind::TyParam, @@ -354,7 +509,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `lower_node_id` routine so param's id is added to `self.children`. let hir_id = self.lower_node_id(node_id); - hir::GenericParam { + Some(hir::GenericParam { hir_id, colon_span: Some(span), def_id, @@ -363,7 +518,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pure_wrt_drop: p.pure_wrt_drop, source: hir::GenericParamSource::Generics, span, - } + }) })); // HACK: for now we generate predicates such that all lifetimes are early bound, @@ -413,77 +568,32 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn create_generics_args_from_params( + pub(super) fn create_generic_arg_path( &mut self, - params: &[hir::GenericParam<'hir>], - add_lifetimes: bool, - span: Span, - ) -> &'hir hir::GenericArgs<'hir> { - self.arena.alloc(hir::GenericArgs { - args: self.arena.alloc_from_iter(params.iter().filter_map(|p| { - // Skip self generic arg, we do not need to propagate it. - if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() { - return None; - } - - let create_path = |this: &mut Self| { - let res = Res::Def( - match p.kind { - hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, - hir::GenericParamKind::Type { .. } => DefKind::TyParam, - hir::GenericParamKind::Const { .. } => DefKind::ConstParam, - }, - p.def_id.to_def_id(), - ); - - hir::QPath::Resolved( - None, - self.arena.alloc(hir::Path { - segments: this.arena.alloc_slice(&[hir::PathSegment { - args: None, - hir_id: this.next_id(), - ident: p.name.ident(), - infer_args: false, - res, - }]), - res, - span: p.span, - }), - ) - }; - - match p.kind { - hir::GenericParamKind::Lifetime { .. } => match add_lifetimes { - true => Some(hir::GenericArg::Lifetime(self.arena.alloc(hir::Lifetime { - hir_id: self.next_id(), - ident: p.name.ident(), - kind: hir::LifetimeKind::Param(p.def_id), - source: hir::LifetimeSource::Path { - angle_brackets: hir::AngleBrackets::Full, - }, - syntax: hir::LifetimeSyntax::ExplicitBound, - }))), - false => None, - }, - hir::GenericParamKind::Type { .. } => { - Some(hir::GenericArg::Type(self.arena.alloc(hir::Ty { - hir_id: self.next_id(), - span: p.span, - kind: hir::TyKind::Path(create_path(self)), - }))) - } - hir::GenericParamKind::Const { .. } => { - Some(hir::GenericArg::Const(self.arena.alloc(hir::ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Path(create_path(self)), - span: p.span, - }))) - } - } - })), - constraints: &[], - parenthesized: hir::GenericArgsParentheses::No, - span_ext: span, - }) + p: &hir::GenericParam<'hir>, + ) -> hir::QPath<'hir> { + let res = Res::Def( + match p.kind { + hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam, + hir::GenericParamKind::Type { .. } => DefKind::TyParam, + hir::GenericParamKind::Const { .. } => DefKind::ConstParam, + }, + p.def_id.to_def_id(), + ); + + hir::QPath::Resolved( + None, + self.arena.alloc(hir::Path { + segments: self.arena.alloc_slice(&[hir::PathSegment { + args: None, + hir_id: self.next_id(), + ident: p.name.ident(), + infer_args: false, + res, + }]), + res, + span: p.span, + }), + ) } } diff --git a/compiler/rustc_ast_lowering/src/diagnostics.rs b/compiler/rustc_ast_lowering/src/diagnostics.rs index 31f094209a946..238a16d9b859d 100644 --- a/compiler/rustc_ast_lowering/src/diagnostics.rs +++ b/compiler/rustc_ast_lowering/src/diagnostics.rs @@ -560,3 +560,12 @@ pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("wrong infer used: expected {$expected}, found: {$actual}")] +pub(crate) struct DelegationInfersMismatch { + #[primary_span] + pub span: Span, + pub expected: Symbol, + pub actual: Symbol, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b8d708d42ff10..06e83a7486100 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,6 +31,9 @@ //! in the HIR, especially for multiple identifiers. // tidy-alphabetical-start +#![feature(const_default)] +#![feature(const_trait_impl)] +#![feature(default_field_values)] #![feature(deref_patterns)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8d886e7ac6fbf..cd7a9a6cd721c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3854,14 +3854,34 @@ pub enum OpaqueTyOrigin { }, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] +pub enum DelegationSelfTyPropagationKind { + /// Used when self type is explicitly specified in free-to-trait reuse + /// `reuse <() as Trait>::foo;`. + SelfTy(HirId /* Self ty id */), + /// Used when infer instead of a self type is specified or self type + /// is not specified at all: `reuse Trait::foo; reuse <_ as Trait>::foo;`. + SelfParam, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] pub struct DelegationInfo { pub call_expr_id: HirId, pub call_path_res: Option, - pub parent_args_segment_id: Option, - pub child_args_segment_id: Option, - pub self_ty_id: Option, - pub propagate_self_ty: bool, + + /// Id of the child segment in delegation: `reuse Trait::foo`, + /// `child_seg_id` points to `foo`. + pub child_seg_id: HirId, + + /// Ids of parent and child segments, `Some` when we need to take + /// generic args of those segments for signature/predicates inheritance. + /// `None` in trait impl case or when error delegation is generated, meaning + /// we should not access those segments for generic args lowering. + /// When `child_seg_id_for_sig` is Some it always equals `child_seg_id`. + pub parent_seg_id_for_sig: Option, + pub child_seg_id_for_sig: Option, + + pub self_ty_propagation_kind: Option, pub group_id: Option<(LocalExpnId, bool /* unused_target_expr */)>, } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 7f3edd7f09231..de2315edb7e8f 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -5,16 +5,15 @@ use std::debug_assert_matches; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::PathSegment; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; use rustc_middle::ty::{ self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::{ErrorGuaranteed, Span, kw}; use crate::collect::ItemCtxt; -use crate::diagnostics::DelegationSelfTypeNotSpecified; use crate::hir_ty_lowering::HirTyLowerer; type RemapTable = FxHashMap; @@ -65,8 +64,9 @@ impl<'tcx> TypeFolder> for ParamIndexRemapper<'tcx> { } } +#[derive(Debug)] enum SelfPositionKind { - AfterLifetimes(bool /* Should propagate self ty */), + AfterLifetimes(Option), Zero, None, } @@ -83,8 +83,8 @@ fn create_self_position_kind( | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero, (FnKind::Free, FnKind::AssocTrait) => { - let propagate_self_ty = tcx.hir_delegation_info(delegation_id).propagate_self_ty; - SelfPositionKind::AfterLifetimes(propagate_self_ty) + let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind; + SelfPositionKind::AfterLifetimes(kind) } _ => SelfPositionKind::None, @@ -268,28 +268,6 @@ fn get_parent_and_inheritance_kind<'tcx>( } } -fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> Ty<'_> { - tcx.hir_delegation_info(delegation_id) - .self_ty_id - .map(|id| { - let ctx = ItemCtxt::new(tcx, delegation_id); - ctx.lower_ty(tcx.hir_node(id).expect_ty()) - }) - .unwrap_or_else(|| { - // It is possible to attempt to get self type when it is used in signature - // (i.e., `fn default() -> Self`), so emit error here in addition to possible - // `mismatched types` error (see #156388). - let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) }; - tcx.dcx().emit_err(err); - - Ty::new_error_with_message( - tcx, - tcx.def_span(delegation_id), - "the self type must be specified", - ) - }) -} - fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option> { let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id"); let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); @@ -302,14 +280,24 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> | (FnKind::AssocTrait, FnKind::AssocTrait) => { match create_self_position_kind(tcx, delegation_id, sig_id) { SelfPositionKind::None => None, - SelfPositionKind::AfterLifetimes(propagate_self_ty) => { - if propagate_self_ty { - Some(get_delegation_self_ty_or_err(tcx, delegation_id)) - } else { - // Both sig parent and child lifetimes are in included in this count. - let index = tcx.generics_of(delegation_id).own_counts().lifetimes; - Some(Ty::new_param(tcx, index as u32, kw::SelfUpper)) - } + SelfPositionKind::AfterLifetimes(propagation_kind) => { + Some(match propagation_kind { + Some(kind) => match kind { + DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { + let ctx = ItemCtxt::new(tcx, delegation_id); + ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) + } + DelegationSelfTyPropagationKind::SelfParam => { + let index = tcx.generics_of(delegation_id).own_counts().lifetimes; + Ty::new_param(tcx, index as u32, kw::SelfUpper) + } + }, + None => Ty::new_error_with_message( + tcx, + tcx.def_span(delegation_id), + "self propagation kind must be specified for `AfterLifetimes` variant", + ), + }) } SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), } @@ -348,137 +336,69 @@ fn create_generic_args<'tcx>( sig_id: DefId, delegation_id: LocalDefId, mut parent_args: &[ty::GenericArg<'tcx>], - child_args: &[ty::GenericArg<'tcx>], + mut child_args: &[ty::GenericArg<'tcx>], ) -> Vec> { - let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); - + let delegation_generics = tcx.generics_of(delegation_id); let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id); - let deleg_parent_args_without_self_count = - get_delegation_parent_args_count_without_self(tcx, delegation_id, sig_id); - - let delegation_generics = tcx.generics_of(delegation_id); let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count(); let synth_args = &delegation_args[real_args_count..]; - let delegation_args = &delegation_args[..real_args_count]; - - let args = match (caller_kind, callee_kind) { - (FnKind::Free, FnKind::Free) - | (FnKind::Free, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) - | (FnKind::AssocTrait, FnKind::AssocTrait) => delegation_args, - (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { - // Special case, as user specifies Trait args in trait impl header, we want to treat - // them as parent args. We always generate a function whose generics match - // child generics in trait. - let parent = tcx.local_parent(delegation_id); - parent_args = - tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; - - assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); - - tcx.mk_args(&delegation_args[delegation_generics.parent_count..]) - } - - (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { - let self_ty = - tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(); + let mut delegation_parent_args = + &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count]; - tcx.mk_args_from_iter( - std::iter::once(ty::GenericArg::from(self_ty)) - .chain(delegation_args.iter().copied()), - ) - } + let delegation_args = &delegation_args[delegation_generics.parent_count..]; - // For trait impl's `sig_id` is always equal to the corresponding trait method. - // For inherent methods delegation is not yet supported. - (FnKind::AssocTraitImpl, _) - | (_, FnKind::AssocTraitImpl) - | (_, FnKind::AssocInherentImpl) => unreachable!(), - }; + let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); + if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { + // Special case, as user specifies Trait args in trait impl header, we want to treat + // them as parent args. We always generate a function whose generics match + // child generics in trait. + let parent = tcx.local_parent(delegation_id); - let mut new_args = vec![]; + parent_args = + tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; - let self_pos_kind = create_self_position_kind(tcx, delegation_id, sig_id); - let mut lifetimes_end_pos; + child_args = + &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..]; - if !parent_args.is_empty() { - let parent_args_lifetimes_count = - parent_args.iter().filter(|a| a.as_region().is_some()).count(); - - match self_pos_kind { - SelfPositionKind::AfterLifetimes { .. } => { - new_args.extend(&parent_args[1..1 + parent_args_lifetimes_count]); + delegation_parent_args = &[]; + } - lifetimes_end_pos = parent_args_lifetimes_count; + let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into()); - new_args.push(parent_args[0]); + // Remove `Self` from parent args (it is always at the `0th` index) as it is + // added manually. + if self_type.is_some() && !parent_args.is_empty() { + parent_args = &parent_args[1..]; + } - new_args.extend(&parent_args[1 + parent_args_lifetimes_count..]); + let (zero_self, after_lifetimes_self) = + match create_self_position_kind(tcx, delegation_id, sig_id) { + SelfPositionKind::AfterLifetimes(_) => { + assert!(self_type.is_some()); + (None, self_type) } SelfPositionKind::Zero => { - lifetimes_end_pos = 1 /* Self */ + parent_args_lifetimes_count; - new_args.extend_from_slice(parent_args); - - for i in 0..deleg_parent_args_without_self_count { - new_args.insert(1 + i, args[1 + i]); - } - - lifetimes_end_pos += deleg_parent_args_without_self_count; + assert!(self_type.is_some()); + (self_type, None) } - // If we have parent args then we obtained them from trait, then self must be somewhere - SelfPositionKind::None => unreachable!(), + SelfPositionKind::None => (None, None), }; - } else { - let self_impact = matches!(self_pos_kind, SelfPositionKind::Zero) as usize; - - lifetimes_end_pos = self_impact - + deleg_parent_args_without_self_count - + &args[self_impact + deleg_parent_args_without_self_count..] - .iter() - .filter(|a| a.as_region().is_some()) - .count(); - - new_args.extend_from_slice(args); - - // Parent args are empty, then if we should propagate self ty (meaning Self generic - // param was not generated) then we should insert it, as it won't be in `args`. - if matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)) { - new_args.insert( - lifetimes_end_pos, - ty::GenericArg::from(get_delegation_self_ty_or_err(tcx, delegation_id)), - ); - } - } - - if !child_args.is_empty() { - let child_lifetimes_count = child_args.iter().filter(|a| a.as_region().is_some()).count(); - - for i in 0..child_lifetimes_count { - new_args.insert(lifetimes_end_pos + i, child_args[i]); - } - new_args.extend_from_slice(&child_args[child_lifetimes_count..]); - } else if !parent_args.is_empty() { - let child_args = &delegation_args[delegation_generics.parent_count..]; - - let child_lifetimes_count = - child_args.iter().take_while(|a| a.as_region().is_some()).count(); - - for i in 0..child_lifetimes_count { - new_args.insert(lifetimes_end_pos + i, child_args[i]); - } - - // If self_ty is propagated it means that Self generic param was not generated. - let skip_self = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(false)); - new_args.extend(&child_args[child_lifetimes_count + skip_self as usize..]); - } - - new_args.extend(synth_args); - - new_args + let zero_self = zero_self.as_ref().into_iter(); + let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter(); + + zero_self + .chain(delegation_parent_args) + .chain(parent_args.iter().filter(|a| a.as_region().is_some())) + .chain(child_args.iter().filter(|a| a.as_region().is_some())) + .chain(after_lifetimes_self) + .chain(parent_args.iter().filter(|a| a.as_region().is_none())) + .chain(child_args.iter().filter(|a| a.as_region().is_none())) + .chain(synth_args) + .copied() + .collect::>() } pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( @@ -541,7 +461,10 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id); let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id); - let filter_self_preds = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true)); + let filter_self_preds = matches!( + self_pos_kind, + SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..))) + ); let collector = PredicatesCollector { tcx, preds: vec![], args, folder, filter_self_preds }; let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id); @@ -640,18 +563,21 @@ pub(crate) fn delegation_user_specified_args<'tcx>( let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id); let lowerer = ctx.lowerer(); + let parent_args = info + .parent_seg_id_for_sig + .and_then(get_segment) + .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait)) + .map(|(segment, def_id)| { + let self_ty = get_delegation_self_ty(tcx, delegation_id); - let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { - let self_ty = get_delegation_self_ty(tcx, delegation_id); - - lowerer - .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) - .0 - .as_slice() - }); + lowerer + .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) + .0 + .as_slice() + }); let child_args = info - .child_args_segment_id + .child_seg_id_for_sig .and_then(get_segment) .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn)) .map(|(segment, def_id)| { diff --git a/compiler/rustc_hir_analysis/src/diagnostics.rs b/compiler/rustc_hir_analysis/src/diagnostics.rs index 5997f16b42917..1bfc495071284 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics.rs @@ -1582,14 +1582,6 @@ pub(crate) struct UnsupportedDelegation<'a> { pub callee_span: Span, } -#[derive(Diagnostic)] -#[diag("delegation self type is not specified")] -#[help("consider explicitly specifying self type: `reuse ::function`")] -pub(crate) struct DelegationSelfTypeNotSpecified { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("inferred lifetimes are not allowed in delegations as we need to inherit signature")] pub(crate) struct ElidedLifetimesAreNotAllowedInDelegations { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index a26d84291e42d..0187a22d564cb 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -6,7 +6,7 @@ use rustc_errors::{ }; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, GenericArg}; +use rustc_hir::{self as hir, DelegationInfo, GenericArg}; use rustc_middle::ty::{ self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, }; @@ -430,8 +430,17 @@ pub(crate) fn check_generic_arg_count( prohibit_assoc_item_constraint(cx, c, None); } - let explicit_late_bound = - prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos); + let tcx = cx.tcx(); + let parent_def = tcx.hir_get_parent_item(seg.hir_id).def_id; + + // Suppress this warning for delegations as it is compiler generated and lifetimes are + // propagated while late-bound lifetimes may be present. + let explicit_late_bound = match tcx.hir_opt_delegation_info(parent_def) { + Some(DelegationInfo { child_seg_id, .. }) if seg.hir_id == *child_seg_id => { + ExplicitLateBound::No + } + _ => prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos), + }; let mut invalid_args = vec![]; @@ -458,7 +467,7 @@ pub(crate) fn check_generic_arg_count( }; let reported = cx.dcx().emit_err(WrongNumberOfGenericArgs::new( - cx.tcx(), + tcx, gen_args_info, seg, gen_params, @@ -536,20 +545,19 @@ pub(crate) fn check_generic_arg_count( .map(|param| param.name) .collect(); if constraint_names == param_names { - let has_assoc_ty_with_same_name = - if let DefKind::Trait = cx.tcx().def_kind(def_id) { - gen_args.constraints.iter().any(|constraint| { - traits::supertrait_def_ids(cx.tcx(), def_id).any(|trait_did| { - cx.probe_trait_that_defines_assoc_item( - trait_did, - ty::AssocTag::Type, - constraint.ident, - ) - }) + let has_assoc_ty_with_same_name = if let DefKind::Trait = tcx.def_kind(def_id) { + gen_args.constraints.iter().any(|constraint| { + traits::supertrait_def_ids(tcx, def_id).any(|trait_did| { + cx.probe_trait_that_defines_assoc_item( + trait_did, + ty::AssocTag::Type, + constraint.ident, + ) }) - } else { - false - }; + }) + } else { + false + }; // We set this to true and delay emitting `WrongNumberOfGenericArgs` // to provide a succinct error for cases like issue #113073, // but only if when we don't have any assoc type with the same name with a @@ -573,7 +581,7 @@ pub(crate) fn check_generic_arg_count( let reported = gen_args.has_err().unwrap_or_else(|| { cx.dcx() .create_err(WrongNumberOfGenericArgs::new( - cx.tcx(), + tcx, gen_args_info, seg, gen_params, diff --git a/tests/pretty/delegation-self-rename.pp b/tests/pretty/delegation-self-rename.pp index 7f7afc403607b..526021c061178 100644 --- a/tests/pretty/delegation-self-rename.pp +++ b/tests/pretty/delegation-self-rename.pp @@ -19,15 +19,18 @@ #[attr = Inline(Hint)] fn foo<'a, Self, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(self: _, arg1: _) -> _ where - 'a:'a { Trait::<'a, A, B>::foo::(self, arg1) } + 'a:'a { >::foo::(self, arg1) } #[attr = Inline(Hint)] fn bar usize>(self: _, arg1: _) - -> _ { Trait::<'static, (), true>::foo::(self, arg1) } + -> + _ { + >::foo::(self, arg1) +} #[attr = Inline(Hint)] fn foo2<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { foo::(arg0, arg1) } + 'a:'a { foo::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar2 usize>(arg0: _, arg1: _) -> _ { bar::(arg0, arg1) } @@ -36,7 +39,7 @@ #[attr = Inline(Hint)] fn foo3<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { foo2::(arg0, arg1) } + 'a:'a { foo2::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar3 usize>(arg0: _, arg1: _) -> _ { bar2::(arg0, arg1) } @@ -47,7 +50,7 @@ #[attr = Inline(Hint)] fn foo4<'a, This, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(arg0: _, arg1: _) -> _ where - 'a:'a { <() as Trait2>::foo3::(arg0, arg1) } + 'a:'a { <() as Trait2>::foo3::<'a, This, A, B, B2, T, U>(arg0, arg1) } #[attr = Inline(Hint)] fn bar4 usize>(arg0: _, arg1: _) -> _ { <() as Trait2>::bar3::(arg0, arg1) } diff --git a/tests/ui/delegation/generics/free-fn-to-trait-infer.rs b/tests/ui/delegation/generics/free-fn-to-trait-infer.rs deleted file mode 100644 index 0a0665b752681..0000000000000 --- a/tests/ui/delegation/generics/free-fn-to-trait-infer.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ compile-flags: -Z deduplicate-diagnostics=yes - -#![feature(fn_delegation)] - -trait Trait { - fn foo(&self, _: U, _: T) {} -} - -impl Trait for u8 {} - -reuse Trait::<_>::foo:: as generic_arguments1; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -reuse >::foo as generic_arguments2; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -reuse <_ as Trait<_>>::foo as generic_arguments3; -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions -//~| ERROR the placeholder `_` is not allowed within types on item signatures for functions - -fn main() {} diff --git a/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr b/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr deleted file mode 100644 index f1e9231cc4050..0000000000000 --- a/tests/ui/delegation/generics/free-fn-to-trait-infer.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:11:15 - | -LL | reuse Trait::<_>::foo:: as generic_arguments1; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:13:20 - | -LL | reuse >::foo as generic_arguments2; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:15:8 - | -LL | reuse <_ as Trait<_>>::foo as generic_arguments3; - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/free-fn-to-trait-infer.rs:15:19 - | -LL | reuse <_ as Trait<_>>::foo as generic_arguments3; - | ^ not allowed in type signatures - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/delegation/generics/free-to-trait-static-reuse.rs b/tests/ui/delegation/generics/free-to-trait-static-reuse.rs index e3d0bdbc7e9b0..3f52209ded317 100644 --- a/tests/ui/delegation/generics/free-to-trait-static-reuse.rs +++ b/tests/ui/delegation/generics/free-to-trait-static-reuse.rs @@ -20,17 +20,9 @@ reuse ::static_method as bar { self + 1 } reuse ::static_method::<'static, Vec, false> as bar2; reuse Trait::static_method as error { self - 123 } -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::<'static, i32, 123>::static_method as error2; -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } -//~^ ERROR: type annotations needed -//~| ERROR: delegation self type is not specified reuse ::static_method as error5; //~^ ERROR: the trait bound `String: Trait<'a, T, X>` is not satisfied diff --git a/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr b/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr index 8d87b9376acd4..04f5e60044cdc 100644 --- a/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr +++ b/tests/ui/delegation/generics/free-to-trait-static-reuse.stderr @@ -1,43 +1,11 @@ -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:22:14 - | -LL | reuse Trait::static_method as error { self - 123 } - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:25:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method as error2; - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:28:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: delegation self type is not specified - --> $DIR/free-to-trait-static-reuse.rs:31:14 - | -LL | reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - error[E0277]: the trait bound `Struct: Bound` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:39:49 + --> $DIR/free-to-trait-static-reuse.rs:31:49 | LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | ^^^^^^ unsatisfied trait bound | help: the trait `Bound` is not implemented for `Struct` - --> $DIR/free-to-trait-static-reuse.rs:38:1 + --> $DIR/free-to-trait-static-reuse.rs:30:1 | LL | struct Struct; | ^^^^^^^^^^^^^ @@ -55,68 +23,8 @@ LL | where LL | Self: Bound, | ^^^^^^^^ required by this bound in `Trait` -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:22:14 - | -LL | reuse Trait::static_method as error { self - 123 } - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:25:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method as error2; - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:28:35 - | -LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3; - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0283]: type annotations needed - --> $DIR/free-to-trait-static-reuse.rs:31:14 - | -LL | reuse Trait::static_method::<'static, Vec, false> as error4 { self + 4 } - | ^^^^^^^^^^^^^ cannot infer type - | -note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found - --> $DIR/free-to-trait-static-reuse.rs:14:1 - | -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0277]: the trait bound `String: Trait<'a, T, X>` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:35:8 + --> $DIR/free-to-trait-static-reuse.rs:27:8 | LL | reuse ::static_method as error5; | ^^^^^^ the trait `Trait<'a, T, X>` is not implemented for `String` @@ -131,13 +39,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct` error[E0277]: the trait bound `Struct: Bound` is not satisfied - --> $DIR/free-to-trait-static-reuse.rs:42:8 + --> $DIR/free-to-trait-static-reuse.rs:34:8 | LL | reuse ::static_method as error6; | ^^^^^^ unsatisfied trait bound | help: the trait `Bound` is not implemented for `Struct` - --> $DIR/free-to-trait-static-reuse.rs:38:1 + --> $DIR/free-to-trait-static-reuse.rs:30:1 | LL | struct Struct; | ^^^^^^^^^^^^^ @@ -155,7 +63,6 @@ LL | { LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {} | ------------- required by a bound in this associated function -error: aborting due to 11 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0283. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.rs b/tests/ui/delegation/generics/generics-gen-args-errors.rs index 4e1ac0a5e4176..6a8d1674fe184 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.rs +++ b/tests/ui/delegation/generics/generics-gen-args-errors.rs @@ -44,8 +44,6 @@ mod test_2 { fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} reuse foo::<> as bar1; - //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions - //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature reuse foo:: as bar2; //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied @@ -54,9 +52,9 @@ mod test_2 { reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; //~^ ERROR: use of undeclared lifetime name `'asdasd` - //~| ERROR: function takes 2 lifetime arguments but 5 lifetime arguments were supplied - //~| ERROR: function takes 3 generic arguments but 2 generic arguments were supplied - //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: function takes 2 lifetime arguments but 6 lifetime arguments were supplied + //~| ERROR: function takes 3 generic arguments but 1 generic argument was supplied + //~| ERROR: wrong infer used: expected '_, found: _ reuse foo:: as bar4; //~^ ERROR: cannot find type `asdasd` in this scope @@ -131,12 +129,13 @@ mod test_3 { //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - //~^ ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR: trait takes 2 generic arguments but 5 generic arguments were supplied + //~^ ERROR: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied + //~| ERROR: trait takes 2 generic arguments but 4 generic arguments were supplied //~| ERROR: method takes 2 generic arguments but 5 generic arguments were supplied //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected '_, found: _ } fn main() {} diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.stderr b/tests/ui/delegation/generics/generics-gen-args-errors.stderr index 7aa1766dfef89..c08e23e6c016a 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.stderr +++ b/tests/ui/delegation/generics/generics-gen-args-errors.stderr @@ -38,7 +38,7 @@ LL | reuse foo:: as xd; = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0261]: use of undeclared lifetime name `'asdasd` - --> $DIR/generics-gen-args-errors.rs:55:29 + --> $DIR/generics-gen-args-errors.rs:53:29 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; | ^^^^^^^ undeclared lifetime @@ -49,7 +49,7 @@ LL | reuse foo'asdasd, ::<'static, _, 'asdasd, 'static, 'static, 'static, _> | ++++++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generics-gen-args-errors.rs:77:50 + --> $DIR/generics-gen-args-errors.rs:75:50 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^ undeclared lifetime @@ -103,65 +103,77 @@ LL | fn check() { | +++++ error[E0425]: cannot find type `asdasd` in this scope - --> $DIR/generics-gen-args-errors.rs:61:39 + --> $DIR/generics-gen-args-errors.rs:59:39 | LL | reuse foo:: as bar4; | ^^^^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:71:22 + --> $DIR/generics-gen-args-errors.rs:69:22 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:77:27 + --> $DIR/generics-gen-args-errors.rs:75:27 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:19 + --> $DIR/generics-gen-args-errors.rs:92:19 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:24 + --> $DIR/generics-gen-args-errors.rs:92:24 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:29 + --> $DIR/generics-gen-args-errors.rs:92:29 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:34 + --> $DIR/generics-gen-args-errors.rs:92:34 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asd` in this scope - --> $DIR/generics-gen-args-errors.rs:94:39 + --> $DIR/generics-gen-args-errors.rs:92:39 | LL | reuse Trait::::foo as bar1; | ^^^ not found in this scope error[E0425]: cannot find type `asdasa` in this scope - --> $DIR/generics-gen-args-errors.rs:94:44 + --> $DIR/generics-gen-args-errors.rs:92:44 | LL | reuse Trait::::foo as bar1; | ^^^^^^ not found in this scope error[E0425]: cannot find type `DDDD` in this scope - --> $DIR/generics-gen-args-errors.rs:124:34 + --> $DIR/generics-gen-args-errors.rs:122:34 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^ not found in this scope +error: wrong infer used: expected '_, found: _ + --> $DIR/generics-gen-args-errors.rs:53:26 + | +LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/generics-gen-args-errors.rs:131:33 + | +LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; + | ^ + error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied --> $DIR/generics-gen-args-errors.rs:33:15 | @@ -184,20 +196,8 @@ error: inferred lifetimes are not allowed in delegations as we need to inherit s LL | reuse foo:: as xd; | ^^^ -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:46:11 - | -LL | reuse foo::<> as bar1; - | ^^^ - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:46:11 - | -LL | reuse foo::<> as bar1; - | ^^^ not allowed in type signatures - error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ expected 2 lifetime arguments @@ -213,7 +213,7 @@ LL | reuse foo::<'a, 'b, String, String> as bar2; | +++++++ error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ ------ ------ supplied 2 generic arguments @@ -231,16 +231,16 @@ LL | reuse foo:: as bar2; | +++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:50:11 + --> $DIR/generics-gen-args-errors.rs:48:11 | LL | reuse foo:: as bar2; | ^^^ -error[E0107]: function takes 2 lifetime arguments but 5 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:55:11 +error[E0107]: function takes 2 lifetime arguments but 6 lifetime arguments were supplied + --> $DIR/generics-gen-args-errors.rs:53:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ --------------------------- help: remove the lifetime arguments + | ^^^------------------------------------------------- help: remove the lifetime arguments | | | expected 2 lifetime arguments | @@ -250,30 +250,24 @@ note: function defined here, with 2 lifetime parameters: `'a`, `'b` LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ -- -- -error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:55:11 +error[E0107]: function takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/generics-gen-args-errors.rs:53:11 | LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ expected 3 generic arguments ------- - supplied 2 generic arguments + | ^^^ expected 3 generic arguments - supplied 1 generic argument | note: function defined here, with 3 generic parameters: `T`, `U`, `N` --> $DIR/generics-gen-args-errors.rs:44:8 | LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- -help: add missing generic argument +help: add missing generic arguments | -LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, N> as bar3; - | +++ - -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:55:11 - | -LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3; - | ^^^ +LL | reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _, U, N> as bar3; + | ++++++ error[E0107]: function takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:61:11 + --> $DIR/generics-gen-args-errors.rs:59:11 | LL | reuse foo:: as bar4; | ^^^ ------ supplied 1 lifetime argument @@ -291,13 +285,13 @@ LL | reuse foo:: as bar4; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:61:11 + --> $DIR/generics-gen-args-errors.rs:59:11 | LL | reuse foo:: as bar4; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ expected 2 lifetime arguments @@ -313,10 +307,10 @@ LL | reuse foo::<'a, 'b, 1, 2, _, 4, 5, _> as bar5; | +++++++ error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; - | ^^^ --------- help: remove the unnecessary generic arguments + | ^^^------------------- help: remove the unnecessary generic arguments | | | expected 3 generic arguments | @@ -327,13 +321,13 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:66:11 + --> $DIR/generics-gen-args-errors.rs:64:11 | LL | reuse foo::<1, 2, _, 4, 5, _> as bar5; | ^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ expected 2 lifetime arguments @@ -349,7 +343,7 @@ LL | reuse foo::<'a, 'b, 1, 2,asd,String, { let x = 0; }> as bar6; | +++++++ error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ ----------------------- help: remove the unnecessary generic arguments @@ -363,25 +357,25 @@ LL | fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} | ^^^ - - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:71:11 + --> $DIR/generics-gen-args-errors.rs:69:11 | LL | reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6; | ^^^ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:77:11 + --> $DIR/generics-gen-args-errors.rs:75:11 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^ error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:77:17 + --> $DIR/generics-gen-args-errors.rs:75:17 | LL | reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7; | ^^^^^^^^ error[E0107]: function takes 2 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:83:11 + --> $DIR/generics-gen-args-errors.rs:81:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ expected 2 lifetime arguments @@ -397,19 +391,19 @@ LL | reuse foo::<'a, 'b, {}, {}, {}> as bar8; | +++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:83:11 + --> $DIR/generics-gen-args-errors.rs:81:11 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -419,7 +413,7 @@ LL | reuse Trait::<'b, 'c, 'a, asd, asd, asd, asd, asd, asdasa>::foo as bar1 | +++++++++++ error[E0107]: trait takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ ----------------------- help: remove the unnecessary generic arguments @@ -427,19 +421,19 @@ LL | reuse Trait::::foo as bar1; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:94:11 + --> $DIR/generics-gen-args-errors.rs:92:11 | LL | reuse Trait::::foo as bar1; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ ------- ------- supplied 2 lifetime arguments @@ -447,7 +441,7 @@ LL | reuse Trait::<'static, 'static>::foo as bar2; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -457,25 +451,25 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar2; | +++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:105:11 + --> $DIR/generics-gen-args-errors.rs:103:11 | LL | reuse Trait::<'static, 'static>::foo as bar2; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -485,7 +479,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, 3, 4, 5>::foo as bar3; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ --------- help: remove the unnecessary generic arguments @@ -493,25 +487,25 @@ LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:109:11 + --> $DIR/generics-gen-args-errors.rs:107:11 | LL | reuse Trait::<1, 2, 3, 4, 5>::foo as bar3; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -521,7 +515,7 @@ LL | reuse Trait::<'b, 'c, 'a, 1, 2, true>::foo as bar4; | +++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ ------ help: remove the unnecessary generic argument @@ -529,19 +523,19 @@ LL | reuse Trait::<1, 2, true>::foo as bar4; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:114:11 + --> $DIR/generics-gen-args-errors.rs:112:11 | LL | reuse Trait::<1, 2, true>::foo as bar4; | ^^^^^ error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ ------- supplied 1 lifetime argument @@ -549,7 +543,7 @@ LL | reuse Trait::<'static>::foo as bar5; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -559,19 +553,19 @@ LL | reuse Trait::<'static, 'static, 'static>::foo as bar5; | ++++++++++++++++++ error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/generics-gen-args-errors.rs:119:11 + --> $DIR/generics-gen-args-errors.rs:117:11 | LL | reuse Trait::<'static>::foo as bar5; | ^^^^^ not allowed in type signatures error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ - supplied 1 lifetime argument @@ -579,7 +573,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- @@ -589,7 +583,7 @@ LL | reuse Trait::<1, 'static, 'static, 2, 'static, DDDD>::foo::<1, 2, 3, 4, | ++++++++++++++++++ error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ --------------- help: remove the unnecessary generic argument @@ -597,25 +591,25 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:124:11 + --> $DIR/generics-gen-args-errors.rs:122:11 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- @@ -625,7 +619,7 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<'d, 1, 2, 3, 4, 5, 6> as bar6 | +++ error[E0107]: method takes 2 generic arguments but 6 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ ------------ help: remove the unnecessary generic arguments @@ -633,73 +627,73 @@ LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:124:41 + --> $DIR/generics-gen-args-errors.rs:122:41 | LL | reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6; | ^^^ -error[E0107]: trait takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/generics-gen-args-errors.rs:133:11 +error[E0107]: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ^^^^^ ----- supplied 1 lifetime argument + | ^^^^^ ----- ----- supplied 2 lifetime arguments | | | expected 3 lifetime arguments | note: trait defined here, with 3 lifetime parameters: `'b`, `'c`, `'a` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ -- -- -- -help: add missing lifetime arguments +help: add missing lifetime argument | -LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ++++++++++++++++++ +LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; + | ++++ -error[E0107]: trait takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:11 +error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; - | ^^^^^ --- help: remove the unnecessary generic argument + | ^^^^^ ------------------------- help: remove the unnecessary generic arguments | | | expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `T`, `N` - --> $DIR/generics-gen-args-errors.rs:90:11 + --> $DIR/generics-gen-args-errors.rs:88:11 | LL | trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { | ^^^^^ - -------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:133:11 + --> $DIR/generics-gen-args-errors.rs:131:11 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^^^ error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ expected 1 lifetime argument | note: method defined here, with 1 lifetime parameter: `'d` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ -- help: add missing lifetime argument | -LL | reuse Trait::::foo::<'d, 1, 2, 3, _, 6> as bar7; +LL | reuse Trait::::foo::<'a, 1, 2, 3, _, 6> as bar7; | +++ error[E0107]: method takes 2 generic arguments but 5 generic arguments were supplied - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ --------- help: remove the unnecessary generic arguments @@ -707,13 +701,13 @@ LL | reuse Trait::::foo::<1, 2, 3, _, | expected 2 generic arguments | note: method defined here, with 2 generic parameters: `U`, `M` - --> $DIR/generics-gen-args-errors.rs:91:12 + --> $DIR/generics-gen-args-errors.rs:89:12 | LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/generics-gen-args-errors.rs:133:59 + --> $DIR/generics-gen-args-errors.rs:131:59 | LL | reuse Trait::::foo::<1, 2, 3, _, 6> as bar7; | ^^^ @@ -789,12 +783,12 @@ LL | reuse foo:: as xd; | + + error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:83:17 + --> $DIR/generics-gen-args-errors.rs:81:17 | LL | reuse foo::<{}, {}, {}> as bar8; | ^^ -error: aborting due to 75 previous errors +error: aborting due to 74 previous errors Some errors have detailed explanations: E0107, E0121, E0261, E0401, E0423, E0425, E0747. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/infers.rs b/tests/ui/delegation/generics/infers.rs new file mode 100644 index 0000000000000..d9205f510a7b4 --- /dev/null +++ b/tests/ui/delegation/generics/infers.rs @@ -0,0 +1,356 @@ +//@ compile-flags: -Z deduplicate-diagnostics=yes + +#![feature(fn_delegation)] + +// Some interesting cases: +mod selected_tests { + mod different_infers { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + // Should differentiate between lifetime and types/consts infers. + reuse foo::<_, '_, '_, '_> as bar; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + } + + mod self_type { + trait Trait<'a, X> { + fn method<'b: 'b, const M: usize>(&self) {} + fn r#static<'b, Y, const B: bool>() {} + } + + impl<'a, X> Trait<'a, X> for () {} + + reuse Trait::<'_, _>::method::<'_, _> as foo; + + reuse <_ as Trait<'_, _>>::method::<'_, _> as foo1; + reuse <() as Trait<'_, _>>::method::<'_, _> as foo2; + + reuse <_ as Trait<'_, _>>::r#static::<_, _> as foo3; + reuse <() as Trait<'_, _>>::r#static::<_, _> as foo4; + + reuse Trait::<'_, _>::r#static::<_, _> as foo5; + } + + mod late_bound_lifetimes { + fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} + + // 'c corresponds to infer. + reuse foo::<'_> as foo1; + + // Only 'c is generated in desugaring, second infer remains just infer in call path. + reuse foo::<'_, '_> as foo2; + //~^ ERROR: function takes 1 lifetime argument but 2 lifetime arguments were supplied + + reuse foo as foo3; + reuse foo::<'static> as foo4; + } + + mod non_angle_bracketed_args { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + reuse foo::('_, _, _, _) as bar; + //~^ ERROR: lifetimes must be followed by `+` to form a trait object type + //~| ERROR: at least one trait is required for an object type + //~| ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214] + //~| ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + } +} + +// All other stuff: +mod legacy_tests { + trait Trait { + fn foo(&self, _: U, _: T) {} + } + + impl Trait for u8 {} + + reuse Trait::<_>::foo:: as generic_arguments1; + reuse >::foo as generic_arguments2; + reuse <_ as Trait<_>>::foo as generic_arguments3; +} + +mod free_to_free { + fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + + reuse foo::<> as foo1; + reuse foo::<'_, _, _, _> as foo2; + reuse foo::<'static, String, _, _> as foo3; + reuse foo::<'_, _, 123, _> as foo4; + + reuse foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: function takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: function takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: function takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_, '_, _, _> as foo7; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse foo::<_> as foo9; + //~^ ERROR: function takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse foo::, _, _, ()> as foo10; + //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + + reuse foo::, _, _, ()> as foo11; + //~^ ERROR: function takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: function takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: use of undeclared lifetime name `'____` [E0261] + //~| ERROR: cannot find type `___` in this scope [E0425] + //~| ERROR: cannot find type `___` in this scope [E0425] + + reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: type provided when a constant was expected [E0747] + + reuse foo::<'_, unresolved_, _, _> as foo14; + //~^ ERROR: cannot find type `unresolved_` in this scope + + reuse foo::<_, _, _> as foo15; + //~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ +} + +mod free_to_trait { + pub trait Trait<'a, 'b, X, const C: usize, Y> { + fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + } + + struct X; + impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + //~^ ERROR: the type parameter `Some` is not constrained by the impl trait, self type, or predicates [E0207] + //~| ERROR: the type parameter `Params` is not constrained by the impl trait, self type, or predicates [E0207] + + mod child_only { + use super::*; + + reuse Trait::foo::<> as foo1; + reuse Trait::foo::<'_, _, _, _> as foo2; + reuse Trait::foo::<'static, String, _, _> as foo3; + reuse Trait::foo::<'_, _, 123, _> as foo4; + + reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: method takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_, '_, _, _> as foo7; + //~^ ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::foo::<_> as foo9; + //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::foo::, _, _, ()> as foo10; + //~^ ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied + + reuse Trait::foo::, _, _, ()> as foo11; + //~^ ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse Trait::foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: use of undeclared lifetime name `'____` [E0261] + //~| ERROR: cannot find type `___` in this scope [E0425] + //~| ERROR: cannot find type `___` in this scope [E0425] + + reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: type provided when a constant was expected [E0747] + + reuse Trait::foo::<'_, unresolved_, _, _> as foo14; + //~^ ERROR: cannot find type `unresolved_` in this scope + + reuse Trait::foo::<_, _, _> as foo15; + //~^ ERROR: method takes 3 generic arguments but 2 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + } + + mod parent_only { + use super::*; + + reuse Trait::<'_, 'static, _, _, _>::foo as foo1; + reuse Trait::<'_, '_, _, _, _>::foo as foo2; + + reuse Trait::<'_, (), _, '_, _>::foo as foo3; + //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<>::foo as foo4; + + reuse Trait::<_, _>::foo as foo5; + //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::<'_, '_>::foo as foo6; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions + + reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + + reuse Trait::<'static, 'static, (), 123, ()>::foo as foo8; + reuse Trait::<'static, 'static, _, _, _>::foo as foo9; + + reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; + //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied + + reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + //~^ ERROR: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _>::foo as foo12; + //~^ ERROR: trait takes 3 generic arguments but 1 generic argument was supplied + } + + mod parent_and_child_random { + use super::*; + + reuse Trait::<'_, 'static, _, _, _>::foo::<> as foo1; + reuse Trait::<'_, '_, _, _, _>::foo::<'_, _, _, _> as foo2; + + reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + //~^ ERROR: trait takes 2 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: trait takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<>::foo::<'_, _, 123, _> as foo4; + + reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + //~^ ERROR: trait takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: method takes 3 generic arguments but 5 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: method takes 3 generic arguments but 6 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 3 lifetime arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: wrong infer used: expected '_, found: _ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + //~^ ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + //~^ ERROR: method takes 3 generic arguments but 0 generic arguments were supplied + //~| ERROR: wrong infer used: expected '_, found: _ + + reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + //~^ ERROR: trait takes 3 generic arguments but 7 generic arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied [E0107] + //~| ERROR: struct takes at least 1 generic argument but 0 generic arguments were supplied [E0107] + + reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + //~^ ERROR: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied [E0107] + //~| ERROR: method takes 3 generic arguments but 4 generic arguments were supplied [E0107] + //~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + //~| ERROR: wrong infer used: expected _, found: '_ + + reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + //~^ ERROR: cannot find type `___` in this scope + //~| ERROR: cannot find type `___` in this scope + //~| ERROR: use of undeclared lifetime name `'____` + //~| ERROR: trait takes 3 generic arguments but 1 generic argument was supplied + } +} + +mod trait_impl_to_free { + pub trait Trait<'a, 'b, X, const C: usize, Y> { + fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self) {} + } + + struct S; + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for S {} + + mod to_reuse { + pub fn foo(_: ()) {} + } + + struct F1(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F1 { + reuse to_reuse::foo::<_, _, _> { self.0 } + //~^ ERROR: mismatched types + } + + struct F2(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F2 { + reuse to_reuse::foo { self.0 } + //~^ ERROR: mismatched types + //~| ERROR: function takes 0 lifetime arguments but 1 lifetime argument was supplied + } + + struct F3(S); + impl<'a, 'b, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for F3 { + reuse to_reuse::foo::<(), 123, ()> { self.0 } + //~^ ERROR: mismatched types + } +} + +fn main() {} diff --git a/tests/ui/delegation/generics/infers.stderr b/tests/ui/delegation/generics/infers.stderr new file mode 100644 index 0000000000000..1ab3ef232832e --- /dev/null +++ b/tests/ui/delegation/generics/infers.stderr @@ -0,0 +1,1296 @@ +error: lifetimes must be followed by `+` to form a trait object type + --> $DIR/infers.rs:54:21 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^ + | +help: consider adding a trait bound after the potential lifetime bound + | +LL | reuse foo::('_ + /* Trait */, _, _, _) as bar; + | +++++++++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:123:17 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:195:28 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse Trait::foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0261]: use of undeclared lifetime name `'____` + --> $DIR/infers.rs:316:51 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'____` here + | +LL | reuse Trait::<'static, 'static, _>::foo'____, ::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:123:24 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:123:32 + | +LL | reuse foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `unresolved_` in this scope + --> $DIR/infers.rs:132:21 + | +LL | reuse foo::<'_, unresolved_, _, _> as foo14; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:195:35 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:195:43 + | +LL | reuse Trait::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `unresolved_` in this scope + --> $DIR/infers.rs:204:32 + | +LL | reuse Trait::foo::<'_, unresolved_, _, _> as foo14; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:316:58 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error[E0425]: cannot find type `___` in this scope + --> $DIR/infers.rs:316:66 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^ not found in this scope + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:11:21 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:24 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:28 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:11:32 + | +LL | reuse foo::<_, '_, '_, '_> as bar; + | ^^ + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses + | +help: use angle brackets instead + | +LL - reuse foo::('_, _, _, _) as bar; +LL + reuse foo::<'_, _, _, _> as bar; + | + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:86:21 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:86:25 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:91:17 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:91:26 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:97:17 + | +LL | reuse foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:97:20 + | +LL | reuse foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:21 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:25 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:101:29 + | +LL | reuse foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:106:17 + | +LL | reuse foo::<_> as foo9; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:135:17 + | +LL | reuse foo::<_, _, _> as foo15; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:158:32 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:158:36 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:163:28 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:163:37 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:169:28 + | +LL | reuse Trait::foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:169:31 + | +LL | reuse Trait::foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:32 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:36 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:173:40 + | +LL | reuse Trait::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:178:28 + | +LL | reuse Trait::foo::<_> as foo9; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:207:28 + | +LL | reuse Trait::foo::<_, _, _> as foo15; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:218:34 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:226:23 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:226:26 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:41 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:44 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:244:48 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:260:34 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:268:23 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:268:26 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:268:40 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:268:44 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:276:38 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:276:47 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:283:64 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:283:67 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:65 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:69 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:289:73 + | +LL | reuse Trait::<'static, 'static, (), 123, ()>::foo::<'_, '_, '_, '_> as foo8; + | ^^ + +error: wrong infer used: expected '_, found: _ + --> $DIR/infers.rs:294:57 + | +LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + | ^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:41 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:44 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error: wrong infer used: expected _, found: '_ + --> $DIR/infers.rs:306:48 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^ + +error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/infers.rs:44:15 + | +LL | reuse foo::<'_, '_> as foo2; + | ^^^--------- help: remove the lifetime argument + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'c` + --> $DIR/infers.rs:38:12 + | +LL | fn foo<'a, 'b, 'c: 'c, 'd>(_: &'a &'b &'c &'d ()) {} + | ^^^ -- + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:52:12 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::('b, '_, _, _, _) as bar; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:52:12 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:54:15 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^^ + +error[E0224]: at least one trait is required for an object type + --> $DIR/infers.rs:54:21 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:54:25 + | +LL | reuse foo::('_, _, _, _) as bar; + | ^ not allowed in type signatures + +error[E0107]: function takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:86:11 + | +LL | reuse foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error[E0107]: function takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:91:11 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- + +error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:91:11 + | +LL | reuse foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error[E0107]: function takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:106:11 + | +LL | reuse foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse fooX, M, Y::<_> as foo9; + | +++++++ + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::<'b, Vec<'_>, _, _, ()> as foo10; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:110:11 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:110:17 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:110:17 + | +LL | reuse foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: function takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'b` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ -- +help: add missing lifetime argument + | +LL | reuse foo::<'b, Vec<_>, _, _, ()> as foo11; + | +++ + +error[E0107]: function takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:117:11 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:117:21 + | +LL | reuse foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:128:25 + | +LL | reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^ not allowed in type signatures + +error[E0747]: type provided when a constant was expected + --> $DIR/infers.rs:128:29 + | +LL | reuse foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | reuse foo::<'_, Vec<_>, { Vec> }, _> as foo13; + | + + + +error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied + --> $DIR/infers.rs:135:11 + | +LL | reuse foo::<_, _, _> as foo15; + | ^^^ + | | + | expected 3 generic arguments + | supplied 2 generic arguments + | +note: function defined here, with 3 generic parameters: `X`, `M`, `Y` + --> $DIR/infers.rs:79:8 + | +LL | fn foo<'a, 'b: 'b, 'c, X, const M: usize, Y>(_: &'a &'b &'c ()) {} + | ^^^ - -------------- - +help: add missing generic argument + | +LL | reuse fooY::<_, _, _> as foo15; + | + + +error[E0207]: the type parameter `Some` is not constrained by the impl trait, self type, or predicates + --> $DIR/infers.rs:146:18 + | +LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + | ^^^^ unconstrained type parameter + +error[E0207]: the type parameter `Params` is not constrained by the impl trait, self type, or predicates + --> $DIR/infers.rs:146:24 + | +LL | impl<'a, 'b, Some, Params, X, const C: usize, Y> Trait<'a, 'b, X, C, Y> for X {} + | ^^^^^^ unconstrained type parameter + +error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:158:22 + | +LL | reuse Trait::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:163:22 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- + +error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:163:22 + | +LL | reuse Trait::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:178:22 + | +LL | reuse Trait::foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic arguments + | +LL | reuse Trait::fooXX, M, YY::<_> as foo9; + | +++++++++ + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::foo::<'a, Vec<'_>, _, _, ()> as foo10; + | +++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:182:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:182:28 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:182:28 + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse Trait::foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::foo::<'a, Vec<_>, _, _, ()> as foo11; + | +++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:189:22 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:189:32 + | +LL | reuse Trait::foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:200:36 + | +LL | reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^ not allowed in type signatures + +error[E0747]: type provided when a constant was expected + --> $DIR/infers.rs:200:40 + | +LL | reuse Trait::foo::<'_, Vec<_>, Vec>, _> as foo13; + | ^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | reuse Trait::foo::<'_, Vec<_>, { Vec> }, _> as foo13; + | + + + +error[E0107]: method takes 3 generic arguments but 2 generic arguments were supplied + --> $DIR/infers.rs:207:22 + | +LL | reuse Trait::foo::<_, _, _> as foo15; + | ^^^ + | | + | expected 3 generic arguments + | supplied 2 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic argument + | +LL | reuse Trait::fooYY::<_, _, _> as foo15; + | ++ + +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ --- supplied 1 lifetime argument + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- +help: add missing lifetime argument + | +LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a as foo3; + | ++++ + +error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:218:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo as foo3; + | ^^^^^ + +error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:226:15 + | +LL | reuse Trait::<_, _>::foo as foo5; + | ^^^^^ expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<_, _>::foo, X, C, Y as foo5; + | +++++++++ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:231:15 + | +LL | reuse Trait::<'_, '_>::foo as foo6; + | ^^^^^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:234:35 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:234:52 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo as foo7; + | ^ not allowed in type signatures + +error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied + --> $DIR/infers.rs:241:15 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo as foo10; + | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error[E0107]: trait takes 2 lifetime arguments but 6 lifetime arguments were supplied + --> $DIR/infers.rs:244:15 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_, '_>::foo as foo11; + | ^^^^^ --------------------------- help: remove the lifetime arguments + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- + +error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/infers.rs:250:15 + | +LL | reuse Trait::<'static, 'static, _>::foo as foo12; + | ^^^^^ --- supplied 1 generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _>::foo, C, Y as foo12; + | ++++++ + +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ --- supplied 1 lifetime argument + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- +help: add missing lifetime argument + | +LL | reuse Trait::<'_, (), _, '_, _>::foo, 'a::<'static, String, _, _> as foo3; + | ++++ + +error[E0107]: trait takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ --- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:260:15 + | +LL | reuse Trait::<'_, (), _, '_, _>::foo::<'static, String, _, _> as foo3; + | ^^^^^ + +error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:268:15 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^^^ expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<_, _>::foo, X, C, Y::<'_, '_, '_, _, _, _,> as foo5; + | +++++++++ + +error[E0107]: method takes 3 generic arguments but 5 generic arguments were supplied + --> $DIR/infers.rs:268:30 + | +LL | reuse Trait::<_, _>::foo::<'_, '_, '_, _, _, _,> as foo5; + | ^^^---------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:276:15 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^^^ not allowed in type signatures + +error[E0107]: method takes 1 lifetime argument but 3 lifetime arguments were supplied + --> $DIR/infers.rs:276:32 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^---------------------- help: remove the lifetime arguments + | | + | expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- + +error[E0107]: method takes 3 generic arguments but 6 generic arguments were supplied + --> $DIR/infers.rs:276:32 + | +LL | reuse Trait::<'_, '_>::foo::<_, _, _, '_, '_, '_, _, _, _,> as foo6; + | ^^^------------------------------- help: remove the unnecessary generic arguments + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:283:35 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:283:52 + | +LL | reuse Trait::<'_, '_, Vec<_>, 123, Vec>>::foo::<_, '_, _, _> as foo7; + | ^ not allowed in type signatures + +error[E0107]: method takes 3 generic arguments but 0 generic arguments were supplied + --> $DIR/infers.rs:294:51 + | +LL | reuse Trait::<'static, 'static, _, _, _>::foo::<_> as foo9; + | ^^^ expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _, _, _>::fooXX, M, YY::<_> as foo9; + | +++++++++ + +error[E0107]: trait takes 3 generic arguments but 7 generic arguments were supplied + --> $DIR/infers.rs:298:15 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^^^ expected 3 generic arguments ------- help: remove the unnecessary generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::<'bb, Vec<'_>, _, _, ()> as foo10; + | ++++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^-------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:298:63 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:298:69 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^---- help: remove the unnecessary generics + | | + | expected 0 lifetime arguments + +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied + --> $DIR/infers.rs:298:69 + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | reuse Trait::<'static, 'static, _, _, _, _, _, _, _>::foo::, _, _, ()> as foo10; + | +++ + +error[E0107]: trait takes 2 lifetime arguments but 5 lifetime arguments were supplied + --> $DIR/infers.rs:306:15 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^^^ ----------------------- help: remove the lifetime arguments + | | + | expected 2 lifetime arguments + | +note: trait defined here, with 2 lifetime parameters: `'a`, `'b` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ -- -- + +error[E0107]: method takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^ expected 1 lifetime argument + | +note: method defined here, with 1 lifetime parameter: `'bb` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ --- +help: add missing lifetime argument + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::<'bb, Vec<_>, _, _, ()> as foo11; + | ++++ + +error[E0107]: method takes 3 generic arguments but 4 generic arguments were supplied + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^------------------- help: remove the unnecessary generic argument + | | + | expected 3 generic arguments + | +note: method defined here, with 3 generic parameters: `XX`, `M`, `YY` + --> $DIR/infers.rs:142:12 + | +LL | fn foo<'aa, 'bb: 'bb, 'cc, XX, const M: usize, YY>(&self, _: &'aa &'b &'cc ()) {} + | ^^^ -- -------------- -- + +error: inferred lifetimes are not allowed in delegations as we need to inherit signature + --> $DIR/infers.rs:306:65 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/infers.rs:306:75 + | +LL | reuse Trait::<'static, 'static, '_,'_, '_, '_, '_, '_>::foo::, _, _, ()> as foo11; + | ^ not allowed in type signatures + +error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied + --> $DIR/infers.rs:316:15 + | +LL | reuse Trait::<'static, 'static, _>::foo::<'____, ___, _, ___> as foo12; + | ^^^^^ --- supplied 1 generic argument + | | + | expected 3 generic arguments + | +note: trait defined here, with 3 generic parameters: `X`, `C`, `Y` + --> $DIR/infers.rs:141:15 + | +LL | pub trait Trait<'a, 'b, X, const C: usize, Y> { + | ^^^^^ - -------------- - +help: add missing generic arguments + | +LL | reuse Trait::<'static, 'static, _>::foo, C, Y::<'____, ___, _, ___> as foo12; + | ++++++ + +error[E0308]: mismatched types + --> $DIR/infers.rs:338:42 + | +LL | reuse to_reuse::foo::<_, _, _> { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error[E0107]: function takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/infers.rs:344:25 + | +LL | reuse to_reuse::foo { self.0 } + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime argument + | +note: function defined here, with 0 lifetime parameters + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/infers.rs:344:31 + | +LL | reuse to_reuse::foo { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error[E0308]: mismatched types + --> $DIR/infers.rs:351:46 + | +LL | reuse to_reuse::foo::<(), 123, ()> { self.0 } + | --- ^^^^^^ expected `()`, found `S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/infers.rs:333:16 + | +LL | pub fn foo(_: ()) {} + | ^^^ ----- + +error: aborting due to 138 previous errors + +Some errors have detailed explanations: E0107, E0121, E0207, E0214, E0224, E0261, E0308, E0425, E0747. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs b/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs index 4073e5ce88607..7b33e1d16eadf 100644 --- a/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs +++ b/tests/ui/delegation/generics/trait-impl-wrong-args-count.rs @@ -26,6 +26,7 @@ mod test_1 { reuse to_reuse::bar1; //~^ ERROR: function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse to_reuse::bar2; //~^ ERROR: type annotations needed @@ -59,8 +60,10 @@ mod test_2 { impl Trait for X { reuse ::bar; //~^ ERROR: missing generics for trait + //~| ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied reuse >::bar as bar1; + //~^ ERROR: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied reuse >::bar::<'static, u32, u32, 1> as bar2; @@ -94,9 +97,11 @@ mod test_3 { impl Trait for X { reuse >::bar; //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse >::bar as bar1; //~^ ERROR: associated function takes 0 generic arguments but 3 generic arguments were supplied + //~| ERROR: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied reuse >::foo as bar2; //~^ ERROR: type annotations needed diff --git a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr index 09281768bbf73..931b61ef0ca85 100644 --- a/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr +++ b/tests/ui/delegation/generics/trait-impl-wrong-args-count.stderr @@ -13,11 +13,29 @@ note: function defined here, with at most 2 generic parameters: `A`, `B` LL | pub fn bar<'a: 'a, 'b: 'b, A, B>(x: &super::XX) {} | ^^^ - - +error[E0107]: function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:27:25 + | +LL | reuse to_reuse::bar1; + | ^^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:7:16 + | +LL | pub fn bar1(x: &super::XX) {} + | ^^^^ + error[E0107]: function takes 0 generic arguments but 3 generic arguments were supplied --> $DIR/trait-impl-wrong-args-count.rs:27:25 | LL | reuse to_reuse::bar1; - | ^^^^ expected 0 generic arguments + | ^^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: function defined here, with 0 generic parameters --> $DIR/trait-impl-wrong-args-count.rs:7:16 @@ -26,7 +44,7 @@ LL | pub fn bar1(x: &super::XX) {} | ^^^^ error[E0284]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:30:25 + --> $DIR/trait-impl-wrong-args-count.rs:31:25 | LL | reuse to_reuse::bar2; | ^^^^ cannot infer the value of the const parameter `X` declared on the function `bar2` @@ -42,7 +60,7 @@ LL | reuse to_reuse::bar2::; | ++++++++++++++++++++++++++ error[E0284]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:30:25 + --> $DIR/trait-impl-wrong-args-count.rs:31:25 | LL | reuse to_reuse::bar2; | ^^^^ cannot infer the value of the const parameter `Y` declared on the function `bar2` @@ -58,13 +76,13 @@ LL | reuse to_reuse::bar2::; | ++++++++++++++++++++++++++ error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:60:21 + --> $DIR/trait-impl-wrong-args-count.rs:61:21 | LL | reuse ::bar; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -73,14 +91,44 @@ help: add missing generic arguments LL | reuse >::bar; | ++++++ +error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:61:30 + | +LL | reuse ::bar; + | ^^^ + | | + | expected 1 lifetime argument + | help: remove the lifetime argument + | +note: associated function defined here, with 1 lifetime parameter: `'x` + --> $DIR/trait-impl-wrong-args-count.rs:53:12 + | +LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} + | ^^^ -- + +error[E0107]: associated function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:65:44 + | +LL | reuse >::bar as bar1; + | ^^^ + | | + | expected 1 lifetime argument + | help: remove the lifetime argument + | +note: associated function defined here, with 1 lifetime parameter: `'x` + --> $DIR/trait-impl-wrong-args-count.rs:53:12 + | +LL | fn bar<'x: 'x, AA, BB, const NN: usize>() {} + | ^^^ -- + error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:67:21 + --> $DIR/trait-impl-wrong-args-count.rs:70:21 | LL | reuse ::bar::<'static, u32, u32, 1> as bar3; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -90,13 +138,13 @@ LL | reuse >::bar::<'static, u32, u32, 1> as bar3; | ++++++ error[E0107]: missing generics for trait `test_2::Trait1` - --> $DIR/trait-impl-wrong-args-count.rs:70:21 + --> $DIR/trait-impl-wrong-args-count.rs:73:21 | LL | reuse ::bar as bar4; | ^^^^^^ expected 2 generic arguments | note: trait defined here, with 2 generic parameters: `A`, `B` - --> $DIR/trait-impl-wrong-args-count.rs:51:11 + --> $DIR/trait-impl-wrong-args-count.rs:52:11 | LL | trait Trait1 { | ^^^^^^ - - @@ -105,38 +153,74 @@ help: add missing generic arguments LL | reuse >::bar as bar4; | ++++++ +error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:98:40 + | +LL | reuse >::bar; + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: associated function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:89:12 + | +LL | fn bar() {} + | ^^^ + error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:95:40 + --> $DIR/trait-impl-wrong-args-count.rs:98:40 | LL | reuse >::bar; - | ^^^ expected 0 generic arguments + | ^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: associated function defined here, with 0 generic parameters - --> $DIR/trait-impl-wrong-args-count.rs:86:12 + --> $DIR/trait-impl-wrong-args-count.rs:89:12 + | +LL | fn bar() {} + | ^^^ + +error[E0107]: associated function takes 0 lifetime arguments but 2 lifetime arguments were supplied + --> $DIR/trait-impl-wrong-args-count.rs:102:40 + | +LL | reuse >::bar as bar1; + | ^^^ + | | + | expected 0 lifetime arguments + | help: remove the lifetime arguments + | +note: associated function defined here, with 0 lifetime parameters + --> $DIR/trait-impl-wrong-args-count.rs:89:12 | LL | fn bar() {} | ^^^ error[E0107]: associated function takes 0 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:98:40 + --> $DIR/trait-impl-wrong-args-count.rs:102:40 | LL | reuse >::bar as bar1; - | ^^^ expected 0 generic arguments + | ^^^ + | | + | expected 0 generic arguments + | help: remove the unnecessary generic arguments | note: associated function defined here, with 0 generic parameters - --> $DIR/trait-impl-wrong-args-count.rs:86:12 + --> $DIR/trait-impl-wrong-args-count.rs:89:12 | LL | fn bar() {} | ^^^ error[E0282]: type annotations needed - --> $DIR/trait-impl-wrong-args-count.rs:101:40 + --> $DIR/trait-impl-wrong-args-count.rs:106:40 | LL | reuse >::foo as bar2; | ^^^ cannot infer type of the type parameter `X` declared on the associated function `foo` error[E0107]: associated function takes at most 2 generic arguments but 3 generic arguments were supplied - --> $DIR/trait-impl-wrong-args-count.rs:104:40 + --> $DIR/trait-impl-wrong-args-count.rs:109:40 | LL | reuse >::foo as bar3; | ^^^ @@ -145,12 +229,12 @@ LL | reuse >::foo as bar3; | help: remove the unnecessary generic argument | note: associated function defined here, with at most 2 generic parameters: `X`, `Y` - --> $DIR/trait-impl-wrong-args-count.rs:87:12 + --> $DIR/trait-impl-wrong-args-count.rs:90:12 | LL | fn foo() {} | ^^^ - - -error: aborting due to 11 previous errors +error: aborting due to 16 previous errors Some errors have detailed explanations: E0107, E0282, E0284. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs index fad06b37ae416..1f97f7c652c35 100644 --- a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs +++ b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.rs @@ -1,3 +1,4 @@ +//@ check-pass //@ compile-flags: -Z deduplicate-diagnostics=yes #![feature(fn_delegation)] @@ -12,11 +13,8 @@ impl Trait for F {} struct S(F); impl S { reuse Trait::foo::<> { self.0 } - //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature + reuse Trait::foo::<'_> as bar { self.0 } - //~^ ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature - //~| WARN: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } fn main() {} diff --git a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr b/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr deleted file mode 100644 index 464b6a3a76819..0000000000000 --- a/tests/ui/delegation/generics/unelided-lifetime-in-sig-ice-156848.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:14:18 - | -LL | reuse Trait::foo::<> { self.0 } - | ^^^ - -warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 - | -LL | fn foo<'a: 'a>(&self) {} - | - the late bound lifetime parameter is introduced here -... -LL | reuse Trait::foo::<'_> as bar { self.0 } - | ^^ - | - = 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 #42868 - = note: `#[warn(late_bound_lifetime_arguments)]` (part of `#[warn(future_incompatible)]`) on by default - -error: inferred lifetimes are not allowed in delegations as we need to inherit signature - --> $DIR/unelided-lifetime-in-sig-ice-156848.rs:16:24 - | -LL | reuse Trait::foo::<'_> as bar { self.0 } - | ^^ - -error: aborting due to 2 previous errors; 1 warning emitted - diff --git a/tests/ui/delegation/self-ty-ice-156388.rs b/tests/ui/delegation/self-ty-ice-156388.rs index 542f56867b2b2..74cad01236375 100644 --- a/tests/ui/delegation/self-ty-ice-156388.rs +++ b/tests/ui/delegation/self-ty-ice-156388.rs @@ -1,8 +1,9 @@ //@ compile-flags: -Z deduplicate-diagnostics=yes +#![feature(const_trait_impl)] #![feature(fn_delegation)] reuse Default::default; -//~^ ERROR: delegation self type is not specified +//~^ ERROR: the trait bound `Self: [const] Default` is not satisfied fn main() {} diff --git a/tests/ui/delegation/self-ty-ice-156388.stderr b/tests/ui/delegation/self-ty-ice-156388.stderr index c2323cf1c6082..a311635db608a 100644 --- a/tests/ui/delegation/self-ty-ice-156388.stderr +++ b/tests/ui/delegation/self-ty-ice-156388.stderr @@ -1,10 +1,14 @@ -error: delegation self type is not specified - --> $DIR/self-ty-ice-156388.rs:5:16 +error[E0277]: the trait bound `Self: [const] Default` is not satisfied + --> $DIR/self-ty-ice-156388.rs:6:16 | LL | reuse Default::default; | ^^^^^^^ | - = help: consider explicitly specifying self type: `reuse ::function` +help: consider restricting type parameter `Self` with trait `Default` + | +LL | reuse Default::default [const] std::default::Default; + | +++++++++++++++++++++++++++++ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs index 14232d194a740..b4b3a31f437fc 100644 --- a/tests/ui/delegation/target-expr.rs +++ b/tests/ui/delegation/target-expr.rs @@ -15,7 +15,6 @@ fn foo(x: i32) -> i32 { x } fn bar(_: T) { reuse Trait::static_method { - //~^ ERROR: delegation self type is not specified let _ = T::Default(); //~^ ERROR can't use generic parameters from outer item } diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index 9126234a2c3cd..2ceefbf929b9f 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -1,18 +1,17 @@ error[E0401]: can't use generic parameters from outer item - --> $DIR/target-expr.rs:19:17 + --> $DIR/target-expr.rs:18:17 | LL | fn bar(_: T) { | - type parameter from outer item LL | reuse Trait::static_method { | ------------- generic parameter used in this inner delegated function -LL | LL | let _ = T::Default(); | ^ use of generic parameter from outer item | = note: nested items are independent from their parent item for everything except for privacy and name resolution error[E0434]: can't capture dynamic environment in a fn item - --> $DIR/target-expr.rs:27:17 + --> $DIR/target-expr.rs:26:17 | LL | let x = y; | ^ @@ -20,7 +19,7 @@ LL | let x = y; = help: use the `|| { ... }` closure form instead error[E0424]: expected value, found module `self` - --> $DIR/target-expr.rs:34:5 + --> $DIR/target-expr.rs:33:5 | LL | fn main() { | ---- this function can't have a `self` parameter @@ -29,26 +28,18 @@ LL | self.0; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter error[E0425]: cannot find value `x` in this scope - --> $DIR/target-expr.rs:36:13 + --> $DIR/target-expr.rs:35:13 | LL | let z = x; | ^ | help: the binding `x` is available in a different scope in the same function - --> $DIR/target-expr.rs:27:13 + --> $DIR/target-expr.rs:26:13 | LL | let x = y; | ^ -error: delegation self type is not specified - --> $DIR/target-expr.rs:17:18 - | -LL | reuse Trait::static_method { - | ^^^^^^^^^^^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0401, E0424, E0425, E0434. For more information about an error, try `rustc --explain E0401`. diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr index fdfd9251b4650..6cdd54e2e27fc 100644 --- a/tests/ui/delegation/unsupported.current.stderr +++ b/tests/ui/delegation/unsupported.current.stderr @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; = note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition = note: for more information, see and -error: delegation self type is not specified - --> $DIR/unsupported.rs:54:18 - | -LL | reuse Trait::foo; - | ^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr index fdfd9251b4650..6cdd54e2e27fc 100644 --- a/tests/ui/delegation/unsupported.next.stderr +++ b/tests/ui/delegation/unsupported.next.stderr @@ -20,14 +20,6 @@ LL | reuse ToReuse::opaque_ret; = note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition = note: for more information, see and -error: delegation self type is not specified - --> $DIR/unsupported.rs:54:18 - | -LL | reuse Trait::foo; - | ^^^ - | - = help: consider explicitly specifying self type: `reuse ::function` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index 3349c4ec27ab1..3da1206b5b2df 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -52,7 +52,6 @@ mod effects { } reuse Trait::foo; - //~^ ERROR: delegation self type is not specified } fn main() {} From 637142bb051b28443a051f03f1496c00708d63b5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 15 Jun 2026 19:50:56 +0200 Subject: [PATCH 10/11] Lift the same-signature restriction for `extern "tail"` --- compiler/rustc_codegen_ssa/src/mir/block.rs | 5 +- compiler/rustc_hir_typeck/src/check.rs | 2 +- .../rustc_mir_build/src/check_tail_calls.rs | 21 +++++++- compiler/rustc_target/src/callconv/mod.rs | 3 ++ compiler/rustc_ty_utils/src/abi.rs | 6 ++- .../no-unsized-arguments.aarch64.stderr | 31 ++++++++++++ .../no-unsized-arguments.rs | 50 +++++++++++++++++++ .../no-unsized-arguments.x86.stderr | 31 ++++++++++++ .../no-unsized-arguments.x86_64.stderr | 31 ++++++++++++ .../explicit-tail-calls/signature-mismatch.rs | 12 +++-- .../signature-mismatch.stderr | 17 +++++-- .../tailcc-no-signature-restriction.rs | 49 ++++++++++++++++++ 12 files changed, 245 insertions(+), 13 deletions(-) create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.rs create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr create mode 100644 tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr create mode 100644 tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d4932adeda1f9..ab983ceb72ffc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1317,7 +1317,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } LocalRef::Operand(arg) => { let Ref(place_value) = arg.val else { - bug!("only `Ref` should use `PassMode::Indirect`"); + bug!( + "only `Ref` should use `PassMode::Indirect`, but got {:?}", + arg.val + ); }; bx.typed_place_copy(place_value, tmp.val, fn_abi.args[i].layout); op.val = arg.val; diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 5fe1f4191c93f..1780430567a80 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -90,7 +90,7 @@ pub(super) fn check_fn<'a, 'tcx>( } // Check that argument is Sized. - if !params_can_be_unsized { + if !params_can_be_unsized || fn_sig.abi() == rustc_abi::ExternAbi::RustTail { fcx.require_type_is_sized( param_ty, param.ty_span, diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index 8052ee26df841..ac9f6e384cf04 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -147,7 +147,9 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { // ``` // we should think what is the expected behavior here. // (we should probably just accept this by revealing opaques?) - if caller_sig.inputs_and_output != callee_sig.inputs_and_output { + if caller_sig.inputs_and_output != callee_sig.inputs_and_output + && !matches!(callee_sig.abi(), ExternAbi::RustTail) + { let caller_ty = self.tcx.type_of(self.caller_def_id).skip_binder(); self.report_signature_mismatch( @@ -189,6 +191,12 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { if callee_sig.c_variadic() { self.report_c_variadic_callee(expr.span); } + + for &arg_ty in callee_sig.inputs() { + if !arg_ty.is_sized(self.tcx, self.typing_env) { + self.report_unsized_argument(expr.span, arg_ty); + } + } } /// Returns true if the caller function needs a location argument @@ -417,6 +425,17 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { self.found_errors = Err(err); } + + fn report_unsized_argument(&mut self, sp: Span, arg_ty: Ty<'tcx>) { + let err = self + .tcx + .dcx() + .struct_span_err(sp, format!("unsized arguments cannot be used in a tail call")) + .with_note(format!("unsized argument of type `{arg_ty}`")) + .emit(); + + self.found_errors = Err(err); + } } impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> { diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 7e1eafa10097f..30d16b5c7b1c9 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -827,6 +827,9 @@ impl<'a, Ty> FnAbi<'a, Ty> { ArgAttribute::default() }; arg.cast_to_with_attrs(Reg { kind: RegKind::Integer, size }, attr.into()); + } else if self.conv == CanonAbi::RustTail { + assert!(arg.layout.is_sized(), "extern \"tail\" arguments must be sized"); + arg.pass_by_stack_offset(None); } } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index e782557d126bf..5c67021c59c59 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -458,8 +458,10 @@ fn fn_abi_sanity_check<'tcx>( // omitted entirely in the calling convention. assert!(arg.is_ignore()); } - if let PassMode::Indirect { on_stack, .. } = arg.mode { - assert!(!on_stack, "rust abi shouldn't use on_stack"); + if let PassMode::Indirect { on_stack, .. } = arg.mode + && spec_abi != ExternAbi::RustTail + { + assert!(!on_stack, "rustic abi {spec_abi:?} shouldn't use on_stack"); } } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { assert_matches!( diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.aarch64.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.rs b/tests/ui/explicit-tail-calls/no-unsized-arguments.rs new file mode 100644 index 0000000000000..a0c5b53d8df0c --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.rs @@ -0,0 +1,50 @@ +//@ add-minicore +//@ ignore-backends: gcc +//@ min-llvm-version: 22 +// +//@ revisions: x86 x86_64 aarch64 +// +//@ [x86] compile-flags: --target=i686-unknown-linux-gnu +//@ [x86] needs-llvm-components: x86 +//@ [x86_64] compile-flags: --target=x86_64-unknown-linux-gnu +//@ [x86_64] needs-llvm-components: x86 +//@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu +//@ [aarch64] needs-llvm-components: aarch64 +#![feature(explicit_tail_calls, rust_tail_cc, unsized_fn_params, no_core)] +#![allow(incomplete_features, internal_features)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extract(_: [u8]) -> u8; +} + +fn vanilla(b: [u8]) -> u8 { + fn unsized_argument(x: [u8]) -> u8 { + unsafe { extract(x) } + } + + // Non-tail call. + let _ = unsized_argument(b); + + become unsized_argument(b); + //~^ ERROR unsized arguments cannot be used in a tail call +} + +extern "tail" fn tailcc(b: &[u8]) -> u8 { + // `extern "tail"` is special because we also can't unsized parameters in standard definitions + // and calls. + extern "tail" fn unsized_argument(x: [u8]) -> u8 { + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + unsafe { extract(x) } + } + + // Vanilla call. + let _ = unsized_argument(*b); + + become unsized_argument(*b); + //~^ ERROR unsized arguments cannot be used in a tail call +} diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr new file mode 100644 index 0000000000000..33e190e1a4a7f --- /dev/null +++ b/tests/ui/explicit-tail-calls/no-unsized-arguments.x86_64.stderr @@ -0,0 +1,31 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/no-unsized-arguments.rs:40:42 + | +LL | extern "tail" fn unsized_argument(x: [u8]) -> u8 { + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +help: function arguments must have a statically known size, borrowed slices always have a known size + | +LL | extern "tail" fn unsized_argument(x: &[u8]) -> u8 { + | + + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:33:5 + | +LL | become unsized_argument(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: unsized arguments cannot be used in a tail call + --> $DIR/no-unsized-arguments.rs:48:5 + | +LL | become unsized_argument(*b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsized argument of type `[u8]` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/explicit-tail-calls/signature-mismatch.rs b/tests/ui/explicit-tail-calls/signature-mismatch.rs index a32ac9d8bfee3..bed480f60f63b 100644 --- a/tests/ui/explicit-tail-calls/signature-mismatch.rs +++ b/tests/ui/explicit-tail-calls/signature-mismatch.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(explicit_tail_calls)] +#![feature(explicit_tail_calls, rust_tail_cc)] #![feature(c_variadic)] fn _f0((): ()) { @@ -8,26 +8,30 @@ fn _f0((): ()) { fn _g0() {} - fn _f1() { become _g1(()); //~ error: mismatched signatures } fn _g1((): ()) {} - extern "C" fn _f2() { become _g2(); //~ error: mismatched function ABIs } fn _g2() {} - fn _f3() { become _g3(); //~ error: mismatched function ABIs } extern "C" fn _g3() {} +extern "tail" fn _tailcc() {} + +fn _f4() { + // tailcc does not need the signatures to match, + // but only tailcc can tail call tailcc. + become _tailcc(); //~ error: mismatched function ABIs +} fn main() {} diff --git a/tests/ui/explicit-tail-calls/signature-mismatch.stderr b/tests/ui/explicit-tail-calls/signature-mismatch.stderr index ba9e9dcb98483..6e26f1c075539 100644 --- a/tests/ui/explicit-tail-calls/signature-mismatch.stderr +++ b/tests/ui/explicit-tail-calls/signature-mismatch.stderr @@ -9,7 +9,7 @@ LL | become _g0(); = note: callee signature: `fn()` error: mismatched signatures - --> $DIR/signature-mismatch.rs:13:5 + --> $DIR/signature-mismatch.rs:12:5 | LL | become _g1(()); | ^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | become _g1(()); = note: callee signature: `fn(())` error: mismatched function ABIs - --> $DIR/signature-mismatch.rs:20:5 + --> $DIR/signature-mismatch.rs:18:5 | LL | become _g2(); | ^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | become _g2(); = note: caller ABI is `"C"`, while callee ABI is `"Rust"` error: mismatched function ABIs - --> $DIR/signature-mismatch.rs:27:5 + --> $DIR/signature-mismatch.rs:24:5 | LL | become _g3(); | ^^^^^^^^^^^^ @@ -36,5 +36,14 @@ LL | become _g3(); = note: `become` requires caller and callee to have the same ABI = note: caller ABI is `"Rust"`, while callee ABI is `"C"` -error: aborting due to 4 previous errors +error: mismatched function ABIs + --> $DIR/signature-mismatch.rs:34:5 + | +LL | become _tailcc(); + | ^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have the same ABI + = note: caller ABI is `"Rust"`, while callee ABI is `"tail"` + +error: aborting due to 5 previous errors diff --git a/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs new file mode 100644 index 0000000000000..772e29260bcfb --- /dev/null +++ b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs @@ -0,0 +1,49 @@ +//@ run-pass +//@ ignore-backends: gcc +//@ min-llvm-version: 22 +//@ revisions: x86 x86_64 aarch64 +// +//@ [x86] only-x86 +//@ [x86_64] only-x86_64 +//@ [aarch64] only-aarch64 +#![feature(explicit_tail_calls, rust_tail_cc)] + +#[inline(never)] +pub extern "tail" fn add() -> u64 { + #[inline(never)] + extern "tail" fn add(a: u64, b: u64) -> u64 { + a.wrapping_add(b) + } + + become add(1, 2); +} + +#[inline(never)] +pub extern "tail" fn pass_struct(a: u64, d: u64) -> u64 { + #[derive(Clone, Copy)] + pub struct Large { + pub a: u64, + pub b: u64, + pub c: u64, + pub d: u64, + } + + #[inline(never)] + extern "tail" fn add(large: Large) -> u64 { + let _ = large.b; + let _ = large.c; + large.a.wrapping_add(large.d) + } + + let large = Large { a, b: 0xBBBB_BBBB_BBBB_BBBB, c: 0xCCCC_CCCC_CCCC_CCCC, d }; + become add(large); +} + +fn main() { + assert_eq!(add(), 3); + + // FIXME: LLVM 22 has a bug which makes this miscompile. + if false { + assert_eq!(pass_struct(5, 6), 5 + 6); + } +} From 2172c51b05018bac56cfb75af4f009d58aab53f1 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Tue, 23 Jun 2026 00:37:42 +0100 Subject: [PATCH 11/11] triagebot: Stop pinging myself https://www.github.com/rust-lang/team/pull/2523 --- triagebot.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index d68e4a4882159..9fd7bad75160f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1155,7 +1155,6 @@ otherwise, make sure you bump the `FORMAT_VERSION` constant. """ cc = [ "@CraftSpider", - "@aDotInTheVoid", "@Enselic", "@obi1kenobi", ] @@ -1313,7 +1312,7 @@ Please ensure that if you've changed the output: - It's intentional. - The `FORMAT_VERSION` in `src/librustdoc-json-types` is bumped if necessary. """ -cc = ["@aDotInTheVoid", "@obi1kenobi"] +cc = ["@obi1kenobi"] [mentions."tests/ui/derives/deriving-all-codegen.stdout"] message = "Changes to the code generated for builtin derived traits." @@ -1698,7 +1697,7 @@ dep-bumps = [ "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] "/tests/rustdoc-js/" = ["rustdoc"] -"/tests/rustdoc-json" = ["@aDotInTheVoid"] +"/tests/rustdoc-json" = ["rustdoc"] "/tests/rustdoc-ui" = ["rustdoc"] "/tests/ui" = ["compiler"] "/tests/ui-fulldeps" = ["compiler"]