From b12acb0b77aad34d4639628b0ab6b0451c1f416a Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 22 May 2026 10:14:32 +0300 Subject: [PATCH 1/7] Do not always generate first delegation argument --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/delegation.rs | 43 +++-- compiler/rustc_ast_lowering/src/errors.rs | 7 + compiler/rustc_ast_lowering/src/lib.rs | 69 +++++++- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 1 + compiler/rustc_parse/src/parser/item.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 52 ++++-- compiler/rustc_resolve/src/lib.rs | 5 + tests/ui/delegation/delegation-first-arg.rs | 83 +++++++++ .../ui/delegation/delegation-first-arg.stderr | 157 ++++++++++++++++++ ...ems-before-lowering-ices.ice_155128.stderr | 20 +-- .../hir-crate-items-before-lowering-ices.rs | 2 +- tests/ui/delegation/inner-attr.rs | 2 +- tests/ui/delegation/inner-attr.stderr | 18 +- .../zero-args-delegations-ice-154332.rs | 4 +- .../zero-args-delegations-ice-154332.stderr | 37 +---- .../zero-args-delegations-ice-154427.rs | 22 +++ .../zero-args-delegations-ice-154427.stderr | 25 +++ 21 files changed, 448 insertions(+), 109 deletions(-) create mode 100644 tests/ui/delegation/delegation-first-arg.rs create mode 100644 tests/ui/delegation/delegation-first-arg.stderr create mode 100644 tests/ui/delegation/zero-args-delegations-ice-154427.rs create mode 100644 tests/ui/delegation/zero-args-delegations-ice-154427.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 682ba78cddc5f..f31f940c766f8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3918,7 +3918,7 @@ pub struct Delegation { pub rename: Option, pub body: Option>, /// The item was expanded from a glob delegation item. - pub from_glob: bool, + pub from_glob_or_list: bool, } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1e96d1d52f7eb..7689e3453cd68 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -428,7 +428,6 @@ macro_rules! common_visitor_and_walkers { ConstItem, ConstItemRhsKind, Defaultness, - Delegation, DelegationMac, DelegationSuffixes, DelimArgs, @@ -573,6 +572,7 @@ macro_rules! common_visitor_and_walkers { fn visit_fn_decl(FnDecl); fn visit_fn_header(FnHeader); fn visit_fn_ret_ty(FnRetTy); + fn visit_delegation(Delegation); //fn visit_foreign_item(ForeignItem); fn visit_foreign_mod(ForeignMod); fn visit_format_args(FormatArgs); diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 5ea62010c3135..526be9a455a46 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -50,13 +50,16 @@ use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::span_bug; -use rustc_middle::ty::Asyncness; +use rustc_middle::ty::{Asyncness, TyCtxt}; use rustc_span::symbol::kw; use rustc_span::{Ident, Span, Symbol}; use smallvec::SmallVec; use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults}; -use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee}; +use crate::errors::{ + CycleInDelegationSignatureResolution, DelegationBlockSpecifiedWhenNoParams, + UnresolvedDelegationCallee, +}; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, ResolverAstLoweringExt, @@ -105,6 +108,12 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ }, ]; +// Function parameter count, including C variadic `...` if present. +pub(crate) fn param_count(tcx: TyCtxt<'_>, def_id: DefId) -> (usize, bool /*c_variadic*/) { + let sig = tcx.fn_sig(def_id).skip_binder().skip_binder(); + (sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic()) +} + impl<'hir> LoweringContext<'_, 'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { @@ -140,13 +149,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let is_method = self.is_method(sig_id, span); - let (param_count, c_variadic) = self.param_count(sig_id); + let (param_count, c_variadic) = param_count(self.tcx, sig_id); let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); let (body_id, call_expr_id) = self.lower_delegation_body( delegation, - is_method, + sig_id, param_count, &mut generics, span, @@ -264,12 +273,6 @@ impl<'hir> LoweringContext<'_, 'hir> { self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()) } - // Function parameter count, including C variadic `...` if present. - fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { - let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder(); - (sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic()) - } - fn lower_delegation_decl( &mut self, sig_id: DefId, @@ -397,7 +400,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_delegation_body( &mut self, delegation: &Delegation, - is_method: bool, + sig_id: DefId, param_count: usize, generics: &mut GenericsGenerationResults<'hir>, span: Span, @@ -409,12 +412,20 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut parameters: Vec> = Vec::with_capacity(param_count); let mut args: Vec> = Vec::with_capacity(param_count); + let is_method = this.is_method(sig_id, span); + + // Should be in sync with conditions in `lower_delayed_owner::is_dead_code`. + let generate_block = is_method + || matches!(this.tcx.def_kind(sig_id), DefKind::Fn) + || !delegation.from_glob_or_list; + for idx in 0..param_count { let (param, pat_node_id) = this.generate_param(is_method, idx, span); parameters.push(param); let arg = if let Some(block) = block && idx == 0 + && generate_block { let mut self_resolver = SelfResolver { ctxt: this, @@ -431,15 +442,13 @@ impl<'hir> LoweringContext<'_, 'hir> { args.push(arg); } - // If we have no params in signature function but user still wrote some code in - // delegation body, then add this code as first arg, eventually an error will be shown, - // also nested delegations may need to access information about this code (#154332), - // so it is better to leave this code as opposed to bodies of extern functions, - // which are completely erased from existence. + // Report an error if user has explicitly specified delegation's block + // in a single delegation when reused function has no params. if param_count == 0 + && !delegation.from_glob_or_list && let Some(block) = block { - args.push(this.lower_target_expr(&block)); + this.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); } let (final_expr, hir_id) = diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index a1c1d1e11d694..dc30d966e7593 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -535,3 +535,10 @@ pub(crate) struct CycleInDelegationSignatureResolution { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("delegation block is specified for function with no params")] +pub(crate) struct DelegationBlockSpecifiedWhenNoParams { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4045f08c053ed..3bcfd99ee2eef 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -541,13 +541,21 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut delayed_ids: FxIndexSet = Default::default(); for def_id in ast_index.indices() { - match &ast_index[def_id] { + // Check if this def is inside delegation (or it is delegation itself), if so, + // we should lower it in delayed mode, as we need to resolve delegation in order + // to understand whether to generate block as first arg or not. + let def_inside_delegation = resolver.defs_in_delegations_blocks.contains_key(&def_id); + let is_delegation = matches!( + ast_index[def_id], AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { - delayed_ids.insert(def_id); - } - _ => lowerer.lower_node(def_id), - }; + | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) + ); + + if def_inside_delegation || is_delegation { + delayed_ids.insert(def_id); + } else { + lowerer.lower_node(def_id); + } } // Don't hash unless necessary, because it's expensive. @@ -576,10 +584,53 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { owners: Owners::Map(&mut map), }; - lowerer.lower_node(def_id); + let is_dead_code = || -> bool { + // Try to find enclosing delegation (delegation in which block this `def_id` is placed). + let Some(&parent_del) = resolver.defs_in_delegations_blocks.get(&def_id) else { + return false; + }; + + let from_glob_or_list = match &ast_index[parent_del] { + AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) + | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => { + d.from_glob_or_list + } + _ => unreachable!(), + }; - for (child_def_id, owner) in map { - tcx.feed_delayed_owner(child_def_id, owner); + let is_method_or_free = if let Some(info) = resolver.delegation_infos.get(&parent_del) + && let Some(sig_id) = resolver + .partial_res_map + .get(&info.resolution_node) + .and_then(|r| r.expect_full_res().opt_def_id()) + { + tcx.opt_associated_item(sig_id).is_some_and(|a| a.is_method()) + || matches!(tcx.def_kind(sig_id), DefKind::Fn) + } else { + // If delegation is unresolved for some reason we will generate an error delegation + // and some errors will be certainly emitted, so no delayed bugs should happen. + return false; + }; + + let (param_count, _) = delegation::param_count(tcx, parent_del.to_def_id()); + + // Should be in sync with conditions in `lower_delegation_body`. + (!is_method_or_free && from_glob_or_list) || param_count == 0 + }; + + if !is_dead_code() { + lowerer.lower_node(def_id); + + for (child_def_id, owner) in map { + // We can encounter `NonOwner` which will result in a phantom being written + // to the map, however this `NonOwner` could be inserted from lowering of + // other owner (for example use trees), so we do not feed delayed_owner + // with Phantom as (1) it is Phantom by default, (2) we want to avoid + // consistency assert during query feeding. + if !matches!(owner, hir::MaybeOwner::Phantom) { + tcx.feed_delayed_owner(child_def_id, owner); + } + } } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 741c34e0304af..66e816fb57302 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2066,7 +2066,7 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>( ident: rename.unwrap_or(ident), rename, body: deleg.body.clone(), - from_glob, + from_glob_or_list: true, })), tokens: None, } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9ea476c48b206..fdee5626e4548 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -258,6 +258,7 @@ pub struct ResolverAstLowering<'tcx> { // Information about delegations which is used when handling recursive delegations pub delegation_infos: LocalDefIdMap, + pub defs_in_delegations_blocks: LocalDefIdMap, pub disambiguators: LocalDefIdMap>, } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3f6429c6a60f0..8bfaa3acad392 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -909,7 +909,7 @@ impl<'a> Parser<'a> { ident, rename, body: self.parse_delegation_body()?, - from_glob: false, + from_glob_or_list: false, })) }) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 4fd98944909dc..fb84a70d31934 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1461,7 +1461,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let parent = self.parent_scope.module.expect_local(); let expansion = self.parent_scope.expansion; self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); - } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) + } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob_or_list) && ident.name != kw::Underscore { // Don't add underscore names, they cannot be looked up anyway. diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index cdc2df5bf2945..fc3b3ca845b8f 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -50,21 +50,39 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { name: Option, def_kind: DefKind, span: Span, + ) -> TyCtxtFeed<'tcx, LocalDefId> { + self.create_feed(node_id, name, def_kind, span, false) + } + + fn create_feed( + &mut self, + node_id: NodeId, + name: Option, + def_kind: DefKind, + span: Span, + is_owner: bool, ) -> TyCtxtFeed<'tcx, LocalDefId> { let parent_def = self.invocation_parent.parent_def; debug!( "create_def(node_id={:?}, def_kind={:?}, parent_def={:?})", node_id, def_kind, parent_def ); - self.r.create_def( + + let feed = self.r.create_def( parent_def, node_id, name, def_kind, self.parent_scope.expansion.to_expn_id(), span.with_parent(None), - false, - ) + is_owner, + ); + + if let Some(last_delegation) = self.invocation_parent.last_delegation { + self.r.defs_in_delegations_blocks.insert(feed.def_id(), last_delegation); + } + + feed } fn with_parent(&mut self, parent_def: LocalDefId, f: F) { @@ -86,16 +104,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { // We only get here if the owner didn't exist yet. After the owner has been created, // future invocations of `collect_definitions` will get the owner out of the `owners` // table. - let parent_def = self.invocation_parent.parent_def; - let feed = self.r.create_def( - parent_def, - owner, - name, - def_kind, - self.parent_scope.expansion.to_expn_id(), - span.with_parent(None), - true, - ); + + let feed = self.create_feed(owner, name, def_kind, span, true); let tables = PerOwnerResolverData::new(owner, feed.key()); let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner); @@ -240,6 +250,22 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ); } + fn visit_delegation(&mut self, node: &'a Delegation) { + // Do not map defs in path (i.e., consts with blocks), consider only + // delegation's block which is its first argument. + visit::walk_path(self, &node.path); + node.qself.as_ref().inspect(|qself| visit::walk_qself(self, qself)); + + let orig_last_delegation = mem::replace( + &mut self.invocation_parent.last_delegation, + Some(self.invocation_parent.parent_def), + ); + + node.body.as_ref().inspect(|block| self.brg_visit_block(block)); + + self.invocation_parent.last_delegation = orig_last_delegation; + } + fn visit_block(&mut self, block: &'a Block) { self.brg_visit_block(block); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ffb2181bae3a9..82cd27b449433 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -188,6 +188,7 @@ struct InvocationParent { in_attr: bool, const_arg_context: ConstArgContext, owner: NodeId, + last_delegation: Option, } impl InvocationParent { @@ -197,6 +198,7 @@ impl InvocationParent { in_attr: false, const_arg_context: ConstArgContext::NonDirect, owner: CRATE_NODE_ID, + last_delegation: None, }; } @@ -1508,8 +1510,10 @@ pub struct Resolver<'ra, 'tcx> { item_generics_num_lifetimes: FxHashMap = default::fx_hash_map(), /// Generic args to suggest for required params (e.g. `<'_>`, `<_, _>`), if any. item_required_generic_args_suggestions: FxHashMap = default::fx_hash_map(), + delegation_fn_sigs: LocalDefIdMap = Default::default(), delegation_infos: LocalDefIdMap = Default::default(), + defs_in_delegations_blocks: LocalDefIdMap = Default::default(), main_def: Option = None, trait_impls: FxIndexMap>, @@ -2004,6 +2008,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { trait_map: self.trait_map, lint_buffer: Steal::new(self.lint_buffer), delegation_infos: self.delegation_infos, + defs_in_delegations_blocks: self.defs_in_delegations_blocks, disambiguators, }; ResolverOutputs { global_ctxt, ast_lowering } diff --git a/tests/ui/delegation/delegation-first-arg.rs b/tests/ui/delegation/delegation-first-arg.rs new file mode 100644 index 0000000000000..9d7175945da8b --- /dev/null +++ b/tests/ui/delegation/delegation-first-arg.rs @@ -0,0 +1,83 @@ +#![feature(fn_delegation)] + +trait Trait: Sized { + fn value(self) {} + fn r#ref(&self) {} + fn mut_ref(&mut self) {} + + fn static_empty() {} + fn static_one_param(x: usize) {} +} + +struct S; +impl Trait for S {} + +struct F(S); +// In glob delegations silently remove first arg if no params or generate default +// first arg (`arg0`) if it is a static function. +reuse impl Trait for F { self.0 } +//~^ ERROR: type annotations needed +//~| ERROR: type annotations needed + +struct F1(S); +impl F1 { + reuse Trait::{value, r#ref, mut_ref} { self.0 } + + // Error is reported as user has explicitly specified block when no params. + reuse ::static_empty { self.0 } + //~^ ERROR: delegation block is specified for function with no params + + reuse ::static_one_param { self.0 } + //~^ ERROR: `usize` is a primitive type and therefore doesn't have fields +} + +struct F2(S); +impl F2 { + // In list delegations silently remove first arg if it is not a method. + reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + //~^ ERROR: mismatched types + //~| ERROR: mismatched types +} + +mod trait_to_reuse { + use super::Trait; + + pub fn value(_: impl Trait) {} + pub fn r#ref(_: &impl Trait) {} + pub fn mut_ref(_: &mut impl Trait) {} + + pub fn static_empty() {} + pub fn static_one_param(x: usize) {} +} + +struct F3(S); +impl Trait for F3 { + reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + //~^ ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct F4(S); +impl F4 { + reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + //~^ ERROR: no field `0` on type `impl Trait` + //~| ERROR: no field `0` on type `&impl Trait` + //~| ERROR: no field `0` on type `&mut impl Trait` + //~| ERROR: `usize` is a primitive type and therefore doesn't have fields +} + +mod to_reuse { + pub fn empty() {} + pub fn one_param(x: usize) {} +} + +// Error is reported as user has explicitly specified block when no params. +reuse to_reuse::empty { self + 1 } +//~^ ERROR: delegation block is specified for function with no params + +reuse to_reuse::one_param { self + 1 } + +// In list delegations silently remove first arg if there are no params. +reuse to_reuse::{empty as empty1, one_param as one_param1} { self + 1 } + +fn main() {} diff --git a/tests/ui/delegation/delegation-first-arg.stderr b/tests/ui/delegation/delegation-first-arg.stderr new file mode 100644 index 0000000000000..b9c86e5ea8cd3 --- /dev/null +++ b/tests/ui/delegation/delegation-first-arg.stderr @@ -0,0 +1,157 @@ +error: delegation block is specified for function with no params + --> $DIR/delegation-first-arg.rs:27:38 + | +LL | reuse ::static_empty { self.0 } + | ^^^^^^^^^^ + +error: delegation block is specified for function with no params + --> $DIR/delegation-first-arg.rs:75:23 + | +LL | reuse to_reuse::empty { self + 1 } + | ^^^^^^^^^^^^ + +error[E0283]: type annotations needed + --> $DIR/delegation-first-arg.rs:18:1 + | +LL | reuse impl Trait for F { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: the type must implement `Trait` +help: the following types implement trait `Trait` + --> $DIR/delegation-first-arg.rs:13:1 + | +LL | impl Trait for S {} + | ^^^^^^^^^^^^^^^^ `S` +... +LL | reuse impl Trait for F { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^ `F` +... +LL | impl Trait for F3 { + | ^^^^^^^^^^^^^^^^^ `F3` + +error[E0283]: type annotations needed + --> $DIR/delegation-first-arg.rs:18:1 + | +LL | reuse impl Trait for F { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: the type must implement `Trait` +help: the following types implement trait `Trait` + --> $DIR/delegation-first-arg.rs:13:1 + | +LL | impl Trait for S {} + | ^^^^^^^^^^^^^^^^ `S` +... +LL | reuse impl Trait for F { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^ `F` +... +LL | impl Trait for F3 { + | ^^^^^^^^^^^^^^^^^ `F3` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0610]: `usize` is a primitive type and therefore doesn't have fields + --> $DIR/delegation-first-arg.rs:30:49 + | +LL | reuse ::static_one_param { self.0 } + | ^ + +error[E0308]: mismatched types + --> $DIR/delegation-first-arg.rs:37:83 + | +LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ----- arguments to this function are incorrect ^^^^^^ expected `&S`, found `S` + | +note: method defined here + --> $DIR/delegation-first-arg.rs:5:8 + | +LL | fn r#ref(&self) {} + | ^^^^^ ----- +help: consider borrowing here + | +LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { &self.0 } + | + + +error[E0308]: mismatched types + --> $DIR/delegation-first-arg.rs:37:83 + | +LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ------- ^^^^^^ expected `&mut S`, found `S` + | | + | arguments to this function are incorrect + | +note: method defined here + --> $DIR/delegation-first-arg.rs:6:8 + | +LL | fn mut_ref(&mut self) {} + | ^^^^^^^ --------- +help: consider mutably borrowing here + | +LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { &mut self.0 } + | ++++ + +error[E0308]: mismatched types + --> $DIR/delegation-first-arg.rs:55:85 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ----- arguments to this function are incorrect ^^^^^^ expected `&_`, found `S` + | + = note: expected reference `&_` + found struct `S` +note: function defined here + --> $DIR/delegation-first-arg.rs:46:12 + | +LL | pub fn r#ref(_: &impl Trait) {} + | ^^^^^ -------------- +help: consider borrowing here + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { &self.0 } + | + + +error[E0308]: mismatched types + --> $DIR/delegation-first-arg.rs:55:85 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ------- ^^^^^^ expected `&mut _`, found `S` + | | + | arguments to this function are incorrect + | + = note: expected mutable reference `&mut _` + found struct `S` +note: function defined here + --> $DIR/delegation-first-arg.rs:47:12 + | +LL | pub fn mut_ref(_: &mut impl Trait) {} + | ^^^^^^^ ------------------ +help: consider mutably borrowing here + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { &mut self.0 } + | ++++ + +error[E0609]: no field `0` on type `impl Trait` + --> $DIR/delegation-first-arg.rs:62:90 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^ unknown field + +error[E0609]: no field `0` on type `&impl Trait` + --> $DIR/delegation-first-arg.rs:62:90 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^ unknown field + +error[E0609]: no field `0` on type `&mut impl Trait` + --> $DIR/delegation-first-arg.rs:62:90 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^ unknown field + +error[E0610]: `usize` is a primitive type and therefore doesn't have fields + --> $DIR/delegation-first-arg.rs:62:90 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^ + +error: aborting due to 13 previous errors + +Some errors have detailed explanations: E0283, E0308, E0609, E0610. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr index 833b0869002e2..ebfc526b62cf9 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr @@ -1,24 +1,12 @@ -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/hir-crate-items-before-lowering-ices.rs:36:11 +error: delegation block is specified for function with no params + --> $DIR/hir-crate-items-before-lowering-ices.rs:36:18 | LL | reuse a as b { - | ___________^______- + | __________________^ LL | | fn foo() {}; LL | | foo LL | | } - | |_____- unexpected argument of type `fn() {foo::<_>}` - | -note: function defined here - --> $DIR/hir-crate-items-before-lowering-ices.rs:34:8 - | -LL | fn a() {} - | ^ -help: remove the extra argument - | -LL - reuse a as b { -LL + reuse { - | + | |_____^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs index c223d5d4a5adc..28523fb91582c 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -33,7 +33,7 @@ mod ice_155127 { mod ice_155128 { fn a() {} - reuse a as b { //[ice_155128]~ ERROR: this function takes 0 arguments but 1 argument was supplied + reuse a as b { //[ice_155128]~ ERROR: delegation block is specified for function with no params fn foo() {}; foo } diff --git a/tests/ui/delegation/inner-attr.rs b/tests/ui/delegation/inner-attr.rs index 6bd2892095fc0..452b3b3b73d5b 100644 --- a/tests/ui/delegation/inner-attr.rs +++ b/tests/ui/delegation/inner-attr.rs @@ -3,6 +3,6 @@ fn a() {} reuse a as b { #![rustc_dummy] self } //~ ERROR an inner attribute is not permitted in this context -//~^ ERROR: this function takes 0 arguments but 1 argument was supplied +//~^ ERROR: delegation block is specified for function with no params fn main() {} diff --git a/tests/ui/delegation/inner-attr.stderr b/tests/ui/delegation/inner-attr.stderr index 307586ccef93d..d6f8cc752902d 100644 --- a/tests/ui/delegation/inner-attr.stderr +++ b/tests/ui/delegation/inner-attr.stderr @@ -9,23 +9,11 @@ LL | fn main() {} | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/inner-attr.rs:5:7 +error: delegation block is specified for function with no params + --> $DIR/inner-attr.rs:5:14 | LL | reuse a as b { #![rustc_dummy] self } - | ^ ---- unexpected argument - | -note: function defined here - --> $DIR/inner-attr.rs:3:4 - | -LL | fn a() {} - | ^ -help: remove the extra argument - | -LL - reuse a as b { #![rustc_dummy] self } -LL + reuse self } - | + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.rs b/tests/ui/delegation/zero-args-delegations-ice-154332.rs index a9d7876db5e87..b1810af36d450 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs @@ -3,7 +3,7 @@ mod test_ice { fn a() {} - reuse a as b { //~ ERROR: this function takes 0 arguments but 1 argument was supplied + reuse a as b { //~ ERROR: delegation block is specified for function with no params let closure = || { fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} @@ -23,7 +23,7 @@ mod test_2 { } reuse to_reuse::zero_args { self } - //~^ ERROR: this function takes 0 arguments but 1 argument was supplied + //~^ ERROR: delegation block is specified for function with no params } fn main() {} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr index 517a01dac6f0e..423b32511acf9 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr @@ -1,43 +1,20 @@ -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/zero-args-delegations-ice-154332.rs:6:11 +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154332.rs:6:18 | LL | reuse a as b { - | ___________^______- + | __________________^ LL | | let closure = || { LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} ... | LL | | closure(); LL | | } - | |_____- unexpected argument of type `()` - | -note: function defined here - --> $DIR/zero-args-delegations-ice-154332.rs:4:8 - | -LL | fn a() {} - | ^ -help: remove the extra argument - | -LL - reuse a as b { -LL + reuse { - | + | |_____^ -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/zero-args-delegations-ice-154332.rs:25:21 +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154332.rs:25:31 | LL | reuse to_reuse::zero_args { self } - | ^^^^^^^^^ ---- unexpected argument - | -note: function defined here - --> $DIR/zero-args-delegations-ice-154332.rs:20:16 - | -LL | pub fn zero_args() -> i32 { - | ^^^^^^^^^ -help: remove the extra argument - | -LL - reuse to_reuse::zero_args { self } -LL + reuse to_reuse::zero_argself } - | + | ^^^^^^^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.rs b/tests/ui/delegation/zero-args-delegations-ice-154427.rs new file mode 100644 index 0000000000000..b50066b057638 --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.rs @@ -0,0 +1,22 @@ +#![feature(fn_delegation)] + +mod ice_154427 { + trait Trait { + fn foo(); + } + struct F; + struct S; + mod to_reuse { + use super::F; + pub fn foo(_: F) {} + } + impl Trait for S { + reuse to_reuse::foo { self } + //~^ ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: delegation block is specified for function with no params + } + + fn main() {} +} + +fn main() {} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.stderr b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr new file mode 100644 index 0000000000000..b73976fedda74 --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr @@ -0,0 +1,25 @@ +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154427.rs:14:29 + | +LL | reuse to_reuse::foo { self } + | ^^^^^^^^ + +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/zero-args-delegations-ice-154427.rs:14:25 + | +LL | reuse to_reuse::foo { self } + | ^^^ argument #1 of type `F` is missing + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154427.rs:11:16 + | +LL | pub fn foo(_: F) {} + | ^^^ ---- +help: provide the argument + | +LL | reuse to_reuse::foo(/* F */) { self } + | +++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`. From 474cf3a46f167c4c28ba05289dea7e6478503af1 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 25 May 2026 09:44:26 +0300 Subject: [PATCH 2/7] Check if the delegation itself is a dead code --- compiler/rustc_ast_lowering/src/lib.rs | 18 +++++++++++---- .../zero-args-delegations-ice-154332.rs | 22 +++++++++++++++++++ .../zero-args-delegations-ice-154332.stderr | 15 ++++++++++++- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3bcfd99ee2eef..dfa7dc547c682 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -567,7 +567,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { } /// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. -pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { +pub fn lower_delayed_owner<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { let krate = tcx.hir_crate(()); let (resolver, krate) = &*krate.delayed_resolver.borrow(); @@ -584,12 +584,22 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { owners: Owners::Map(&mut map), }; - let is_dead_code = || -> bool { + fn is_dead_code<'tcx>( + tcx: TyCtxt<'tcx>, + resolver: &ResolverAstLowering<'tcx>, + ast_index: &IndexVec>, + def_id: LocalDefId, + ) -> bool { // Try to find enclosing delegation (delegation in which block this `def_id` is placed). let Some(&parent_del) = resolver.defs_in_delegations_blocks.get(&def_id) else { return false; }; + // Check if the delegation itself is a dead-code (recursively up to topmost delegation). + if is_dead_code(tcx, resolver, ast_index, parent_del) { + return true; + } + let from_glob_or_list = match &ast_index[parent_del] { AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => { @@ -616,9 +626,9 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Should be in sync with conditions in `lower_delegation_body`. (!is_method_or_free && from_glob_or_list) || param_count == 0 - }; + } - if !is_dead_code() { + if !is_dead_code(tcx, resolver, &ast_index, def_id) { lowerer.lower_node(def_id); for (child_def_id, owner) in map { diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.rs b/tests/ui/delegation/zero-args-delegations-ice-154332.rs index b1810af36d450..10d8def4c8c76 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs @@ -26,4 +26,26 @@ mod test_2 { //~^ ERROR: delegation block is specified for function with no params } +mod nested_delegations { + fn a() {} + + reuse a as b { //~ ERROR: delegation block is specified for function with no params + let closure = || { + reuse a as b { + fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} + + reuse foo:: as bar; + bar(&"".to_string(), &"".to_string()); + + reuse a as b { + reuse foo:: as bar; + bar(&"".to_string(), &"".to_string()); + } + } + }; + + closure(); + } +} + fn main() {} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr index 423b32511acf9..fd2f34eedabb7 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr @@ -16,5 +16,18 @@ error: delegation block is specified for function with no params LL | reuse to_reuse::zero_args { self } | ^^^^^^^^ -error: aborting due to 2 previous errors +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154332.rs:32:18 + | +LL | reuse a as b { + | __________________^ +LL | | let closure = || { +LL | | reuse a as b { +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | closure(); +LL | | } + | |_____^ + +error: aborting due to 3 previous errors From 376032fd370382281ff5c14b5287b644818ddcf1 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 25 May 2026 09:54:12 +0300 Subject: [PATCH 3/7] `from_glob_or_list` -> `DelegationSource` --- compiler/rustc_ast/src/ast.rs | 9 ++++++++- compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/src/delegation.rs | 5 +++-- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_expand/src/expand.rs | 6 +++++- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_resolve/src/build_reduced_graph.rs | 8 ++++---- 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f31f940c766f8..bb4b1828a29fc 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3908,6 +3908,13 @@ pub struct EiiImpl { pub is_default: bool, } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum DelegationSource { + Single, + List, + Glob, +} + #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct Delegation { /// Path resolution id. @@ -3918,7 +3925,7 @@ pub struct Delegation { pub rename: Option, pub body: Option>, /// The item was expanded from a glob delegation item. - pub from_glob_or_list: bool, + pub source: DelegationSource, } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 7689e3453cd68..e5db9e1cb19a3 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -430,6 +430,7 @@ macro_rules! common_visitor_and_walkers { Defaultness, DelegationMac, DelegationSuffixes, + DelegationSource, DelimArgs, DelimSpan, EnumDef, diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 526be9a455a46..9dd0e0c314b95 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -413,11 +413,12 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut args: Vec> = Vec::with_capacity(param_count); let is_method = this.is_method(sig_id, span); + let is_single_delegation = matches!(delegation.source, DelegationSource::Single); // Should be in sync with conditions in `lower_delayed_owner::is_dead_code`. let generate_block = is_method || matches!(this.tcx.def_kind(sig_id), DefKind::Fn) - || !delegation.from_glob_or_list; + || is_single_delegation; for idx in 0..param_count { let (param, pat_node_id) = this.generate_param(is_method, idx, span); @@ -445,7 +446,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Report an error if user has explicitly specified delegation's block // in a single delegation when reused function has no params. if param_count == 0 - && !delegation.from_glob_or_list + && is_single_delegation && let Some(block) = block { this.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dfa7dc547c682..7ca9f14c79b4a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -603,7 +603,7 @@ pub fn lower_delayed_owner<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { let from_glob_or_list = match &ast_index[parent_del] { AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => { - d.from_glob_or_list + !matches!(d.source, DelegationSource::Single) } _ => unreachable!(), }; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 66e816fb57302..ac16dbc2fa387 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2066,7 +2066,11 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>( ident: rename.unwrap_or(ident), rename, body: deleg.body.clone(), - from_glob_or_list: true, + source: if from_glob { + ast::DelegationSource::Glob + } else { + ast::DelegationSource::List + }, })), tokens: None, } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 8bfaa3acad392..7b9527a6730ae 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -909,7 +909,7 @@ impl<'a> Parser<'a> { ident, rename, body: self.parse_delegation_body()?, - from_glob_or_list: false, + source: DelegationSource::Single, })) }) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index fb84a70d31934..2f6b3d159c1e0 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -9,9 +9,9 @@ use std::sync::Arc; use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind}; use rustc_ast::{ - self as ast, AssocItem, AssocItemKind, Block, ConstItem, DUMMY_NODE_ID, Delegation, Fn, - ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, - TyAlias, + self as ast, AssocItem, AssocItemKind, Block, ConstItem, DUMMY_NODE_ID, Delegation, + DelegationSource, Fn, ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, + StmtKind, TraitAlias, TyAlias, }; use rustc_attr_parsing::AttributeParser; use rustc_expand::base::{ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; @@ -1461,7 +1461,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let parent = self.parent_scope.module.expect_local(); let expansion = self.parent_scope.expansion; self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); - } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob_or_list) + } else if !matches!(&item.kind, AssocItemKind::Delegation(d) if matches!(d.source, DelegationSource::Glob)) && ident.name != kw::Underscore { // Don't add underscore names, they cannot be looked up anyway. From 72bdcbb824d37535d60143a137e9368a1c8d9db5 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 29 May 2026 14:24:00 +0300 Subject: [PATCH 4/7] Simplifying delegation's block deletion logic --- compiler/rustc_ast_lowering/src/delegation.rs | 73 ++++-- compiler/rustc_ast_lowering/src/errors.rs | 7 + compiler/rustc_ast_lowering/src/lib.rs | 79 +------ compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_resolve/src/late.rs | 7 +- compiler/rustc_resolve/src/lib.rs | 2 - tests/ui/delegation/delegation-first-arg.rs | 4 +- .../ui/delegation/delegation-first-arg.stderr | 86 +++---- ...ems-before-lowering-ices.ice_155128.stderr | 26 ++- ...ems-before-lowering-ices.ice_155164.stderr | 2 +- ...ems-before-lowering-ices.ice_155202.stderr | 4 +- .../hir-crate-items-before-lowering-ices.rs | 1 + tests/ui/delegation/inner-attr.rs | 1 + tests/ui/delegation/inner-attr.stderr | 20 +- .../delegation/self-coercion-static-free.rs | 10 +- .../self-coercion-static-free.stderr | 112 ++++++--- .../target-expr-removal-defs-inside.rs | 35 +++ .../target-expr-removal-defs-inside.stderr | 218 ++++++++++++++++++ .../target-expression-removal-pass.rs | 39 ++++ .../zero-args-delegations-ice-154332.rs | 10 +- .../zero-args-delegations-ice-154332.stderr | 158 ++++++++++++- .../zero-args-delegations-ice-154427.rs | 3 +- .../zero-args-delegations-ice-154427.stderr | 19 +- 24 files changed, 715 insertions(+), 207 deletions(-) create mode 100644 tests/ui/delegation/target-expr-removal-defs-inside.rs create mode 100644 tests/ui/delegation/target-expr-removal-defs-inside.stderr create mode 100644 tests/ui/delegation/target-expression-removal-pass.rs diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 9dd0e0c314b95..84f33b089832b 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -57,8 +57,8 @@ use smallvec::SmallVec; use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults}; use crate::errors::{ - CycleInDelegationSignatureResolution, DelegationBlockSpecifiedWhenNoParams, - UnresolvedDelegationCallee, + CycleInDelegationSignatureResolution, DelegationAttemptedBlockWithDefsDeletion, + DelegationBlockSpecifiedWhenNoParams, UnresolvedDelegationCallee, }; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, @@ -131,7 +131,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); // Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356) - let sig_id = if let Some(delegation_info) = self.resolver.delegation_info(self.owner.def_id) + let sig_id = if let Some(resolution_node) = + self.resolver.delegation_info(self.owner.def_id).and_then(|i| i.resolution_node) { self.get_sig_id(delegation_info.resolution_id, span) } else { @@ -151,6 +152,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let (param_count, c_variadic) = param_count(self.tcx, sig_id); + if !self.check_block_soundness(delegation, sig_id, is_method, param_count) { + return self.generate_delegation_error(span, delegation); + } + let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); let (body_id, call_expr_id) = self.lower_delegation_body( @@ -188,6 +193,48 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn check_block_soundness( + &self, + delegation: &Delegation, + sig_id: DefId, + is_method: bool, + param_count: usize, + ) -> bool { + let mut result = true; + + // Report an error if user has explicitly specified delegation's block + // in a single delegation when reused function has no params. + if let Some(block) = delegation.body.as_ref() { + if param_count == 0 && matches!(delegation.source, DelegationSource::Single) { + self.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); + result = false; + } + + if !self.should_generate_block(delegation, sig_id, is_method) + && self + .resolver + .delegation_info(self.owner.def_id) + .is_some_and(|i| i.block_contains_defs) + { + self.dcx().emit_err(DelegationAttemptedBlockWithDefsDeletion { span: block.span }); + result = false; + } + } + + result + } + + fn should_generate_block( + &self, + delegation: &Delegation, + sig_id: DefId, + is_method: bool, + ) -> bool { + is_method + || matches!(self.tcx.def_kind(sig_id), DefKind::Fn) + || matches!(delegation.source, DelegationSource::Single) + } + fn add_attrs_if_needed(&mut self, span: Span, sig_id: DefId) { let new_attrs = self.create_new_attrs(ATTRS_ADDITIONS, span, sig_id, self.attrs.get(&PARENT_ID)); @@ -252,7 +299,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(delegation_info) = self.resolver.delegation_info(local_id) + && let Some(resolution_node) = + self.resolver.delegation_info(local_id).and_then(|i| i.resolution_node) { def_id = delegation_info.resolution_id; if visited.contains(&def_id) { @@ -413,12 +461,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut args: Vec> = Vec::with_capacity(param_count); let is_method = this.is_method(sig_id, span); - let is_single_delegation = matches!(delegation.source, DelegationSource::Single); - - // Should be in sync with conditions in `lower_delayed_owner::is_dead_code`. - let generate_block = is_method - || matches!(this.tcx.def_kind(sig_id), DefKind::Fn) - || is_single_delegation; for idx in 0..param_count { let (param, pat_node_id) = this.generate_param(is_method, idx, span); @@ -426,7 +468,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let arg = if let Some(block) = block && idx == 0 - && generate_block + && this.should_generate_block(delegation, sig_id, is_method) { let mut self_resolver = SelfResolver { ctxt: this, @@ -443,15 +485,6 @@ impl<'hir> LoweringContext<'_, 'hir> { args.push(arg); } - // Report an error if user has explicitly specified delegation's block - // in a single delegation when reused function has no params. - if param_count == 0 - && is_single_delegation - && let Some(block) = block - { - this.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); - } - let (final_expr, hir_id) = this.finalize_body_lowering(delegation, args, generics, span); diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index dc30d966e7593..392a5c5934ea1 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -542,3 +542,10 @@ pub(crate) struct DelegationBlockSpecifiedWhenNoParams { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("attempted to delete delegation's block that contains definitions inside")] +pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7ca9f14c79b4a..2a8b4ecd82ee6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -541,20 +541,14 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut delayed_ids: FxIndexSet = Default::default(); for def_id in ast_index.indices() { - // Check if this def is inside delegation (or it is delegation itself), if so, - // we should lower it in delayed mode, as we need to resolve delegation in order - // to understand whether to generate block as first arg or not. - let def_inside_delegation = resolver.defs_in_delegations_blocks.contains_key(&def_id); - let is_delegation = matches!( - ast_index[def_id], + match ast_index[def_id] { AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) - ); - - if def_inside_delegation || is_delegation { - delayed_ids.insert(def_id); - } else { - lowerer.lower_node(def_id); + | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { + delayed_ids.insert(def_id); + } + _ => { + lowerer.lower_node(def_id); + } } } @@ -584,63 +578,10 @@ pub fn lower_delayed_owner<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { owners: Owners::Map(&mut map), }; - fn is_dead_code<'tcx>( - tcx: TyCtxt<'tcx>, - resolver: &ResolverAstLowering<'tcx>, - ast_index: &IndexVec>, - def_id: LocalDefId, - ) -> bool { - // Try to find enclosing delegation (delegation in which block this `def_id` is placed). - let Some(&parent_del) = resolver.defs_in_delegations_blocks.get(&def_id) else { - return false; - }; - - // Check if the delegation itself is a dead-code (recursively up to topmost delegation). - if is_dead_code(tcx, resolver, ast_index, parent_del) { - return true; - } - - let from_glob_or_list = match &ast_index[parent_del] { - AstOwner::Item(Item { kind: ItemKind::Delegation(d), .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(d), .. }, _) => { - !matches!(d.source, DelegationSource::Single) - } - _ => unreachable!(), - }; - - let is_method_or_free = if let Some(info) = resolver.delegation_infos.get(&parent_del) - && let Some(sig_id) = resolver - .partial_res_map - .get(&info.resolution_node) - .and_then(|r| r.expect_full_res().opt_def_id()) - { - tcx.opt_associated_item(sig_id).is_some_and(|a| a.is_method()) - || matches!(tcx.def_kind(sig_id), DefKind::Fn) - } else { - // If delegation is unresolved for some reason we will generate an error delegation - // and some errors will be certainly emitted, so no delayed bugs should happen. - return false; - }; - - let (param_count, _) = delegation::param_count(tcx, parent_del.to_def_id()); + lowerer.lower_node(def_id); - // Should be in sync with conditions in `lower_delegation_body`. - (!is_method_or_free && from_glob_or_list) || param_count == 0 - } - - if !is_dead_code(tcx, resolver, &ast_index, def_id) { - lowerer.lower_node(def_id); - - for (child_def_id, owner) in map { - // We can encounter `NonOwner` which will result in a phantom being written - // to the map, however this `NonOwner` could be inserted from lowering of - // other owner (for example use trees), so we do not feed delayed_owner - // with Phantom as (1) it is Phantom by default, (2) we want to avoid - // consistency assert during query feeding. - if !matches!(owner, hir::MaybeOwner::Phantom) { - tcx.feed_delayed_owner(child_def_id, owner); - } - } + for (child_def_id, owner) in map { + tcx.feed_delayed_owner(child_def_id, owner); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index fdee5626e4548..4f47623282cb1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -258,12 +258,11 @@ pub struct ResolverAstLowering<'tcx> { // Information about delegations which is used when handling recursive delegations pub delegation_infos: LocalDefIdMap, - pub defs_in_delegations_blocks: LocalDefIdMap, pub disambiguators: LocalDefIdMap>, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct DelegationInfo { // `DefId` (either the resolution at delegation.id or item_id in case of a trait impl) for signature resolution, // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 @@ -271,6 +270,7 @@ pub struct DelegationInfo { /// Usually points to the final resolution, as most "chains" are just /// one step to a trait or an impl. pub resolution_id: DefId, + pub block_contains_defs: bool, } #[derive(Clone, Copy, Debug, StableHash)] diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index fc3b3ca845b8f..d241ba5281e88 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -79,7 +79,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { ); if let Some(last_delegation) = self.invocation_parent.last_delegation { - self.r.defs_in_delegations_blocks.insert(feed.def_id(), last_delegation); + self.r.delegation_infos.entry(last_delegation).or_default().block_contains_defs = true; } feed diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 58899ffd53ab9..d3955a487301c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRe use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_middle::middle::resolve_bound_vars::Set1; -use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility}; +use rustc_middle::ty::{AssocTag, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::errors::feature_err; @@ -3906,9 +3906,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .get(&resolution_id) .and_then(|r| r.expect_full_res().opt_def_id()); if let Some(resolution_id) = def_id { - self.r - .delegation_infos - .insert(self.r.current_owner.def_id, DelegationInfo { resolution_id }); + let info = self.r.delegation_infos.entry(self.r.current_owner.def_id).or_default(); + info.resolution_id = resolution_id; } else { self.r.tcx.dcx().span_delayed_bug( delegation.path.span, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 82cd27b449433..70d21d2dd51ee 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1513,7 +1513,6 @@ pub struct Resolver<'ra, 'tcx> { delegation_fn_sigs: LocalDefIdMap = Default::default(), delegation_infos: LocalDefIdMap = Default::default(), - defs_in_delegations_blocks: LocalDefIdMap = Default::default(), main_def: Option = None, trait_impls: FxIndexMap>, @@ -2008,7 +2007,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { trait_map: self.trait_map, lint_buffer: Steal::new(self.lint_buffer), delegation_infos: self.delegation_infos, - defs_in_delegations_blocks: self.defs_in_delegations_blocks, disambiguators, }; ResolverOutputs { global_ctxt, ast_lowering } diff --git a/tests/ui/delegation/delegation-first-arg.rs b/tests/ui/delegation/delegation-first-arg.rs index 9d7175945da8b..005a5910b69c0 100644 --- a/tests/ui/delegation/delegation-first-arg.rs +++ b/tests/ui/delegation/delegation-first-arg.rs @@ -26,6 +26,7 @@ impl F1 { // Error is reported as user has explicitly specified block when no params. reuse ::static_empty { self.0 } //~^ ERROR: delegation block is specified for function with no params + //~| ERROR: this function takes 0 arguments but 1 argument was supplied reuse ::static_one_param { self.0 } //~^ ERROR: `usize` is a primitive type and therefore doesn't have fields @@ -35,8 +36,6 @@ struct F2(S); impl F2 { // In list delegations silently remove first arg if it is not a method. reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } - //~^ ERROR: mismatched types - //~| ERROR: mismatched types } mod trait_to_reuse { @@ -74,6 +73,7 @@ mod to_reuse { // Error is reported as user has explicitly specified block when no params. reuse to_reuse::empty { self + 1 } //~^ ERROR: delegation block is specified for function with no params +//~| ERROR: this function takes 0 arguments but 1 argument was supplied reuse to_reuse::one_param { self + 1 } diff --git a/tests/ui/delegation/delegation-first-arg.stderr b/tests/ui/delegation/delegation-first-arg.stderr index b9c86e5ea8cd3..601fee336296a 100644 --- a/tests/ui/delegation/delegation-first-arg.stderr +++ b/tests/ui/delegation/delegation-first-arg.stderr @@ -5,7 +5,7 @@ LL | reuse ::static_empty { self.0 } | ^^^^^^^^^^ error: delegation block is specified for function with no params - --> $DIR/delegation-first-arg.rs:75:23 + --> $DIR/delegation-first-arg.rs:74:23 | LL | reuse to_reuse::empty { self + 1 } | ^^^^^^^^^^^^ @@ -49,48 +49,31 @@ LL | impl Trait for F3 { | ^^^^^^^^^^^^^^^^^ `F3` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0610]: `usize` is a primitive type and therefore doesn't have fields - --> $DIR/delegation-first-arg.rs:30:49 +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/delegation-first-arg.rs:27:25 | -LL | reuse ::static_one_param { self.0 } - | ^ - -error[E0308]: mismatched types - --> $DIR/delegation-first-arg.rs:37:83 +LL | reuse ::static_empty { self.0 } + | ^^^^^^^^^^^^ ------ unexpected argument | -LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } - | ----- arguments to this function are incorrect ^^^^^^ expected `&S`, found `S` +note: associated function defined here + --> $DIR/delegation-first-arg.rs:8:8 | -note: method defined here - --> $DIR/delegation-first-arg.rs:5:8 +LL | fn static_empty() {} + | ^^^^^^^^^^^^ +help: remove the extra argument | -LL | fn r#ref(&self) {} - | ^^^^^ ----- -help: consider borrowing here +LL - reuse ::static_empty { self.0 } +LL + reuse ::static_emptself.0 } | -LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { &self.0 } - | + -error[E0308]: mismatched types - --> $DIR/delegation-first-arg.rs:37:83 - | -LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } - | ------- ^^^^^^ expected `&mut S`, found `S` - | | - | arguments to this function are incorrect - | -note: method defined here - --> $DIR/delegation-first-arg.rs:6:8 - | -LL | fn mut_ref(&mut self) {} - | ^^^^^^^ --------- -help: consider mutably borrowing here +error[E0610]: `usize` is a primitive type and therefore doesn't have fields + --> $DIR/delegation-first-arg.rs:31:49 | -LL | reuse ::{value, r#ref, mut_ref, static_empty, static_one_param} { &mut self.0 } - | ++++ +LL | reuse ::static_one_param { self.0 } + | ^ error[E0308]: mismatched types - --> $DIR/delegation-first-arg.rs:55:85 + --> $DIR/delegation-first-arg.rs:54:85 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ----- arguments to this function are incorrect ^^^^^^ expected `&_`, found `S` @@ -98,7 +81,7 @@ LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_ = note: expected reference `&_` found struct `S` note: function defined here - --> $DIR/delegation-first-arg.rs:46:12 + --> $DIR/delegation-first-arg.rs:45:12 | LL | pub fn r#ref(_: &impl Trait) {} | ^^^^^ -------------- @@ -108,7 +91,7 @@ LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_ | + error[E0308]: mismatched types - --> $DIR/delegation-first-arg.rs:55:85 + --> $DIR/delegation-first-arg.rs:54:85 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ------- ^^^^^^ expected `&mut _`, found `S` @@ -118,7 +101,7 @@ LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_ = note: expected mutable reference `&mut _` found struct `S` note: function defined here - --> $DIR/delegation-first-arg.rs:47:12 + --> $DIR/delegation-first-arg.rs:46:12 | LL | pub fn mut_ref(_: &mut impl Trait) {} | ^^^^^^^ ------------------ @@ -128,30 +111,47 @@ LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_ | ++++ error[E0609]: no field `0` on type `impl Trait` - --> $DIR/delegation-first-arg.rs:62:90 + --> $DIR/delegation-first-arg.rs:61:90 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ^ unknown field error[E0609]: no field `0` on type `&impl Trait` - --> $DIR/delegation-first-arg.rs:62:90 + --> $DIR/delegation-first-arg.rs:61:90 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ^ unknown field error[E0609]: no field `0` on type `&mut impl Trait` - --> $DIR/delegation-first-arg.rs:62:90 + --> $DIR/delegation-first-arg.rs:61:90 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ^ unknown field error[E0610]: `usize` is a primitive type and therefore doesn't have fields - --> $DIR/delegation-first-arg.rs:62:90 + --> $DIR/delegation-first-arg.rs:61:90 | LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } | ^ +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/delegation-first-arg.rs:74:17 + | +LL | reuse to_reuse::empty { self + 1 } + | ^^^^^ -------- unexpected argument + | +note: function defined here + --> $DIR/delegation-first-arg.rs:69:12 + | +LL | pub fn empty() {} + | ^^^^^ +help: remove the extra argument + | +LL - reuse to_reuse::empty { self + 1 } +LL + reuse to_reuse::emptself + 1 } + | + error: aborting due to 13 previous errors -Some errors have detailed explanations: E0283, E0308, E0609, E0610. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0061, E0283, E0308, E0609, E0610. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr index ebfc526b62cf9..c9c59bb56aba9 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr @@ -3,10 +3,34 @@ error: delegation block is specified for function with no params | LL | reuse a as b { | __________________^ +LL | | LL | | fn foo() {}; LL | | foo LL | | } | |_____^ -error: aborting due to 1 previous error +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/hir-crate-items-before-lowering-ices.rs:36:11 + | +LL | reuse a as b { + | ___________^______- +LL | | +LL | | fn foo() {}; +LL | | foo +LL | | } + | |_____- unexpected argument of type `fn() {foo::<_>}` + | +note: function defined here + --> $DIR/hir-crate-items-before-lowering-ices.rs:34:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr index 8590881e67836..34d1a92ccd225 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr @@ -1,5 +1,5 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/hir-crate-items-before-lowering-ices.rs:46:13 + --> $DIR/hir-crate-items-before-lowering-ices.rs:47:13 | LL | / { LL | | diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155202.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155202.stderr index abe70cb82f3b3..28f045ca69442 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155202.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155202.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find value `async` in this scope - --> $DIR/hir-crate-items-before-lowering-ices.rs:65:13 + --> $DIR/hir-crate-items-before-lowering-ices.rs:66:13 | LL | async || {}; | ^^^^^ not found in this scope error[E0308]: mismatched types - --> $DIR/hir-crate-items-before-lowering-ices.rs:65:22 + --> $DIR/hir-crate-items-before-lowering-ices.rs:66:22 | LL | async || {}; | ^^ expected `bool`, found `()` diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs index 28523fb91582c..e8fba33bcab17 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -34,6 +34,7 @@ mod ice_155128 { fn a() {} reuse a as b { //[ice_155128]~ ERROR: delegation block is specified for function with no params + //[ice_155128]~^ ERROR: this function takes 0 arguments but 1 argument was supplied fn foo() {}; foo } diff --git a/tests/ui/delegation/inner-attr.rs b/tests/ui/delegation/inner-attr.rs index 452b3b3b73d5b..4a1e7cde5185f 100644 --- a/tests/ui/delegation/inner-attr.rs +++ b/tests/ui/delegation/inner-attr.rs @@ -4,5 +4,6 @@ fn a() {} reuse a as b { #![rustc_dummy] self } //~ ERROR an inner attribute is not permitted in this context //~^ ERROR: delegation block is specified for function with no params +//~| ERROR: this function takes 0 arguments but 1 argument was supplied fn main() {} diff --git a/tests/ui/delegation/inner-attr.stderr b/tests/ui/delegation/inner-attr.stderr index d6f8cc752902d..f47f92fb4e28b 100644 --- a/tests/ui/delegation/inner-attr.stderr +++ b/tests/ui/delegation/inner-attr.stderr @@ -15,5 +15,23 @@ error: delegation block is specified for function with no params LL | reuse a as b { #![rustc_dummy] self } | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/inner-attr.rs:5:7 + | +LL | reuse a as b { #![rustc_dummy] self } + | ^ ---- unexpected argument + | +note: function defined here + --> $DIR/inner-attr.rs:3:4 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { #![rustc_dummy] self } +LL + reuse self } + | + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/self-coercion-static-free.rs b/tests/ui/delegation/self-coercion-static-free.rs index f61d4247a1d94..2aeb5bd404991 100644 --- a/tests/ui/delegation/self-coercion-static-free.rs +++ b/tests/ui/delegation/self-coercion-static-free.rs @@ -20,10 +20,11 @@ struct S(F); impl Trait for S { reuse ::{static_value, static_mut_ref, static_ref} { - let _ = self; - S::static_self() //~^ ERROR: mismatched types //~| ERROR: mismatched types + //~| ERROR: mismatched types + let _ = self; + S::static_self() } } @@ -31,10 +32,11 @@ struct S1(Box>>>>>); impl Trait for S1 { reuse ::{static_value, static_mut_ref, static_ref} { - let _ = self; - S1::static_self() //~^ ERROR: mismatched types //~| ERROR: mismatched types + //~| ERROR: mismatched types + let _ = self; + S1::static_self() } } diff --git a/tests/ui/delegation/self-coercion-static-free.stderr b/tests/ui/delegation/self-coercion-static-free.stderr index 5f78272815aa5..b61ec58ee715c 100644 --- a/tests/ui/delegation/self-coercion-static-free.stderr +++ b/tests/ui/delegation/self-coercion-static-free.stderr @@ -1,49 +1,103 @@ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:24:9 + --> $DIR/self-coercion-static-free.rs:22:26 | -LL | S::static_self() - | ^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^ + | | + | expected `F`, found `S` + | arguments to this function are incorrect | -help: consider mutably borrowing here +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:10:8 | -LL | &mut S::static_self() - | ++++ +LL | fn static_value(_: Self) -> i32 { 1 } + | ^^^^^^^^^^^^ ------- error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:24:9 + --> $DIR/self-coercion-static-free.rs:22:40 | -LL | S::static_self() - | ^^^^^^^^^^^^^^^^ expected `&F`, found `F` +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^^^ + | | + | expected `&mut F`, found `&mut S` + | arguments to this function are incorrect | -help: consider borrowing here + = note: expected mutable reference `&mut F` + found mutable reference `&mut S` +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:11:8 | -LL | &S::static_self() - | + +LL | fn static_mut_ref(_: &mut Self) -> i32 { 2 } + | ^^^^^^^^^^^^^^ ------------ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:35:9 + --> $DIR/self-coercion-static-free.rs:22:56 | -LL | S1::static_self() - | ^^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^ + | | + | expected `&F`, found `&S` + | arguments to this function are incorrect | -help: consider mutably borrowing here + = note: expected reference `&F` + found reference `&S` +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:12:8 | -LL | &mut S1::static_self() - | ++++ +LL | fn static_ref(_: &Self) -> i32 { 3 } + | ^^^^^^^^^^ -------- error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:35:9 + --> $DIR/self-coercion-static-free.rs:34:26 | -LL | S1::static_self() - | ^^^^^^^^^^^^^^^^^ expected `&F`, found `F` +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^ + | | + | expected `F`, found `S1` + | arguments to this function are incorrect | -help: consider borrowing here +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:10:8 + | +LL | fn static_value(_: Self) -> i32 { 1 } + | ^^^^^^^^^^^^ ------- + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:34:40 + | +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^^^ + | | + | expected `&mut F`, found `&mut S1` + | arguments to this function are incorrect + | + = note: expected mutable reference `&mut F` + found mutable reference `&mut S1` +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:11:8 + | +LL | fn static_mut_ref(_: &mut Self) -> i32 { 2 } + | ^^^^^^^^^^^^^^ ------------ + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:34:56 + | +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^ + | | + | expected `&F`, found `&S1` + | arguments to this function are incorrect + | + = note: expected reference `&F` + found reference `&S1` +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:12:8 | -LL | &S1::static_self() - | + +LL | fn static_ref(_: &Self) -> i32 { 3 } + | ^^^^^^^^^^ -------- error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:48:43 + --> $DIR/self-coercion-static-free.rs:50:43 | LL | reuse to_reuse::{value, mut_ref, r#ref} { F } | ------- ^ expected `&mut _`, found `F` @@ -53,7 +107,7 @@ LL | reuse to_reuse::{value, mut_ref, r#ref} { F } = note: expected mutable reference `&mut _` found struct `F` note: function defined here - --> $DIR/self-coercion-static-free.rs:44:12 + --> $DIR/self-coercion-static-free.rs:46:12 | LL | pub fn mut_ref(_: &mut impl Trait) -> i32 { 2 } | ^^^^^^^ ------------------ @@ -63,7 +117,7 @@ LL | reuse to_reuse::{value, mut_ref, r#ref} { &mut F } | ++++ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:48:43 + --> $DIR/self-coercion-static-free.rs:50:43 | LL | reuse to_reuse::{value, mut_ref, r#ref} { F } | ----- ^ expected `&_`, found `F` @@ -73,7 +127,7 @@ LL | reuse to_reuse::{value, mut_ref, r#ref} { F } = note: expected reference `&_` found struct `F` note: function defined here - --> $DIR/self-coercion-static-free.rs:45:12 + --> $DIR/self-coercion-static-free.rs:47:12 | LL | pub fn r#ref(_: &impl Trait) -> i32 { 3 } | ^^^^^ -------------- @@ -82,6 +136,6 @@ help: consider borrowing here LL | reuse to_reuse::{value, mut_ref, r#ref} { &F } | + -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/target-expr-removal-defs-inside.rs b/tests/ui/delegation/target-expr-removal-defs-inside.rs new file mode 100644 index 0000000000000..f36030549defb --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-defs-inside.rs @@ -0,0 +1,35 @@ +#![feature(fn_delegation)] + +pub trait Trait: Sized { + fn static_self() -> F { F } + + fn static_value(_: Self) -> i32 { 1 } + fn static_mut_ref(_: &mut Self) -> i32 { 2 } + fn static_ref(_: &Self) -> i32 { 3 } +} + +struct F; +impl Trait for F {} + +struct S(F); + +reuse impl Trait for S { + //~^ ERROR: attempted to delete delegation's block that contains definitions inside + //~| ERROR: attempted to delete delegation's block that contains definitions inside + //~| ERROR: attempted to delete delegation's block that contains definitions inside + //~| ERROR: attempted to delete delegation's block that contains definitions inside + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: method `static_self` has an incompatible type for trait + //~| ERROR: method `static_value` has 0 parameters but the declaration in trait `Trait::static_value` has 1 + //~| ERROR: method `static_mut_ref` has 0 parameters but the declaration in trait `Trait::static_mut_ref` has 1 + //~| ERROR: method `static_ref` has 0 parameters but the declaration in trait `Trait::static_ref` has 1 + //~| ERROR: this function takes 0 arguments but 1 argument was supplied + struct Def {} + + self +} + +fn main() {} diff --git a/tests/ui/delegation/target-expr-removal-defs-inside.stderr b/tests/ui/delegation/target-expr-removal-defs-inside.stderr new file mode 100644 index 0000000000000..79bff70e1406a --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-defs-inside.stderr @@ -0,0 +1,218 @@ +error: attempted to delete delegation's block that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:16:24 + | +LL | reuse impl Trait for S { + | ________________________^ +... | +LL | | self +LL | | } + | |_^ + +error: attempted to delete delegation's block that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:16:24 + | +LL | reuse impl Trait for S { + | ________________________^ +... | +LL | | self +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's block that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:16:24 + | +LL | reuse impl Trait for S { + | ________________________^ +... | +LL | | self +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's block that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:16:24 + | +LL | reuse impl Trait for S { + | ________________________^ +... | +LL | | self +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0053]: method `static_self` has an incompatible type for trait + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | |_^ expected `F`, found `()` + | +note: type in trait + --> $DIR/target-expr-removal-defs-inside.rs:4:25 + | +LL | fn static_self() -> F { F } + | ^ + = note: expected signature `fn() -> F` + found signature `fn() -> ()` +help: change the output type to match the trait + | +LL - reuse impl Trait for S { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - struct Def {} +LL - +LL - self +LL - } +LL + -> F + | + +error[E0050]: method `static_value` has 0 parameters but the declaration in trait `Trait::static_value` has 1 + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | fn static_value(_: Self) -> i32 { 1 } + | ---- trait requires 1 parameter +... +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | |_^ expected 1 parameter, found 0 + +error[E0050]: method `static_mut_ref` has 0 parameters but the declaration in trait `Trait::static_mut_ref` has 1 + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | fn static_mut_ref(_: &mut Self) -> i32 { 2 } + | --------- trait requires 1 parameter +... +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | |_^ expected 1 parameter, found 0 + +error[E0050]: method `static_ref` has 0 parameters but the declaration in trait `Trait::static_ref` has 1 + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | fn static_ref(_: &Self) -> i32 { 3 } + | ----- trait requires 1 parameter +... +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | |_^ expected 1 parameter, found 0 + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | reuse impl Trait for S { + | _^ - + | |________________________| +... || +LL | || self +LL | || } + | ||_^ unexpected argument + | |_| + | + | +note: associated function defined here + --> $DIR/target-expr-removal-defs-inside.rs:4:8 + | +LL | fn static_self() -> F { F } + | ^^^^^^^^^^^ +help: remove the extra argument + | +LL - reuse impl Trait for S { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - struct Def {} +LL - +LL - self +LL - } +LL + reuse impl Trait for S } + | + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | | ^- help: consider using a semicolon here: `;` + | | | + | |_expected `()`, found `F` + | expected `()` because of default return type + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | | ^- help: consider using a semicolon here: `;` + | | | + | |_expected `()`, found `i32` + | expected `()` because of default return type + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | | ^- help: consider using a semicolon here: `;` + | | | + | |_expected `()`, found `i32` + | expected `()` because of default return type + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:16:1 + | +LL | / reuse impl Trait for S { +... | +LL | | self +LL | | } + | | ^- help: consider using a semicolon here: `;` + | | | + | |_expected `()`, found `i32` + | expected `()` because of default return type + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 13 previous errors + +Some errors have detailed explanations: E0050, E0053, E0061, E0308. +For more information about an error, try `rustc --explain E0050`. diff --git a/tests/ui/delegation/target-expression-removal-pass.rs b/tests/ui/delegation/target-expression-removal-pass.rs new file mode 100644 index 0000000000000..14bf5a66c6efe --- /dev/null +++ b/tests/ui/delegation/target-expression-removal-pass.rs @@ -0,0 +1,39 @@ +//@ run-pass + +#![feature(fn_delegation)] + +trait Trait: Sized { + fn by_value(self) -> i32 { 1 } + fn by_mut_ref(&mut self) -> i32 { 2 } + fn by_ref(&self) -> i32 { 3 } + + fn static_self() -> F { F } + + fn static_value(_: F) -> i32 { 1 } + fn static_mut_ref(_: &mut F) -> i32 { 2 } + fn static_ref(_: &F) -> i32 { 3 } +} + +#[derive(Default, Eq, PartialEq, Debug)] +struct F; +impl Trait for F {} + +struct S(F); + +impl Trait for S { + // Delegation's expression is removed from static functions. + reuse ::* { self.0 } +} + +fn main() { + let mut s = S(F); + assert_eq!(s.by_mut_ref(), 2); + assert_eq!(s.by_ref(), 3); + assert_eq!(s.by_value(), 1); + + assert_eq!(S::static_self(), F); + + assert_eq!(S::static_value(F), 1); + assert_eq!(S::static_mut_ref(&mut F), 2); + assert_eq!(S::static_ref(&F), 3); +} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.rs b/tests/ui/delegation/zero-args-delegations-ice-154332.rs index 10d8def4c8c76..133b6f93b40e6 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs @@ -4,6 +4,7 @@ mod test_ice { fn a() {} reuse a as b { //~ ERROR: delegation block is specified for function with no params + //~^ ERROR: this function takes 0 arguments but 1 argument was supplied let closure = || { fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} @@ -24,20 +25,25 @@ mod test_2 { reuse to_reuse::zero_args { self } //~^ ERROR: delegation block is specified for function with no params + //~| ERROR: this function takes 0 arguments but 1 argument was supplied + //~| ERROR: mismatched types } mod nested_delegations { fn a() {} reuse a as b { //~ ERROR: delegation block is specified for function with no params + //~^ ERROR: this function takes 0 arguments but 1 argument was supplied let closure = || { - reuse a as b { + reuse a as b { //~ ERROR: delegation block is specified for function with no params + //~^ ERROR: this function takes 0 arguments but 1 argument was supplied fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} reuse foo:: as bar; bar(&"".to_string(), &"".to_string()); - reuse a as b { + reuse a as b { //~ ERROR: delegation block is specified for function with no params + //~^ ERROR: this function takes 0 arguments but 1 argument was supplied reuse foo:: as bar; bar(&"".to_string(), &"".to_string()); } diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr index fd2f34eedabb7..3dd8f238f98ea 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr @@ -3,6 +3,7 @@ error: delegation block is specified for function with no params | LL | reuse a as b { | __________________^ +LL | | LL | | let closure = || { LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} ... | @@ -11,23 +12,172 @@ LL | | } | |_____^ error: delegation block is specified for function with no params - --> $DIR/zero-args-delegations-ice-154332.rs:25:31 + --> $DIR/zero-args-delegations-ice-154332.rs:26:31 | LL | reuse to_reuse::zero_args { self } | ^^^^^^^^ error: delegation block is specified for function with no params - --> $DIR/zero-args-delegations-ice-154332.rs:32:18 + --> $DIR/zero-args-delegations-ice-154332.rs:35:18 | LL | reuse a as b { | __________________^ +LL | | LL | | let closure = || { LL | | reuse a as b { -LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} ... | LL | | closure(); LL | | } | |_____^ -error: aborting due to 3 previous errors +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154332.rs:38:26 + | +LL | reuse a as b { + | __________________________^ +LL | | +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | } + | |_____________^ + +error: delegation block is specified for function with no params + --> $DIR/zero-args-delegations-ice-154332.rs:45:30 + | +LL | reuse a as b { + | ______________________________^ +LL | | +LL | | reuse foo:: as bar; +LL | | bar(&"".to_string(), &"".to_string()); +LL | | } + | |_________________^ + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:6:11 + | +LL | reuse a as b { + | ___________^______- +LL | | +LL | | let closure = || { +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | closure(); +LL | | } + | |_____- unexpected argument of type `()` + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:4:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:26:21 + | +LL | reuse to_reuse::zero_args { self } + | ^^^^^^^^^ ---- unexpected argument + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:21:16 + | +LL | pub fn zero_args() -> i32 { + | ^^^^^^^^^ +help: remove the extra argument + | +LL - reuse to_reuse::zero_args { self } +LL + reuse to_reuse::zero_argself } + | + +error[E0308]: mismatched types + --> $DIR/zero-args-delegations-ice-154332.rs:26:21 + | +LL | reuse to_reuse::zero_args { self } + | ^^^^^^^^^ expected `()`, found `i32` + | +help: consider using a semicolon here + | +LL | reuse to_reuse::zero_args; { self } + | + +help: try adding a return type + | +LL - reuse to_reuse::zero_args { self } +LL + reuse to_reuse:: -> i32 { self } + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:35:11 + | +LL | reuse a as b { + | ___________^______- +LL | | +LL | | let closure = || { +LL | | reuse a as b { +... | +LL | | closure(); +LL | | } + | |_____- unexpected argument of type `()` + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:33:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:38:19 + | +LL | reuse a as b { + | ___________________^______- +LL | | +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | } + | |_____________- unexpected argument of type `()` + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:33:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/zero-args-delegations-ice-154332.rs:45:23 + | +LL | reuse a as b { + | _______________________^______- +LL | | +LL | | reuse foo:: as bar; +LL | | bar(&"".to_string(), &"".to_string()); +LL | | } + | |_________________- unexpected argument of type `()` + | +note: function defined here + --> $DIR/zero-args-delegations-ice-154332.rs:33:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error: aborting due to 11 previous errors +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.rs b/tests/ui/delegation/zero-args-delegations-ice-154427.rs index b50066b057638..b0e00947a041f 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154427.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.rs @@ -12,8 +12,7 @@ mod ice_154427 { } impl Trait for S { reuse to_reuse::foo { self } - //~^ ERROR: this function takes 1 argument but 0 arguments were supplied - //~| ERROR: delegation block is specified for function with no params + //~^ ERROR: delegation block is specified for function with no params } fn main() {} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.stderr b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr index b73976fedda74..7aca43d1b3e64 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154427.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr @@ -4,22 +4,5 @@ error: delegation block is specified for function with no params LL | reuse to_reuse::foo { self } | ^^^^^^^^ -error[E0061]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/zero-args-delegations-ice-154427.rs:14:25 - | -LL | reuse to_reuse::foo { self } - | ^^^ argument #1 of type `F` is missing - | -note: function defined here - --> $DIR/zero-args-delegations-ice-154427.rs:11:16 - | -LL | pub fn foo(_: F) {} - | ^^^ ---- -help: provide the argument - | -LL | reuse to_reuse::foo(/* F */) { self } - | +++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0061`. From f75e1e6e3bb08821b5021c5cae3213b966d7be8f Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 29 May 2026 15:21:23 +0300 Subject: [PATCH 5/7] Cleanups --- compiler/rustc_ast_lowering/src/delegation.rs | 16 ++++++++-------- compiler/rustc_ast_lowering/src/lib.rs | 8 +++----- compiler/rustc_resolve/src/lib.rs | 1 - 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 84f33b089832b..42ae138d97563 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -50,7 +50,7 @@ use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, TyCtxt}; +use rustc_middle::ty::Asyncness; use rustc_span::symbol::kw; use rustc_span::{Ident, Span, Symbol}; use smallvec::SmallVec; @@ -108,12 +108,6 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ }, ]; -// Function parameter count, including C variadic `...` if present. -pub(crate) fn param_count(tcx: TyCtxt<'_>, def_id: DefId) -> (usize, bool /*c_variadic*/) { - let sig = tcx.fn_sig(def_id).skip_binder().skip_binder(); - (sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic()) -} - impl<'hir> LoweringContext<'_, 'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { @@ -150,7 +144,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let is_method = self.is_method(sig_id, span); - let (param_count, c_variadic) = param_count(self.tcx, sig_id); + let (param_count, c_variadic) = self.param_count(sig_id); if !self.check_block_soundness(delegation, sig_id, is_method, param_count) { return self.generate_delegation_error(span, delegation); @@ -321,6 +315,12 @@ impl<'hir> LoweringContext<'_, 'hir> { self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()) } + // Function parameter count, including C variadic `...` if present. + fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { + let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder(); + (sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic()) + } + fn lower_delegation_decl( &mut self, sig_id: DefId, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2a8b4ecd82ee6..c4af2f7feae2b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -541,14 +541,12 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut delayed_ids: FxIndexSet = Default::default(); for def_id in ast_index.indices() { - match ast_index[def_id] { + match &ast_index[def_id] { AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { delayed_ids.insert(def_id); } - _ => { - lowerer.lower_node(def_id); - } + _ => lowerer.lower_node(def_id), } } @@ -561,7 +559,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { } /// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. -pub fn lower_delayed_owner<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { +pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { let krate = tcx.hir_crate(()); let (resolver, krate) = &*krate.delayed_resolver.borrow(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 70d21d2dd51ee..8fb8c69aea166 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1510,7 +1510,6 @@ pub struct Resolver<'ra, 'tcx> { item_generics_num_lifetimes: FxHashMap = default::fx_hash_map(), /// Generic args to suggest for required params (e.g. `<'_>`, `<_, _>`), if any. item_required_generic_args_suggestions: FxHashMap = default::fx_hash_map(), - delegation_fn_sigs: LocalDefIdMap = Default::default(), delegation_infos: LocalDefIdMap = Default::default(), From eb949909ba38da6556607af444c752018df4bc47 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Tue, 2 Jun 2026 10:42:53 +0300 Subject: [PATCH 6/7] After-rebase fixes --- compiler/rustc_ast_lowering/src/delegation.rs | 12 ++++++------ compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_resolve/src/late.rs | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 42ae138d97563..69960d325ed01 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -125,10 +125,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); // Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356) - let sig_id = if let Some(resolution_node) = - self.resolver.delegation_info(self.owner.def_id).and_then(|i| i.resolution_node) + let sig_id = if let Some(resolution_id) = + self.resolver.delegation_info(self.owner.def_id).and_then(|i| i.resolution_id) { - self.get_sig_id(delegation_info.resolution_id, span) + self.get_sig_id(resolution_id, span) } else { self.dcx().span_delayed_bug( span, @@ -293,10 +293,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(resolution_node) = - self.resolver.delegation_info(local_id).and_then(|i| i.resolution_node) + && let Some(resolution_id) = + self.resolver.delegation_info(local_id).and_then(|i| i.resolution_id) { - def_id = delegation_info.resolution_id; + def_id = resolution_id; if visited.contains(&def_id) { // We encountered a cycle in the resolution, or delegation callee refers to non-existent // entity, in this case emit an error. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4f47623282cb1..a7cdafb20c1cb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -269,7 +269,7 @@ pub struct DelegationInfo { /// Refers to the next element in a delegation resolution chain. /// Usually points to the final resolution, as most "chains" are just /// one step to a trait or an impl. - pub resolution_id: DefId, + pub resolution_id: Option, pub block_contains_defs: bool, } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d3955a487301c..c2f03d61f8622 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3905,9 +3905,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .partial_res_map .get(&resolution_id) .and_then(|r| r.expect_full_res().opt_def_id()); + if let Some(resolution_id) = def_id { let info = self.r.delegation_infos.entry(self.r.current_owner.def_id).or_default(); - info.resolution_id = resolution_id; + info.resolution_id = Some(resolution_id); } else { self.r.tcx.dcx().span_delayed_bug( delegation.path.span, From a51d4b94790ef7f3f230658770c0614a7589263e Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 3 Jun 2026 11:38:07 +0300 Subject: [PATCH 7/7] Cleanups --- compiler/rustc_ast_lowering/src/delegation.rs | 34 +++++++++---------- compiler/rustc_ast_lowering/src/errors.rs | 4 +-- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 12 ++++--- tests/ui/delegation/delegation-first-arg.rs | 4 +-- .../ui/delegation/delegation-first-arg.stderr | 4 +-- ...ems-before-lowering-ices.ice_155128.stderr | 2 +- .../hir-crate-items-before-lowering-ices.rs | 2 +- tests/ui/delegation/inner-attr.rs | 2 +- tests/ui/delegation/inner-attr.stderr | 2 +- .../target-expr-removal-defs-inside.rs | 8 ++--- .../target-expr-removal-defs-inside.stderr | 8 ++--- .../zero-args-delegations-ice-154332.rs | 10 +++--- .../zero-args-delegations-ice-154332.stderr | 10 +++--- .../zero-args-delegations-ice-154427.rs | 2 +- .../zero-args-delegations-ice-154427.stderr | 2 +- 16 files changed, 56 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 69960d325ed01..d9764e5510b7c 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -194,28 +194,28 @@ impl<'hir> LoweringContext<'_, 'hir> { is_method: bool, param_count: usize, ) -> bool { - let mut result = true; + let Some(block) = delegation.body.as_ref() else { return true }; - // Report an error if user has explicitly specified delegation's block + // Report an error if user has explicitly specified delegation's target expression // in a single delegation when reused function has no params. - if let Some(block) = delegation.body.as_ref() { - if param_count == 0 && matches!(delegation.source, DelegationSource::Single) { - self.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); - result = false; - } + if param_count == 0 && matches!(delegation.source, DelegationSource::Single) { + self.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); + return false; + } - if !self.should_generate_block(delegation, sig_id, is_method) - && self - .resolver - .delegation_info(self.owner.def_id) - .is_some_and(|i| i.block_contains_defs) - { - self.dcx().emit_err(DelegationAttemptedBlockWithDefsDeletion { span: block.span }); - result = false; - } + // If there are definitions inside and we can't delete target expression, so report an error. + // FIXME(fn_delegation): support deletion of target expression with defs inside. + if !self.should_generate_block(delegation, sig_id, is_method) + && self + .resolver + .delegation_info(self.owner.def_id) + .is_some_and(|i| i.block_contains_defs) + { + self.dcx().emit_err(DelegationAttemptedBlockWithDefsDeletion { span: block.span }); + return false; } - result + true } fn should_generate_block( diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 392a5c5934ea1..2efb91a4e355b 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -537,14 +537,14 @@ pub(crate) struct CycleInDelegationSignatureResolution { } #[derive(Diagnostic)] -#[diag("delegation block is specified for function with no params")] +#[diag("delegation's target expression is specified for function with no params")] pub(crate) struct DelegationBlockSpecifiedWhenNoParams { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag("attempted to delete delegation's block that contains definitions inside")] +#[diag("attempted to delete delegation's target expression that contains definitions inside")] pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { #[primary_span] pub span: Span, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c4af2f7feae2b..4045f08c053ed 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -547,7 +547,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { delayed_ids.insert(def_id); } _ => lowerer.lower_node(def_id), - } + }; } // Don't hash unless necessary, because it's expensive. diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index d241ba5281e88..00a4f345b67ad 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -252,16 +252,20 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { fn visit_delegation(&mut self, node: &'a Delegation) { // Do not map defs in path (i.e., consts with blocks), consider only - // delegation's block which is its first argument. - visit::walk_path(self, &node.path); - node.qself.as_ref().inspect(|qself| visit::walk_qself(self, qself)); + // delegation's target expression which is its first argument. + self.visit_path(&node.path); + if let Some(qself) = node.qself.as_ref() { + self.visit_qself(qself); + } let orig_last_delegation = mem::replace( &mut self.invocation_parent.last_delegation, Some(self.invocation_parent.parent_def), ); - node.body.as_ref().inspect(|block| self.brg_visit_block(block)); + if let Some(block) = node.body.as_ref() { + self.visit_block(block); + } self.invocation_parent.last_delegation = orig_last_delegation; } diff --git a/tests/ui/delegation/delegation-first-arg.rs b/tests/ui/delegation/delegation-first-arg.rs index 005a5910b69c0..8686268f408e8 100644 --- a/tests/ui/delegation/delegation-first-arg.rs +++ b/tests/ui/delegation/delegation-first-arg.rs @@ -25,7 +25,7 @@ impl F1 { // Error is reported as user has explicitly specified block when no params. reuse ::static_empty { self.0 } - //~^ ERROR: delegation block is specified for function with no params + //~^ ERROR: delegation's target expression is specified for function with no params //~| ERROR: this function takes 0 arguments but 1 argument was supplied reuse ::static_one_param { self.0 } @@ -72,7 +72,7 @@ mod to_reuse { // Error is reported as user has explicitly specified block when no params. reuse to_reuse::empty { self + 1 } -//~^ ERROR: delegation block is specified for function with no params +//~^ ERROR: delegation's target expression is specified for function with no params //~| ERROR: this function takes 0 arguments but 1 argument was supplied reuse to_reuse::one_param { self + 1 } diff --git a/tests/ui/delegation/delegation-first-arg.stderr b/tests/ui/delegation/delegation-first-arg.stderr index 601fee336296a..f209dcad27345 100644 --- a/tests/ui/delegation/delegation-first-arg.stderr +++ b/tests/ui/delegation/delegation-first-arg.stderr @@ -1,10 +1,10 @@ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/delegation-first-arg.rs:27:38 | LL | reuse ::static_empty { self.0 } | ^^^^^^^^^^ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/delegation-first-arg.rs:74:23 | LL | reuse to_reuse::empty { self + 1 } diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr index c9c59bb56aba9..80ecb2ec0fca5 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155128.stderr @@ -1,4 +1,4 @@ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/hir-crate-items-before-lowering-ices.rs:36:18 | LL | reuse a as b { diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs index e8fba33bcab17..b9a7a73732cf3 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -33,7 +33,7 @@ mod ice_155127 { mod ice_155128 { fn a() {} - reuse a as b { //[ice_155128]~ ERROR: delegation block is specified for function with no params + reuse a as b { //[ice_155128]~ ERROR: delegation's target expression is specified for function with no params //[ice_155128]~^ ERROR: this function takes 0 arguments but 1 argument was supplied fn foo() {}; foo diff --git a/tests/ui/delegation/inner-attr.rs b/tests/ui/delegation/inner-attr.rs index 4a1e7cde5185f..03e9b865f9dd7 100644 --- a/tests/ui/delegation/inner-attr.rs +++ b/tests/ui/delegation/inner-attr.rs @@ -3,7 +3,7 @@ fn a() {} reuse a as b { #![rustc_dummy] self } //~ ERROR an inner attribute is not permitted in this context -//~^ ERROR: delegation block is specified for function with no params +//~^ ERROR: delegation's target expression is specified for function with no params //~| ERROR: this function takes 0 arguments but 1 argument was supplied fn main() {} diff --git a/tests/ui/delegation/inner-attr.stderr b/tests/ui/delegation/inner-attr.stderr index f47f92fb4e28b..7771a6b1b4416 100644 --- a/tests/ui/delegation/inner-attr.stderr +++ b/tests/ui/delegation/inner-attr.stderr @@ -9,7 +9,7 @@ LL | fn main() {} | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/inner-attr.rs:5:14 | LL | reuse a as b { #![rustc_dummy] self } diff --git a/tests/ui/delegation/target-expr-removal-defs-inside.rs b/tests/ui/delegation/target-expr-removal-defs-inside.rs index f36030549defb..bcd89dfcf836a 100644 --- a/tests/ui/delegation/target-expr-removal-defs-inside.rs +++ b/tests/ui/delegation/target-expr-removal-defs-inside.rs @@ -14,10 +14,10 @@ impl Trait for F {} struct S(F); reuse impl Trait for S { - //~^ ERROR: attempted to delete delegation's block that contains definitions inside - //~| ERROR: attempted to delete delegation's block that contains definitions inside - //~| ERROR: attempted to delete delegation's block that contains definitions inside - //~| ERROR: attempted to delete delegation's block that contains definitions inside + //~^ ERROR: attempted to delete delegation's target expression that contains definitions inside + //~| ERROR: attempted to delete delegation's target expression that contains definitions inside + //~| ERROR: attempted to delete delegation's target expression that contains definitions inside + //~| ERROR: attempted to delete delegation's target expression that contains definitions inside //~| ERROR: mismatched types //~| ERROR: mismatched types //~| ERROR: mismatched types diff --git a/tests/ui/delegation/target-expr-removal-defs-inside.stderr b/tests/ui/delegation/target-expr-removal-defs-inside.stderr index 79bff70e1406a..ac07c99d439d3 100644 --- a/tests/ui/delegation/target-expr-removal-defs-inside.stderr +++ b/tests/ui/delegation/target-expr-removal-defs-inside.stderr @@ -1,4 +1,4 @@ -error: attempted to delete delegation's block that contains definitions inside +error: attempted to delete delegation's target expression that contains definitions inside --> $DIR/target-expr-removal-defs-inside.rs:16:24 | LL | reuse impl Trait for S { @@ -8,7 +8,7 @@ LL | | self LL | | } | |_^ -error: attempted to delete delegation's block that contains definitions inside +error: attempted to delete delegation's target expression that contains definitions inside --> $DIR/target-expr-removal-defs-inside.rs:16:24 | LL | reuse impl Trait for S { @@ -20,7 +20,7 @@ LL | | } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: attempted to delete delegation's block that contains definitions inside +error: attempted to delete delegation's target expression that contains definitions inside --> $DIR/target-expr-removal-defs-inside.rs:16:24 | LL | reuse impl Trait for S { @@ -32,7 +32,7 @@ LL | | } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: attempted to delete delegation's block that contains definitions inside +error: attempted to delete delegation's target expression that contains definitions inside --> $DIR/target-expr-removal-defs-inside.rs:16:24 | LL | reuse impl Trait for S { diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.rs b/tests/ui/delegation/zero-args-delegations-ice-154332.rs index 133b6f93b40e6..2b412fd89dd07 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs @@ -3,7 +3,7 @@ mod test_ice { fn a() {} - reuse a as b { //~ ERROR: delegation block is specified for function with no params + reuse a as b { //~ ERROR: delegation's target expression is specified for function with no params //~^ ERROR: this function takes 0 arguments but 1 argument was supplied let closure = || { fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} @@ -24,7 +24,7 @@ mod test_2 { } reuse to_reuse::zero_args { self } - //~^ ERROR: delegation block is specified for function with no params + //~^ ERROR: delegation's target expression is specified for function with no params //~| ERROR: this function takes 0 arguments but 1 argument was supplied //~| ERROR: mismatched types } @@ -32,17 +32,17 @@ mod test_2 { mod nested_delegations { fn a() {} - reuse a as b { //~ ERROR: delegation block is specified for function with no params + reuse a as b { //~ ERROR: delegation's target expression is specified for function with no params //~^ ERROR: this function takes 0 arguments but 1 argument was supplied let closure = || { - reuse a as b { //~ ERROR: delegation block is specified for function with no params + reuse a as b { //~ ERROR: delegation's target expression is specified for function with no params //~^ ERROR: this function takes 0 arguments but 1 argument was supplied fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} reuse foo:: as bar; bar(&"".to_string(), &"".to_string()); - reuse a as b { //~ ERROR: delegation block is specified for function with no params + reuse a as b { //~ ERROR: delegation's target expression is specified for function with no params //~^ ERROR: this function takes 0 arguments but 1 argument was supplied reuse foo:: as bar; bar(&"".to_string(), &"".to_string()); diff --git a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr index 3dd8f238f98ea..b958e0120cf99 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr @@ -1,4 +1,4 @@ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154332.rs:6:18 | LL | reuse a as b { @@ -11,13 +11,13 @@ LL | | closure(); LL | | } | |_____^ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154332.rs:26:31 | LL | reuse to_reuse::zero_args { self } | ^^^^^^^^ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154332.rs:35:18 | LL | reuse a as b { @@ -30,7 +30,7 @@ LL | | closure(); LL | | } | |_____^ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154332.rs:38:26 | LL | reuse a as b { @@ -41,7 +41,7 @@ LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &' LL | | } | |_____________^ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154332.rs:45:30 | LL | reuse a as b { diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.rs b/tests/ui/delegation/zero-args-delegations-ice-154427.rs index b0e00947a041f..11c27c7720c06 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154427.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.rs @@ -12,7 +12,7 @@ mod ice_154427 { } impl Trait for S { reuse to_reuse::foo { self } - //~^ ERROR: delegation block is specified for function with no params + //~^ ERROR: delegation's target expression is specified for function with no params } fn main() {} diff --git a/tests/ui/delegation/zero-args-delegations-ice-154427.stderr b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr index 7aca43d1b3e64..03d5c62dfe7f6 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154427.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr @@ -1,4 +1,4 @@ -error: delegation block is specified for function with no params +error: delegation's target expression is specified for function with no params --> $DIR/zero-args-delegations-ice-154427.rs:14:29 | LL | reuse to_reuse::foo { self }