diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6e036e59b2349..8a342acbfa913 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, PartialEq, Eq)] +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, } impl Delegation { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1e96d1d52f7eb..19255e55506f9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -431,6 +431,7 @@ macro_rules! common_visitor_and_walkers { Delegation, 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 a5cd643e3ca76..5af13c70ef693 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -37,24 +37,29 @@ //! also be emitted during HIR ty lowering. use std::iter; +use std::ops::ControlFlow; use ast::visit::Visitor; use hir::def::{DefKind, Res}; use hir::{BodyId, HirId}; use rustc_abi::ExternAbi; use rustc_ast as ast; +use rustc_ast::node_id::NodeMap; use rustc_ast::*; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, TyCtxt}; +use rustc_middle::ty::{Asyncness, PerOwnerResolverData, TyCtxt}; use rustc_span::symbol::kw; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; 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, index_crate, @@ -198,10 +203,14 @@ 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, param_count, &mut generics, span); + self.lower_delegation_body(delegation, sig_id, param_count, &mut generics, span); let decl = self.lower_delegation_decl( sig_id, @@ -227,6 +236,82 @@ impl<'hir> LoweringContext<'_, 'hir> { DelegationResults { body_id, sig, ident, generics } } + fn check_block_soundness( + &self, + delegation: &Delegation, + sig_id: DefId, + is_method: bool, + param_count: usize, + ) -> bool { + let Some(block) = delegation.body.as_ref() else { return true }; + let should_generate_block = self.should_generate_block(delegation, sig_id, is_method); + + // Report an error if user has explicitly specified delegation's target expression + // in a single delegation when reused function has no params. + if param_count == 0 && should_generate_block { + self.dcx().emit_err(DelegationBlockSpecifiedWhenNoParams { span: block.span }); + return false; + } + + struct DefinitionsFinder<'a> { + all_owners: &'a NodeMap>, + // `self.owner.node_id_to_def_id` + nested_def_ids: &'a NodeMap, + } + + impl<'a> ast::visit::Visitor<'a> for DefinitionsFinder<'a> { + type Result = ControlFlow<()>; + + fn visit_id(&mut self, id: NodeId) -> Self::Result { + /* + (from `tests\ui\delegation\target-expr-removal-defs-inside.rs`): + ```rust + reuse impl Trait for S1 { + some::path::<{ fn foo() {} }>::xd(); + fn foo() {} + self.0 + } + ``` + + Constant from unresolved path will be in `nested_owners`, + `fn foo() {}` will not be in `nested_owners` but will be in `owners`, + both have `LocalDefId`, so we check those two maps. + */ + match self.all_owners.contains_key(&id) || self.nested_def_ids.contains_key(&id) { + true => ControlFlow::Break(()), + false => ControlFlow::Continue(()), + } + } + } + + let mut collector = DefinitionsFinder { + all_owners: &self.resolver.owners, + nested_def_ids: &self.owner.node_id_to_def_id, + }; + + let contains_defs = collector.visit_block(block).is_break(); + + // 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 !should_generate_block && contains_defs { + self.dcx().emit_err(DelegationAttemptedBlockWithDefsDeletion { span: block.span }); + return false; + } + + true + } + + 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)); @@ -415,7 +500,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, @@ -428,6 +513,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut args: Vec> = Vec::with_capacity(param_count); let mut stmts: &[hir::Stmt<'hir>] = &[]; + 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); @@ -437,6 +524,7 @@ impl<'hir> LoweringContext<'_, 'hir> { 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, @@ -467,17 +555,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_block_expr(&block)); - } - let (final_expr, hir_id) = this.finalize_body_lowering(delegation, stmts, args, generics, span); diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index a1c1d1e11d694..2efb91a4e355b 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'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 target expression that contains definitions inside")] +pub(crate) struct DelegationAttemptedBlockWithDefsDeletion { + #[primary_span] + pub span: Span, +} 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_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index fbd8a3f611ec1..d6104c705bdd2 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 4fd98944909dc..1efc280e350f8 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) + } else if !matches!(&item.kind, AssocItemKind::Delegation(d) if d.source == DelegationSource::Glob) && ident.name != kw::Underscore { // Don't add underscore names, they cannot be looked up anyway. diff --git a/tests/ui/delegation/delegation-first-arg.rs b/tests/ui/delegation/delegation-first-arg.rs new file mode 100644 index 0000000000000..0721e6e8cef73 --- /dev/null +++ b/tests/ui/delegation/delegation-first-arg.rs @@ -0,0 +1,86 @@ +#![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'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 } + //~^ 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 + //~| ERROR: this function takes 0 arguments but 1 argument was supplied + //~| ERROR: delegation's target expression is specified for function with no params +} + +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'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 } + +reuse to_reuse::{empty as empty1, one_param as one_param1} { self + 1 } +//~^ ERROR: this function takes 0 arguments but 1 argument was supplied +//~| ERROR: delegation's target expression is specified for function with no params + +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..da1cf2f57d946 --- /dev/null +++ b/tests/ui/delegation/delegation-first-arg.stderr @@ -0,0 +1,203 @@ +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's target expression is specified for function with no params + --> $DIR/delegation-first-arg.rs:61:83 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^^^^^^^^^^ + +error: delegation's target expression is specified for function with no params + --> $DIR/delegation-first-arg.rs:76:23 + | +LL | reuse to_reuse::empty { self + 1 } + | ^^^^^^^^^^^^ + +error: delegation's target expression is specified for function with no params + --> $DIR/delegation-first-arg.rs:82:60 + | +LL | reuse to_reuse::{empty as empty1, one_param as one_param1} { 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_empt{ self.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[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/delegation-first-arg.rs:61:51 + | +LL | reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } + | ^^^^^^^^^^^^ ---------- unexpected argument + | +note: function defined here + --> $DIR/delegation-first-arg.rs:48:12 + | +LL | pub fn static_empty() {} + | ^^^^^^^^^^^^ +help: remove the extra argument + | +LL - reuse trait_to_reuse::{value, r#ref, mut_ref, static_empty, static_one_param} { self.0 } +LL + reuse trait_to_reuse::{value, r#ref, mut_ref, static_empt{ self.0 } + | + +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:76:17 + | +LL | reuse to_reuse::empty { self + 1 } + | ^^^^^ ------------ unexpected argument + | +note: function defined here + --> $DIR/delegation-first-arg.rs:71:12 + | +LL | pub fn empty() {} + | ^^^^^ +help: remove the extra argument + | +LL - reuse to_reuse::empty { self + 1 } +LL + reuse to_reuse::empt{ self + 1 } + | + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/delegation-first-arg.rs:82:18 + | +LL | reuse to_reuse::{empty as empty1, one_param as one_param1} { self + 1 } + | ^^^^^ ------------ unexpected argument + | +note: function defined here + --> $DIR/delegation-first-arg.rs:71:12 + | +LL | pub fn empty() {} + | ^^^^^ +help: remove the extra argument + | +LL - reuse to_reuse::{empty as empty1, one_param as one_param1} { self + 1 } +LL + reuse to_reuse::{empt{ self + 1 } + | + +error: aborting due to 17 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..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,8 +1,20 @@ +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 { + | __________________^ +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..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,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'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 6bd2892095fc0..03e9b865f9dd7 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'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 9f4b66818062e..95fd5a1f377ac 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's target expression 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 { #![rustc_dummy] 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 d77dcb1fbda58..b61ec58ee715c 100644 --- a/tests/ui/delegation/self-coercion-static-free.stderr +++ b/tests/ui/delegation/self-coercion-static-free.stderr @@ -1,81 +1,103 @@ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:24:9 + --> $DIR/self-coercion-static-free.rs:22:26 | LL | reuse ::{static_value, static_mut_ref, static_ref} { - | -------------- arguments to this function are incorrect -LL | let _ = self; -LL | S::static_self() - | ^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` + | ^^^^^^^^^^^^ + | | + | expected `F`, found `S` + | arguments to this function are incorrect | +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:22:40 + | +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^^^ + | | + | expected `&mut F`, found `&mut S` + | arguments to this function are incorrect + | + = 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 | fn static_mut_ref(_: &mut Self) -> i32 { 2 } | ^^^^^^^^^^^^^^ ------------ -help: consider mutably borrowing here - | -LL | &mut S::static_self() - | ++++ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:24:9 + --> $DIR/self-coercion-static-free.rs:22:56 | LL | reuse ::{static_value, static_mut_ref, static_ref} { - | ---------- arguments to this function are incorrect -LL | let _ = self; -LL | S::static_self() - | ^^^^^^^^^^^^^^^^ expected `&F`, found `F` + | ^^^^^^^^^^ + | | + | expected `&F`, found `&S` + | arguments to this function are incorrect | + = note: expected reference `&F` + found reference `&S` note: associated function defined here --> $DIR/self-coercion-static-free.rs:12:8 | LL | fn static_ref(_: &Self) -> i32 { 3 } | ^^^^^^^^^^ -------- -help: consider borrowing here + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:34:26 + | +LL | reuse ::{static_value, static_mut_ref, static_ref} { + | ^^^^^^^^^^^^ + | | + | expected `F`, found `S1` + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/self-coercion-static-free.rs:10:8 | -LL | &S::static_self() - | + +LL | fn static_value(_: Self) -> i32 { 1 } + | ^^^^^^^^^^^^ ------- error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:35:9 + --> $DIR/self-coercion-static-free.rs:34:40 | LL | reuse ::{static_value, static_mut_ref, static_ref} { - | -------------- arguments to this function are incorrect -LL | let _ = self; -LL | S1::static_self() - | ^^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` + | ^^^^^^^^^^^^^^ + | | + | 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 } | ^^^^^^^^^^^^^^ ------------ -help: consider mutably borrowing here - | -LL | &mut S1::static_self() - | ++++ error[E0308]: mismatched types - --> $DIR/self-coercion-static-free.rs:35:9 + --> $DIR/self-coercion-static-free.rs:34:56 | LL | reuse ::{static_value, static_mut_ref, static_ref} { - | ---------- arguments to this function are incorrect -LL | let _ = self; -LL | S1::static_self() - | ^^^^^^^^^^^^^^^^^ expected `&F`, found `F` + | ^^^^^^^^^^ + | | + | 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 | fn static_ref(_: &Self) -> i32 { 3 } | ^^^^^^^^^^ -------- -help: consider borrowing here - | -LL | &S1::static_self() - | + 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` @@ -85,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 } | ^^^^^^^ ------------------ @@ -95,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` @@ -105,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 } | ^^^^^ -------------- @@ -114,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..665c889003bf3 --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-defs-inside.rs @@ -0,0 +1,76 @@ +#![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 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 + //~| 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.0 +} + +struct S1(F); +reuse impl Trait for S1 { + //~^ 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 + //~| 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 + some::path::<{ fn foo() {} }>::xd(); + //~^ ERROR: cannot find module or crate `some` in this scope + //~| ERROR: cannot find module or crate `some` in this scope + //~| ERROR: cannot find module or crate `some` in this scope + //~| ERROR: cannot find module or crate `some` in this scope + self.0 +} + +struct S2(F); +reuse impl Trait for S2 { + //~^ 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 + //~| 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 + fn foo() {} + self.0 +} + +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..eb3540801adea --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-defs-inside.stderr @@ -0,0 +1,683 @@ +error[E0433]: cannot find module or crate `some` in this scope + --> $DIR/target-expr-removal-defs-inside.rs:49:5 + | +LL | some::path::<{ fn foo() {} }>::xd(); + | ^^^^ use of unresolved module or unlinked crate `some` + | + = help: you might be missing a crate named `some` + +error[E0433]: cannot find module or crate `some` in this scope + --> $DIR/target-expr-removal-defs-inside.rs:49:5 + | +LL | some::path::<{ fn foo() {} }>::xd(); + | ^^^^ use of unresolved module or unlinked crate `some` + | + = help: you might be missing a crate named `some` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0433]: cannot find module or crate `some` in this scope + --> $DIR/target-expr-removal-defs-inside.rs:49:5 + | +LL | some::path::<{ fn foo() {} }>::xd(); + | ^^^^ use of unresolved module or unlinked crate `some` + | + = help: you might be missing a crate named `some` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0433]: cannot find module or crate `some` in this scope + --> $DIR/target-expr-removal-defs-inside.rs:49:5 + | +LL | some::path::<{ fn foo() {} }>::xd(); + | ^^^^ use of unresolved module or unlinked crate `some` + | + = help: you might be missing a crate named `some` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +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 { + | ________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + +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 { + | ________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +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 { + | ________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +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 { + | ________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:35:25 + | +LL | reuse impl Trait for S1 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:35:25 + | +LL | reuse impl Trait for S1 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:35:25 + | +LL | reuse impl Trait for S1 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:35:25 + | +LL | reuse impl Trait for S1 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:58:25 + | +LL | reuse impl Trait for S2 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:58:25 + | +LL | reuse impl Trait for S2 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:58:25 + | +LL | reuse impl Trait for S2 { + | _________________________^ +... | +LL | | self.0 +LL | | } + | |_^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: attempted to delete delegation's target expression that contains definitions inside + --> $DIR/target-expr-removal-defs-inside.rs:58:25 + | +LL | reuse impl Trait for S2 { + | _________________________^ +... | +LL | | self.0 +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.0 +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 - self.0 +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.0 +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.0 +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.0 +LL | | } + | |_^ expected 1 parameter, found 0 + +error[E0053]: method `static_self` has an incompatible type for trait + --> $DIR/target-expr-removal-defs-inside.rs:35:1 + | +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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 S1 { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - some::path::<{ fn foo() {} }>::xd(); +LL - +LL - +LL - +LL - +LL - self.0 +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:35:1 + | +LL | fn static_value(_: Self) -> i32 { 1 } + | ---- trait requires 1 parameter +... +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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:35:1 + | +LL | fn static_mut_ref(_: &mut Self) -> i32 { 2 } + | --------- trait requires 1 parameter +... +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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:35:1 + | +LL | fn static_ref(_: &Self) -> i32 { 3 } + | ----- trait requires 1 parameter +... +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +LL | | } + | |_^ expected 1 parameter, found 0 + +error[E0053]: method `static_self` has an incompatible type for trait + --> $DIR/target-expr-removal-defs-inside.rs:58:1 + | +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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 S2 { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - fn foo() {} +LL - self.0 +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:58:1 + | +LL | fn static_value(_: Self) -> i32 { 1 } + | ---- trait requires 1 parameter +... +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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:58:1 + | +LL | fn static_mut_ref(_: &mut Self) -> i32 { 2 } + | --------- trait requires 1 parameter +... +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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:58:1 + | +LL | fn static_ref(_: &Self) -> i32 { 3 } + | ----- trait requires 1 parameter +... +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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.0 +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 - self.0 +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.0 +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.0 +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.0 +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.0 +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[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/target-expr-removal-defs-inside.rs:35:1 + | +LL | reuse impl Trait for S1 { + | _^ - + | |_________________________| +... || +LL | || self.0 +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 S1 { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - some::path::<{ fn foo() {} }>::xd(); +LL - +LL - +LL - +LL - +LL - self.0 +LL - } +LL + reuse impl Trait for S1 } + | + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:35:1 + | +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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:35:1 + | +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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:35:1 + | +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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:35:1 + | +LL | / reuse impl Trait for S1 { +... | +LL | | self.0 +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[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/target-expr-removal-defs-inside.rs:58:1 + | +LL | reuse impl Trait for S2 { + | _^ - + | |_________________________| +... || +LL | || self.0 +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 S2 { +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - +LL - fn foo() {} +LL - self.0 +LL - } +LL + reuse impl Trait for S2 } + | + +error[E0308]: mismatched types + --> $DIR/target-expr-removal-defs-inside.rs:58:1 + | +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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:58:1 + | +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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:58:1 + | +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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:58:1 + | +LL | / reuse impl Trait for S2 { +... | +LL | | self.0 +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 43 previous errors + +Some errors have detailed explanations: E0050, E0053, E0061, E0308, E0433. +For more information about an error, try `rustc --explain E0050`. diff --git a/tests/ui/delegation/target-expr-removal-free-to-free.rs b/tests/ui/delegation/target-expr-removal-free-to-free.rs new file mode 100644 index 0000000000000..02470c27b661f --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-free-to-free.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] + +mod to_reuse { + pub fn foo(x: usize) -> usize { x } + pub fn bar() -> () { () } +} + +reuse to_reuse::{foo, bar} { self + 1 } +//~^ ERROR: this function takes 0 arguments but 1 argument was supplied +//~| ERROR: delegation's target expression is specified for function with no params + +fn main() {} diff --git a/tests/ui/delegation/target-expr-removal-free-to-free.stderr b/tests/ui/delegation/target-expr-removal-free-to-free.stderr new file mode 100644 index 0000000000000..a0ccd6bdfef37 --- /dev/null +++ b/tests/ui/delegation/target-expr-removal-free-to-free.stderr @@ -0,0 +1,26 @@ +error: delegation's target expression is specified for function with no params + --> $DIR/target-expr-removal-free-to-free.rs:8:28 + | +LL | reuse to_reuse::{foo, bar} { self + 1 } + | ^^^^^^^^^^^^ + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/target-expr-removal-free-to-free.rs:8:23 + | +LL | reuse to_reuse::{foo, bar} { self + 1 } + | ^^^ ------------ unexpected argument + | +note: function defined here + --> $DIR/target-expr-removal-free-to-free.rs:5:12 + | +LL | pub fn bar() -> () { () } + | ^^^ +help: remove the extra argument + | +LL - reuse to_reuse::{foo, bar} { self + 1 } +LL + reuse to_reuse::{foo, ba{ self + 1 } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`. 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..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,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'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) {} @@ -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's target expression 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'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'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'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()); + } + } + }; + + 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 d2aab756c6d6e..915401219203c 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's target expression 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'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's target expression 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's target expression 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's target expression 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_arg{ self } | -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..11c27c7720c06 --- /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's target expression 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..03d5c62dfe7f6 --- /dev/null +++ b/tests/ui/delegation/zero-args-delegations-ice-154427.stderr @@ -0,0 +1,8 @@ +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 } + | ^^^^^^^^ + +error: aborting due to 1 previous error +