diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 682ba78cddc5f..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: 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 1e96d1d52f7eb..e5db9e1cb19a3 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -428,9 +428,9 @@ macro_rules! common_visitor_and_walkers { ConstItem, ConstItemRhsKind, Defaultness, - Delegation, DelegationMac, DelegationSuffixes, + DelegationSource, DelimArgs, DelimSpan, EnumDef, @@ -573,6 +573,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 8accaa8c3125c..b1d0a0888c62e 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -56,7 +56,10 @@ use rustc_span::{Ident, Span, Symbol}; use smallvec::SmallVec; use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults}; -use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee}; +use crate::errors::{ + CycleInDelegationSignatureResolution, DelegationAttemptedBlockWithDefsDeletion, + DelegationBlockSpecifiedWhenNoParams, UnresolvedDelegationCallee, +}; use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, ResolverAstLoweringExt, @@ -122,9 +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(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_node, span) + self.get_sig_id(resolution_node, span) } else { self.dcx().span_delayed_bug( span, @@ -142,11 +146,15 @@ impl<'hir> LoweringContext<'_, 'hir> { 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); + } + 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, @@ -179,6 +187,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)); @@ -253,9 +303,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(delegation_info) = self.resolver.delegation_info(local_id) + && let Some(resolution_node) = + self.resolver.delegation_info(local_id).and_then(|i| i.resolution_node) { - node_id = delegation_info.resolution_node; + node_id = resolution_node; if visited.contains(&node_id) { // We encountered a cycle in the resolution, or delegation callee refers to non-existent // entity, in this case emit an error. @@ -407,7 +458,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, @@ -419,12 +470,15 @@ 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); + 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 + && this.should_generate_block(delegation, sig_id, is_method) { let mut self_resolver = SelfResolver { ctxt: this, @@ -441,17 +495,6 @@ 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. - if param_count == 0 - && let Some(block) = block - { - args.push(this.lower_target_expr(&block)); - } - 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 a1c1d1e11d694..392a5c5934ea1 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -535,3 +535,17 @@ 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, +} + +#[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 a916ee1f143bd..20eac0ab1e79a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -561,7 +561,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_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 741c34e0304af..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, + source: if from_glob { + ast::DelegationSource::Glob + } else { + ast::DelegationSource::List + }, })), tokens: None, } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 74f9e75fb48c0..45a6906179209 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -251,11 +251,12 @@ pub struct ResolverAstLowering<'tcx> { pub disambiguators: LocalDefIdMap>, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct DelegationInfo { // NodeId (either 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 - pub resolution_node: ast::NodeId, + pub resolution_node: Option, + pub block_contains_defs: bool, } #[derive(Clone, Copy, Debug, StableHash)] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3f6429c6a60f0..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: 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 43443e0ac3052..6a42fb4925fff 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}; @@ -1462,7 +1462,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(d) if matches!(d.source, DelegationSource::Glob)) && 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..d241ba5281e88 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.delegation_infos.entry(last_delegation).or_default().block_contains_defs = true; + } + + 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/late.rs b/compiler/rustc_resolve/src/late.rs index fb8de90d28aca..bd2736fbd6698 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, TraitCandidate}; 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; @@ -3923,12 +3923,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_path(&delegation.path); }); - self.r.delegation_infos.insert( - self.r.current_owner.def_id, - DelegationInfo { - resolution_node: if is_in_trait_impl { item_id } else { delegation.id }, - }, - ); + let info = self.r.delegation_infos.entry(self.r.current_owner.def_id).or_default(); + let resolution_node = if is_in_trait_impl { item_id } else { delegation.id }; + + info.resolution_node = Some(resolution_node); let Some(body) = &delegation.body else { return }; self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f5f4c9e6e2580..7f16fdfb7c5f0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -189,6 +189,7 @@ struct InvocationParent { in_attr: bool, const_arg_context: ConstArgContext, owner: NodeId, + last_delegation: Option, } impl InvocationParent { @@ -198,6 +199,7 @@ impl InvocationParent { in_attr: false, const_arg_context: ConstArgContext::NonDirect, owner: CRATE_NODE_ID, + last_delegation: None, }; } diff --git a/tests/ui/delegation/delegation-first-arg.rs b/tests/ui/delegation/delegation-first-arg.rs new file mode 100644 index 0000000000000..005a5910b69c0 --- /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 + //~| 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 +} + +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 } +} + +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 +//~| ERROR: this function takes 0 arguments but 1 argument was supplied + +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..601fee336296a --- /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:74: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[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/delegation-first-arg.rs:27:25 + | +LL | reuse ::static_empty { self.0 } + | ^^^^^^^^^^^^ ------ unexpected argument + | +note: associated function defined here + --> $DIR/delegation-first-arg.rs:8:8 + | +LL | fn static_empty() {} + | ^^^^^^^^^^^^ +help: remove the extra argument + | +LL - reuse ::static_empty { self.0 } +LL + reuse ::static_emptself.0 } + | + +error[E0610]: `usize` is a primitive type and therefore doesn't have fields + --> $DIR/delegation-first-arg.rs:31:49 + | +LL | reuse ::static_one_param { self.0 } + | ^ + +error[E0308]: mismatched types + --> $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` + | + = note: expected reference `&_` + found struct `S` +note: function defined here + --> $DIR/delegation-first-arg.rs:45: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:54: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:46: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: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: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: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: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: 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 833b0869002e2..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 @@ -1,8 +1,20 @@ +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 | | +LL | | fn foo() {}; +LL | | foo +LL | | } + | |_____^ + 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 | | } @@ -19,6 +31,6 @@ LL - reuse a as b { LL + reuse { | -error: aborting due to 1 previous error +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 c223d5d4a5adc..e8fba33bcab17 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,8 @@ 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 + //[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 6bd2892095fc0..4a1e7cde5185f 100644 --- a/tests/ui/delegation/inner-attr.rs +++ b/tests/ui/delegation/inner-attr.rs @@ -3,6 +3,7 @@ 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 +//~| 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 307586ccef93d..f47f92fb4e28b 100644 --- a/tests/ui/delegation/inner-attr.stderr +++ b/tests/ui/delegation/inner-attr.stderr @@ -9,6 +9,12 @@ 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 + --> $DIR/inner-attr.rs:5:14 + | +LL | reuse a as b { #![rustc_dummy] self } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/inner-attr.rs:5:7 | @@ -26,6 +32,6 @@ LL - reuse a as b { #![rustc_dummy] self } LL + reuse self } | -error: aborting due to 2 previous errors +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 a9d7876db5e87..133b6f93b40e6 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.rs +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.rs @@ -3,7 +3,8 @@ 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 + //~^ 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) {} @@ -23,7 +24,34 @@ 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 + //~| 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 { //~ 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 { //~ 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()); + } + } + }; + + 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 517a01dac6f0e..3dd8f238f98ea 100644 --- a/tests/ui/delegation/zero-args-delegations-ice-154332.stderr +++ b/tests/ui/delegation/zero-args-delegations-ice-154332.stderr @@ -1,8 +1,63 @@ +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 | | +LL | | let closure = || { +LL | | fn foo<'a, 'b, T: Clone, const N: usize, U: Clone>(_t: &'a T, _u: &'b U) {} +... | +LL | | closure(); +LL | | } + | |_____^ + +error: delegation block 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 + --> $DIR/zero-args-delegations-ice-154332.rs:35:18 + | +LL | reuse a as b { + | __________________^ +LL | | +LL | | let closure = || { +LL | | reuse a as b { +... | +LL | | closure(); +LL | | } + | |_____^ + +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) {} ... | @@ -22,13 +77,13 @@ LL + reuse { | error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/zero-args-delegations-ice-154332.rs:25:21 + --> $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:20:16 + --> $DIR/zero-args-delegations-ice-154332.rs:21:16 | LL | pub fn zero_args() -> i32 { | ^^^^^^^^^ @@ -38,6 +93,91 @@ LL - reuse to_reuse::zero_args { self } LL + reuse to_reuse::zero_argself } | -error: aborting due to 2 previous errors +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 -For more information about this error, try `rustc --explain E0061`. +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 new file mode 100644 index 0000000000000..b0e00947a041f --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.rs @@ -0,0 +1,21 @@ +#![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: 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..7aca43d1b3e64 --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr @@ -0,0 +1,8 @@ +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: aborting due to 1 previous error +