diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index df5ea7c3168ff..8accaa8c3125c 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -58,8 +58,8 @@ use smallvec::SmallVec; use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults}; use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee}; use crate::{ - AllowReturnTypeNotation, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, - ParamMode, ResolverAstLoweringExt, + AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, + ResolverAstLoweringExt, }; mod generics; @@ -144,7 +144,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method); - let body_id = self.lower_delegation_body( + let (body_id, call_expr_id) = self.lower_delegation_body( delegation, is_method, param_count, @@ -152,16 +152,23 @@ impl<'hir> LoweringContext<'_, 'hir> { span, ); - let decl = - self.lower_delegation_decl(sig_id, param_count, c_variadic, span, &generics); + let decl = self.lower_delegation_decl( + sig_id, + param_count, + c_variadic, + span, + &generics, + delegation.id, + call_expr_id, + ); let sig = self.lower_delegation_sig(sig_id, decl, span); let ident = self.lower_ident(delegation.ident); let generics = self.arena.alloc(hir::Generics { has_where_clause_predicates: false, - params: self.arena.alloc_from_iter(generics.all_params(span, self)), - predicates: self.arena.alloc_from_iter(generics.all_predicates(span, self)), + params: self.arena.alloc_from_iter(generics.all_params()), + predicates: self.arena.alloc_from_iter(generics.all_predicates()), span, where_clause_span: span, }); @@ -280,6 +287,8 @@ impl<'hir> LoweringContext<'_, 'hir> { c_variadic: bool, span: Span, generics: &GenericsGenerationResults<'hir>, + call_path_node_id: NodeId, + call_expr_id: HirId, ) -> &'hir hir::FnDecl<'hir> { // The last parameter in C variadic functions is skipped in the signature, // like during regular lowering. @@ -297,7 +306,9 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id: self.next_id(), kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig( sig_id, - hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationGenerics { + hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationInfo { + call_expr_id, + call_path_res: self.get_resolution_id(call_path_node_id), child_args_segment_id: generics.child.args_segment_id, parent_args_segment_id: generics.parent.args_segment_id, self_ty_id: generics.self_ty_id, @@ -400,10 +411,11 @@ impl<'hir> LoweringContext<'_, 'hir> { param_count: usize, generics: &mut GenericsGenerationResults<'hir>, span: Span, - ) -> BodyId { + ) -> (BodyId, HirId) { let block = delegation.body.as_deref(); + let mut call_expr_id = HirId::INVALID; - self.lower_body(|this| { + let block_id = self.lower_body(|this| { let mut parameters: Vec> = Vec::with_capacity(param_count); let mut args: Vec> = Vec::with_capacity(param_count); @@ -440,10 +452,17 @@ impl<'hir> LoweringContext<'_, 'hir> { args.push(this.lower_target_expr(&block)); } - let final_expr = this.finalize_body_lowering(delegation, args, generics, span); + let (final_expr, hir_id) = + this.finalize_body_lowering(delegation, args, generics, span); + + call_expr_id = hir_id; (this.arena.alloc_from_iter(parameters), final_expr) - }) + }); + + debug_assert_ne!(call_expr_id, HirId::INVALID); + + (block_id, call_expr_id) } // FIXME(fn_delegation): Alternatives for target expression lowering: @@ -459,108 +478,59 @@ impl<'hir> LoweringContext<'_, 'hir> { self.mk_expr(hir::ExprKind::Block(block, None), block.span) } - // Generates expression for the resulting body. If possible, `MethodCall` is used - // to allow autoref/autoderef for target expression. For example in: - // - // trait Trait : Sized { - // fn by_value(self) -> i32 { 1 } - // fn by_mut_ref(&mut self) -> i32 { 2 } - // fn by_ref(&self) -> i32 { 3 } - // } - // - // struct NewType(SomeType); - // impl Trait for NewType { - // reuse Trait::* { self.0 } - // } - // - // `self.0` will automatically coerce. fn finalize_body_lowering( &mut self, delegation: &Delegation, args: Vec>, generics: &mut GenericsGenerationResults<'hir>, span: Span, - ) -> hir::Expr<'hir> { - let args = self.arena.alloc_from_iter(args); - - let has_generic_args = - delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some()); - - let call = if self - .get_resolution_id(delegation.id) - .map(|def_id| self.is_method(def_id, span)) - .unwrap_or_default() - && delegation.qself.is_none() - && !has_generic_args - && !args.is_empty() - { - let ast_segment = delegation.path.segments.last().unwrap(); - let segment = self.lower_path_segment( - delegation.path.span, - ast_segment, - ParamMode::Optional, - GenericArgsMode::Err, - ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, - ); - - // FIXME(fn_delegation): proper support for parent generics propagation - // in method call scenario. - let segment = self.process_segment(span, &segment, &mut generics.child); - let segment = self.arena.alloc(segment); - - self.arena.alloc(hir::Expr { - hir_id: self.next_id(), - kind: hir::ExprKind::MethodCall(segment, &args[0], &args[1..], span), - span, - }) - } else { - let path = self.lower_qpath( - delegation.id, - &delegation.qself, - &delegation.path, - ParamMode::Optional, - AllowReturnTypeNotation::No, - ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, - ); - - let new_path = match path { - hir::QPath::Resolved(ty, path) => { - let mut new_path = path.clone(); - let len = new_path.segments.len(); - - new_path.segments = self.arena.alloc_from_iter( - new_path.segments.iter().enumerate().map(|(idx, segment)| { - if idx + 2 == len { - self.process_segment(span, segment, &mut generics.parent) - } else if idx + 1 == len { - self.process_segment(span, segment, &mut generics.child) - } else { - segment.clone() - } - }), - ); - - hir::QPath::Resolved(ty, self.arena.alloc(new_path)) - } - hir::QPath::TypeRelative(ty, segment) => { - let segment = self.process_segment(span, segment, &mut generics.child); - - hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) - } - }; + ) -> (hir::Expr<'hir>, HirId) { + let path = self.lower_qpath( + delegation.id, + &delegation.qself, + &delegation.path, + ParamMode::Optional, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); + + let new_path = match path { + hir::QPath::Resolved(ty, path) => { + let mut new_path = path.clone(); + let len = new_path.segments.len(); + + new_path.segments = self.arena.alloc_from_iter( + new_path.segments.iter().enumerate().map(|(idx, segment)| { + if idx + 2 == len { + self.process_segment(span, segment, &mut generics.parent) + } else if idx + 1 == len { + self.process_segment(span, segment, &mut generics.child) + } else { + segment.clone() + } + }), + ); - generics.self_ty_id = match new_path { - hir::QPath::Resolved(ty, _) => ty, - hir::QPath::TypeRelative(ty, _) => Some(ty), + hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } - .map(|ty| ty.hir_id); + hir::QPath::TypeRelative(ty, segment) => { + let segment = self.process_segment(span, segment, &mut generics.child); - let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span)); - self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span)) + hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) + } }; + generics.self_ty_id = match new_path { + hir::QPath::Resolved(ty, _) => ty, + hir::QPath::TypeRelative(ty, _) => Some(ty), + } + .map(|ty| ty.hir_id); + + let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span)); + let args = self.arena.alloc_from_iter(args); + let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span)); + let block = self.arena.alloc(hir::Block { stmts: &[], expr: Some(call), @@ -570,7 +540,7 @@ impl<'hir> LoweringContext<'_, 'hir> { targeted_by_break: false, }); - self.mk_expr(hir::ExprKind::Block(block, None), span) + (self.mk_expr(hir::ExprKind::Block(block, None), span), call.hir_id) } fn process_segment( @@ -581,8 +551,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::PathSegment<'hir> { let details = result.generics.args_propagation_details(); + // Always uplift generic params, because if they are not empty then they + // should be generated in delegation. + let generics = result.generics.into_hir_generics(self, span); let segment = if details.should_propagate { - let generics = result.generics.into_hir_generics(self, span); let args = generics.into_generic_args(self, span); // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index c2c3bd740e3cf..f8e3528750035 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -171,22 +171,9 @@ impl<'hir> GenericsGenerationResult<'hir> { } impl<'hir> GenericsGenerationResults<'hir> { - pub(super) fn all_params( - &mut self, - span: Span, - ctx: &mut LoweringContext<'_, 'hir>, - ) -> impl Iterator> { - // Now we always call `into_hir_generics` both on child and parent, - // however in future we would not do that, when scenarios like - // method call will be supported (if HIR generics were not obtained - // then it means that we did not propagated them, thus we do not need - // to generate params). - let mut create_params = |result: &mut GenericsGenerationResult<'hir>| { - result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().params - }; - - let parent = create_params(&mut self.parent); - let child = create_params(&mut self.child); + pub(super) fn all_params(&self) -> impl Iterator> { + let parent = self.parent.generics.hir_generics_or_empty().params; + let child = self.child.generics.hir_generics_or_empty().params; // Order generics, first we have parent and child lifetimes, // then parent and child types and consts. @@ -205,24 +192,14 @@ impl<'hir> GenericsGenerationResults<'hir> { /// and `generate_lifetime_predicate` functions) we need to add them to delegation generics. /// Those predicates will not affect resulting predicate inheritance and folding /// in `rustc_hir_analysis`, as we inherit all predicates from delegation signature. - pub(super) fn all_predicates( - &mut self, - span: Span, - ctx: &mut LoweringContext<'_, 'hir>, - ) -> impl Iterator> { - // Now we always call `into_hir_generics` both on child and parent, - // however in future we would not do that, when scenarios like - // method call will be supported (if HIR generics were not obtained - // then it means that we did not propagated them, thus we do not need - // to generate predicates). - let mut create_predicates = |result: &mut GenericsGenerationResult<'hir>| { - result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().predicates - }; - - let parent = create_predicates(&mut self.parent); - let child = create_predicates(&mut self.child); - - parent.into_iter().chain(child).copied() + pub(super) fn all_predicates(&self) -> impl Iterator> { + self.parent + .generics + .hir_generics_or_empty() + .predicates + .into_iter() + .chain(self.child.generics.hir_generics_or_empty().predicates) + .copied() } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0569c1b986d1a..59d1b4b5576ee 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3864,9 +3864,10 @@ pub enum OpaqueTyOrigin { }, } -// Ids of parent (or child) path segment that contains user-specified args #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] -pub struct DelegationGenerics { +pub struct DelegationInfo { + pub call_expr_id: HirId, + pub call_path_res: Option, pub parent_args_segment_id: Option, pub child_args_segment_id: Option, pub self_ty_id: Option, @@ -3876,8 +3877,8 @@ pub struct DelegationGenerics { #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] pub enum InferDelegationSig<'hir> { Input(usize), - // Place generics info here, as we always specify output type for delegations. - Output(&'hir DelegationGenerics), + // Place delegation info here, as we always specify output type for delegations. + Output(&'hir DelegationInfo), } #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] @@ -4164,7 +4165,7 @@ impl<'hir> FnDecl<'hir> { None } - pub fn opt_delegation_generics(&self) -> Option<&'hir DelegationGenerics> { + pub fn opt_delegation_info(&self) -> Option<&'hir DelegationInfo> { if let FnRetTy::Return(ty) = self.output && let TyKind::InferDelegation(InferDelegation::Sig(_, kind)) = ty.kind && let InferDelegationSig::Output(generics) = kind diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 2d6d5a5d81f9a..f67181a4655b9 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -7,7 +7,7 @@ use std::debug_assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{DelegationGenerics, HirId, PathSegment}; +use rustc_hir::{DelegationInfo, HirId, PathSegment}; use rustc_middle::ty::{ self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -71,13 +71,17 @@ enum SelfPositionKind { None, } -fn get_delegation_generics(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> &DelegationGenerics { +pub fn opt_get_delegation_info( + tcx: TyCtxt<'_>, + delegation_id: LocalDefId, +) -> Option<&DelegationInfo> { tcx.hir_node(tcx.local_def_id_to_hir_id(delegation_id)) .fn_sig() - .expect("processing delegation") - .decl - .opt_delegation_generics() - .expect("processing delegation") + .and_then(|sig| sig.decl.opt_delegation_info()) +} + +fn get_delegation_info(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> &DelegationInfo { + opt_get_delegation_info(tcx, delegation_id).expect("processing delegation") } fn create_self_position_kind( @@ -92,7 +96,7 @@ fn create_self_position_kind( | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero, (FnKind::Free, FnKind::AssocTrait) => { - let propagate_self_ty = get_delegation_generics(tcx, delegation_id).propagate_self_ty; + let propagate_self_ty = get_delegation_info(tcx, delegation_id).propagate_self_ty; SelfPositionKind::AfterLifetimes(propagate_self_ty) } @@ -278,7 +282,7 @@ fn get_parent_and_inheritance_kind<'tcx>( } fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) -> Ty<'_> { - get_delegation_generics(tcx, delegation_id) + get_delegation_info(tcx, delegation_id) .self_ty_id .map(|id| { let ctx = ItemCtxt::new(tcx, delegation_id); @@ -640,7 +644,7 @@ fn get_delegation_user_specified_args<'tcx>( tcx: TyCtxt<'tcx>, delegation_id: LocalDefId, ) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) { - let info = get_delegation_generics(tcx, delegation_id); + let info = get_delegation_info(tcx, delegation_id); let get_segment = |hir_id: HirId| -> Option<(&'tcx PathSegment<'tcx>, DefId)> { let segment = tcx.hir_node(hir_id).expect_path_segment(); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 9cadaef8f886b..1e9bc80749881 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -73,7 +73,7 @@ mod check_unused; mod coherence; mod collect; mod constrained_generic_params; -mod delegation; +pub mod delegation; pub mod errors; pub mod hir_ty_lowering; pub mod hir_wf_check; diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index e15c9fe661641..d51a0bf2c3ef4 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -7,15 +7,16 @@ use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, HirId, LangItem, find_attr}; use rustc_hir_analysis::autoderef::Autoderef; +use rustc_hir_analysis::delegation::opt_get_delegation_info; use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; +use rustc_middle::ty::{self, FnSig, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; -use rustc_span::{Span, sym}; +use rustc_span::{Ident, Span, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -27,6 +28,8 @@ use super::method::probe::ProbeScope; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; use crate::errors; use crate::method::TreatNotYetDefinedOpaques; +use crate::method::confirm::ConfirmContext; +use crate::method::probe::{IsSuggestion, Mode}; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific @@ -591,16 +594,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let fn_sig = self.normalize(call_expr.span, Unnormalized::new_wip(fn_sig)); - self.check_argument_types( - call_expr.span, - call_expr, - fn_sig.inputs(), - fn_sig.output(), - expected, - arg_exprs, - fn_sig.c_variadic(), - TupleArgumentsFlag::DontTupleArguments, - def_id, + self.check_argument_types_maybe_method_like( + &fn_sig, call_expr, arg_exprs, expected, def_id, ); if fn_sig.abi() == rustc_abi::ExternAbi::RustCall { @@ -620,6 +615,110 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output() } + /// Performs arguments check with an additional routine of adjusting the first argument, + /// so it corresponds to the first parameter of the function. We reuse adjustments + /// that are obtained from `probe_for_name`, where the first argument pretends to be + /// a receiver like in a method call. At this point this routine is used for delegations, + /// as from this moment we always generate a call (earlier method calls were generated), + /// so we can both propagate parent generics and get benefits from adjustments from method call. + fn check_argument_types_maybe_method_like( + &self, + fn_sig: &FnSig<'tcx>, + call_expr: &'tcx hir::Expr<'tcx>, + arg_exprs: &'tcx [hir::Expr<'tcx>], + expected: Expectation<'tcx>, + def_id: Option, + ) { + let do_check = || { + self.check_argument_types( + call_expr.span, + call_expr, + fn_sig.inputs(), + fn_sig.output(), + expected, + arg_exprs, + fn_sig.c_variadic(), + TupleArgumentsFlag::DontTupleArguments, + def_id, + ); + }; + + let Some(scope) = self.get_scope_for_method_call_adjustments(call_expr, arg_exprs) else { + return do_check(); + }; + + let first_expr = &arg_exprs[0]; + let first_arg_type = self.check_expr(first_expr); + + // Reuse method probing that is used during method call, as all this code pretends that + // we generated method call. + let pick = self.probe_for_name( + Mode::MethodCall, + Ident::dummy(), + None, + IsSuggestion(false), + first_arg_type, + call_expr.hir_id, + scope, + ); + + let Ok(ref pick) = pick else { return do_check() }; + + // Fool typechecker by placing an adjusted type of the first arg to avoid errors. + // We already wrote type of `first_expr` during `self.check_expr(first_expr)` above. + let first_arg_type = self + .typeck_results + .borrow_mut() + .node_types_mut() + .insert(first_expr.hir_id, pick.self_ty) + .expect("must be set"); + + do_check(); + + let mut results = self.typeck_results.borrow_mut(); + + // Remove any added adjustments for `first_expr` during `do_check` and replace them with ours. + let mut adjustments = results.adjustments_mut(); + let adjustments = adjustments.entry(first_expr.hir_id).or_default(); + + let mut ctx = ConfirmContext::new(self, first_expr.span, first_expr, first_expr); + *adjustments = ctx.create_ty_adjustments_from_pick(first_arg_type, pick).1; + + // Restore original first provided arg type. + results.node_types_mut().insert(first_expr.hir_id, first_arg_type); + } + + /// Gets scope for method-call like adjustments for the first argument of the call. + /// Now only delegations are processed this way. + fn get_scope_for_method_call_adjustments( + &self, + call_expr: &'tcx hir::Expr<'tcx>, + arg_exprs: &'tcx [hir::Expr<'tcx>], + ) -> Option { + // Check that we are inside delegation and processing its call. First, we check that + // the parent of call expr. is delegation and then make sure that it is compiler-generated + // by comparing their hir ids (otherwise we will encounter errors in nested delegations, + // see tests\ui\delegation\impl-reuse-pass.rs:237). + let parent_def = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id; + let Some(info) = opt_get_delegation_info(self.tcx, parent_def) else { return None }; + + if call_expr.hir_id != info.call_expr_id { + return None; + }; + + let Some(path_res_id) = info.call_path_res else { return None }; + + // Check that delegation has first provided arg and that the call path + // resolves to a trait method (inherent methods are not yet supported). + if arg_exprs.is_empty() + || !self.tcx.opt_associated_item(path_res_id).is_some_and(|i| i.is_method()) + { + return None; + } + + Some(ProbeScope::Single(path_res_id)) + } + /// Attempts to reinterpret `method(rcvr, args...)` as `rcvr.method(args...)` /// and suggesting the fix if the method probe is successful. fn suggest_call_as_method( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 415630dab38b3..d62ba9cf804eb 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::{Expr, ExprKind, FnRetTy, HirId, LangItem, Node, QPath, is_range_literal}; use rustc_hir_analysis::check::potentially_plural_count; +use rustc_hir_analysis::delegation::opt_get_delegation_info; use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, ResolvedStructPath}; use rustc_index::IndexVec; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TypeTrace}; @@ -329,7 +330,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let demand_compatible = |idx| { let formal_input_ty: Ty<'tcx> = formal_input_tys[idx]; let expected_input_ty: Ty<'tcx> = expected_input_tys[idx]; - let provided_arg = &provided_args[idx]; + let provided_arg: &hir::Expr<'tcx> = &provided_args[idx]; debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty); @@ -338,7 +339,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 1. Unify the provided argument with the expected type let expectation = Expectation::rvalue_hint(self, expected_input_ty); - let checked_ty = self.check_expr_with_expectation(provided_arg, expectation); + // If we are processing first arg of delegation then we could have adjusted it + // in `execute_delegation_aware_arguments_check`. + let checked_ty = opt_get_delegation_info(self.tcx, self.body_id) + .and_then(|_| self.typeck_results.borrow().node_type_opt(provided_arg.hir_id)) + .unwrap_or_else(|| self.check_expr_with_expectation(provided_arg, expectation)); // 2. Coerce to the most detailed type that could be coerced // to, which is `expected_ty` if `rvalue_hint` returns an diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 0c83c1948d6f2..4ef6de12f7623 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -34,7 +34,7 @@ use super::{MethodCallee, probe}; use crate::errors::{SupertraitItemShadowee, SupertraitItemShadower, SupertraitItemShadowing}; use crate::{FnCtxt, callee}; -struct ConfirmContext<'a, 'tcx> { +pub(crate) struct ConfirmContext<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, span: Span, self_expr: &'tcx hir::Expr<'tcx>, @@ -90,7 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { - fn new( + pub(crate) fn new( fcx: &'a FnCtxt<'a, 'tcx>, span: Span, self_expr: &'tcx hir::Expr<'tcx>, @@ -178,14 +178,32 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ) -> Ty<'tcx> { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various typeck results. + let (target, adjustments) = self.create_ty_adjustments_from_pick(unadjusted_self_ty, pick); + + // Write out the final adjustments. + if !self.skip_record_for_diagnostics { + self.apply_adjustments(self.self_expr, adjustments); + } + + target + } + + pub(crate) fn create_ty_adjustments_from_pick( + &mut self, + unadjusted_self_ty: Ty<'tcx>, + pick: &probe::Pick<'tcx>, + ) -> (Ty<'tcx>, Vec>) { let mut autoderef = self.autoderef(self.call_expr.span, unadjusted_self_ty); let Some((mut target, n)) = autoderef.nth(pick.autoderefs) else { - return Ty::new_error_with_message( + let error_ty = Ty::new_error_with_message( self.tcx, DUMMY_SP, format!("failed autoderef {}", pick.autoderefs), ); + + return (error_ty, vec![]); }; + assert_eq!(n, pick.autoderefs); let mut adjustments = self.adjust_steps(&autoderef); @@ -260,12 +278,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.register_predicates(autoderef.into_obligations()); - // Write out the final adjustments. - if !self.skip_record_for_diagnostics { - self.apply_adjustments(self.self_expr, adjustments); - } - - target + (target, adjustments) } /// Returns a set of generic parameters for the method *receiver* where all type and region diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 49126ff0e964c..2ebff26ff9822 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir-typeck/method-lookup.html -mod confirm; +pub(crate) mod confirm; mod prelude_edition_lints; pub(crate) mod probe; mod suggest; diff --git a/tests/pretty/delegation-inline-attribute.pp b/tests/pretty/delegation-inline-attribute.pp index 125ed1c298262..fc409aa636d5c 100644 --- a/tests/pretty/delegation-inline-attribute.pp +++ b/tests/pretty/delegation-inline-attribute.pp @@ -38,33 +38,34 @@ fn foo(self: _) -> _ { - { - // Check that #[inline(hint)] is added to foo0 reuse inside another reuse + Trait::foo( + // Check that #[inline(hint)] is added to foo0 reuse inside another reuse + + // Check that #[inline(hint)] is added when other attributes present in inner reuse + + // Check that #[inline(never)] is preserved in inner reuse + + // Check that #[inline(always)] is preserved in inner reuse + + // Check that #[inline(never)] is preserved when there are other attributes in inner reuse + { #[attr = Inline(Hint)] fn foo0(arg0: _) -> _ { to_reuse::foo(self + 1) } - - // Check that #[inline(hint)] is added when other attributes present in inner reuse #[attr = Cold] #[attr = MustUse] #[attr = Deprecated {deprecation: Deprecation {since: Unspecified}}] #[attr = Inline(Hint)] fn foo1(arg0: _) -> _ { to_reuse::foo(self / 2) } - - // Check that #[inline(never)] is preserved in inner reuse #[attr = Inline(Never)] fn foo2(arg0: _) -> _ { to_reuse::foo(self / 2) } - - // Check that #[inline(always)] is preserved in inner reuse #[attr = Inline(Always)] fn foo3(arg0: _) -> _ { to_reuse::foo(self / 2) } - - // Check that #[inline(never)] is preserved when there are other attributes in inner reuse #[attr = Cold] #[attr = MustUse] #[attr = Inline(Never)] #[attr = Deprecated {deprecation: Deprecation {since: Unspecified}}] fn foo4(arg0: _) -> _ { to_reuse::foo(self / 2) } - }.foo() + }) } // Check that #[inline(hint)] is added when there are other attributes present in trait reuse @@ -72,22 +73,22 @@ #[attr = MustUse] #[attr = Deprecated {deprecation: Deprecation {since: Unspecified}}] #[attr = Inline(Hint)] - fn foo1(self: _) -> _ { self.0.foo1() } + fn foo1(self: _) -> _ { Trait::foo1(self.0) } // Check that #[inline(never)] is preserved in trait reuse #[attr = Inline(Never)] - fn foo2(self: _) -> _ { self.0.foo2() } + fn foo2(self: _) -> _ { Trait::foo2(self.0) } // Check that #[inline(always)] is preserved in trait reuse #[attr = Inline(Always)] - fn foo3(self: _) -> _ { self.0.foo3() } + fn foo3(self: _) -> _ { Trait::foo3(self.0) } // Check that #[inline(never)] is preserved when there are other attributes in trait reuse #[attr = Cold] #[attr = MustUse] #[attr = Inline(Never)] #[attr = Deprecated {deprecation: Deprecation {since: Unspecified}}] - fn foo4(self: _) -> _ { self.0.foo4() } + fn foo4(self: _) -> _ { Trait::foo4(self.0) } } fn main() { } diff --git a/tests/pretty/delegation-self-rename.pp b/tests/pretty/delegation-self-rename.pp index 59a07315185c7..7f7afc403607b 100644 --- a/tests/pretty/delegation-self-rename.pp +++ b/tests/pretty/delegation-self-rename.pp @@ -19,7 +19,7 @@ #[attr = Inline(Hint)] fn foo<'a, Self, A, const B: _, const B2: _, T, U, impl FnOnce() -> usize>(self: _, arg1: _) -> _ where - 'a:'a { self.foo::(arg1) } + 'a:'a { Trait::<'a, A, B>::foo::(self, arg1) } #[attr = Inline(Hint)] fn bar usize>(self: _, arg1: _) -> _ { Trait::<'static, (), true>::foo::(self, arg1) } diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index ab0c6d66e9c51..9537e45f3b8f0 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr @@ -65,13 +65,20 @@ LL | impl Trait for Z { | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:53 + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:44 | LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `InvariantRef<'_, ()>` + | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&u8`, found `&InvariantRef<'_, ()>` + | | + | arguments to this function are incorrect | - = note: expected type `u8` - found struct `InvariantRef<'_, ()>` + = note: expected reference `&u8` + found reference `&InvariantRef<'_, ()>` +note: method defined here + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:13:8 + | +LL | fn foo(&self) -> u8 { 0 } + | ^^^ ----- error[E0277]: the trait bound `u8: Trait` is not satisfied --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:12 @@ -87,14 +94,20 @@ LL | impl Trait for Z { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:53 + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:44 | LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `InvariantRef<'_, ()>` + | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&u8`, found `&InvariantRef<'_, ()>` + | | + | arguments to this function are incorrect | - = note: expected type `u8` - found struct `InvariantRef<'_, ()>` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: expected reference `&u8` + found reference `&InvariantRef<'_, ()>` +note: method defined here + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:14:8 + | +LL | fn bar(&self) -> u8 { 1 } + | ^^^ ----- error[E0277]: the trait bound `u8: Trait` is not satisfied --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:12 @@ -110,14 +123,20 @@ LL | impl Trait for Z { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:53 + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:21:44 | LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW } } - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `InvariantRef<'_, ()>` + | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&u8`, found `&InvariantRef<'_, ()>` + | | + | arguments to this function are incorrect | - = note: expected type `u8` - found struct `InvariantRef<'_, ()>` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: expected reference `&u8` + found reference `&InvariantRef<'_, ()>` +note: method defined here + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:15:8 + | +LL | fn meh(&self) -> u8 { 2 } + | ^^^ ----- error: aborting due to 10 previous errors diff --git a/tests/ui/delegation/generics/generics-aux-pass.rs b/tests/ui/delegation/generics/generics-aux-pass.rs index 06f5c6d4d212e..f5d49c03a6137 100644 --- a/tests/ui/delegation/generics/generics-aux-pass.rs +++ b/tests/ui/delegation/generics/generics-aux-pass.rs @@ -16,20 +16,17 @@ impl generics::Trait<'static, i32, 1> for X {} impl X { reuse generics::foo as bar; - reuse generics::Trait::foo as trait_foo; reuse generics::foo::<'static, 'static, i32, i32, 1> as bar1; reuse generics::Trait::<'static, i32, 1>::foo::<'static, i32, false> as trait_foo1; } trait LocalTrait { - fn get() -> u8 { 123 } fn get_self(&self) -> u8 { 123 } reuse generics::foo as bar; reuse generics::foo::<'static, 'static, i32, i32, 1> as bar1; - reuse generics::Trait::foo as trait_foo { Self::get() } reuse generics::Trait::<'static, i32, 1>::foo::<'static, i32, false> as trait_foo1 { Self::get_self(&self) } @@ -50,13 +47,11 @@ fn main() { X::bar::(); X::bar::<'static, 'static, i32, i32, 1>(); X::bar1(); - x.trait_foo::<'static, 'static, i32, 1, String, true>(); x.trait_foo1(); ::bar::(); ::bar::<'static, 'static, i32, i32, 1>(); ::bar1(); - 1usize.trait_foo::<'static, 'static, i32, 1, String, true>(); 1usize.trait_foo1(); } diff --git a/tests/ui/delegation/generics/impl-to-trait-method.rs b/tests/ui/delegation/generics/impl-to-trait-method.rs index 102e905068e2a..88d6e4fdaabef 100644 --- a/tests/ui/delegation/generics/impl-to-trait-method.rs +++ b/tests/ui/delegation/generics/impl-to-trait-method.rs @@ -36,7 +36,6 @@ mod unconstrained_parameter { struct S(F); impl S { reuse Trait::foo { &self.0 } - //~^ ERROR type annotations needed } } diff --git a/tests/ui/delegation/generics/impl-to-trait-method.stderr b/tests/ui/delegation/generics/impl-to-trait-method.stderr index 114ebf48cca06..34259d49a1bd9 100644 --- a/tests/ui/delegation/generics/impl-to-trait-method.stderr +++ b/tests/ui/delegation/generics/impl-to-trait-method.stderr @@ -46,13 +46,6 @@ LL | fn foo(&self) LL | Self: Trait0, | ^^^^^^ required by this bound in `Trait1::foo` -error[E0282]: type annotations needed - --> $DIR/impl-to-trait-method.rs:38:22 - | -LL | reuse Trait::foo { &self.0 } - | ^^^ cannot infer type for type parameter `T` declared on the trait `Trait` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0282. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/self-coercion-errors.rs b/tests/ui/delegation/self-coercion-errors.rs new file mode 100644 index 0000000000000..6c8356bd7495b --- /dev/null +++ b/tests/ui/delegation/self-coercion-errors.rs @@ -0,0 +1,234 @@ +// Tests below represent situations when type of the first argument can not be adjusted +// to the type of first parameter (i.e., Rc -> &mut T). + +#![feature(fn_delegation)] + +use std::sync::Arc; +use std::pin::Pin; +use std::rc::Rc; + +trait Trait: Sized { + fn by_value(self) -> i32 { 1 } + fn by_mut_ref(&mut self) -> i32 { 2 } + fn by_ref(&self) -> i32 { 3 } + fn r#box(self: Box) -> i32 { 4 } + fn arc(self: Arc) -> i32 { 5 } + fn rc(self: Rc) -> i32 { 6 } + fn pin_box(self: Pin>) -> i32 { 7 } + fn pin_rc(self: Pin>) -> i32 { 8 } + fn pin_arc(self: Pin>) -> i32 { 9 } + fn box_box(self: Box>) -> i32 { 10 } +} + +struct F; +impl Trait for F {} + +struct S(F); + +fn foo() -> F { + F +} + +impl S { + reuse Trait::{by_value, by_mut_ref, by_ref} { + println!("123"); + let x = &self.0; + foo() + } +} + +struct S1(F); + +impl S1 { + reuse Trait::{by_value, by_mut_ref, by_ref} { + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: the trait bound `fn() -> F {foo}: Trait` is not satisfied + println!("123"); + let x = &self.0; + foo + } +} + +struct S2(F); + +impl S2 { + reuse Trait::{by_value, by_mut_ref, by_ref} { + println!("123"); + let x = &self.0; + let x = foo(); + + x + } +} + +struct S3(F); + +impl S3 { + reuse Trait::{by_value, by_mut_ref, by_ref} { + println!("123"); + let x = &self.0; + let x = foo(); + + &mut x + //~^ ERROR: cannot borrow `x` as mutable, as it is not declared as mutable + //~| ERROR: cannot borrow `x` as mutable, as it is not declared as mutable + //~| ERROR: cannot borrow `x` as mutable, as it is not declared as mutable + //~| ERROR: cannot move out of a mutable reference + } +} + +struct X(F); + +impl X { + reuse Trait::* { &mut self.0 } + //~^ ERROR: cannot borrow `self.0` as mutable, as it is behind a `&` reference + //~| ERROR: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + //~| ERROR: cannot move out of a mutable reference + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X1(F); + +impl X1 { + reuse Trait::* { &self.0 } + //~^ ERROR: cannot borrow data in a `&` reference as mutable + //~| ERROR: cannot move out of a shared reference + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X2(F); + +impl X2 { + reuse Trait::* { &&&&self.0 } + //~^ ERROR: cannot move out of a shared reference + //~| ERROR: cannot borrow data in a `&` reference as mutable + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X3(Box); + +impl X3 { + reuse Trait::* { self.0.as_ref() } + //~^ ERROR: cannot borrow data in a `&` reference as mutable + //~| ERROR: cannot move out of a shared reference + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X4(F); + +impl X4 { + reuse Trait::* { &mut &mut &mut self.0 } + //~^ ERROR: cannot move out of a mutable reference + //~| ERROR: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + //~| ERROR: cannot borrow `self.0` as mutable, as it is behind a `&` reference + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X5(F); + +impl X5 { + reuse Trait::* { &&mut self.0 } + //~^ ERROR: cannot borrow `self.0` as mutable, as it is behind a `&` reference + //~| ERROR: cannot borrow data in a `&` reference as mutable [E0596] + //~| ERROR: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + //~| ERROR: cannot move out of a shared reference + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X6(Box); + +impl X6 { + reuse Trait::* { self.0 } + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X7(Box>>); + +impl X7 { + reuse Trait::* { self.0 } + //~^ ERROR: cannot borrow data in an `Arc` as mutable + //~| ERROR: cannot move out of an `Arc` + //~| ERROR: cannot move out of an `Arc` + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct X8(Pin>); + +impl X8 { + reuse Trait::* { self.0 } + //~^ ERROR: cannot move out of dereference of `Pin>` + //~| ERROR: cannot borrow data in dereference of `Pin>` as mutable + //~| ERROR: cannot move out of dereference of `Pin>` + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct OtherStruct; +struct X9(OtherStruct); + +impl X9 { + reuse Trait::* { self.0 } + //~^ ERROR: the trait bound `OtherStruct: Trait` is not satisfied + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/delegation/self-coercion-errors.stderr b/tests/ui/delegation/self-coercion-errors.stderr new file mode 100644 index 0000000000000..89308b15d2d84 --- /dev/null +++ b/tests/ui/delegation/self-coercion-errors.stderr @@ -0,0 +1,1916 @@ +error[E0277]: the trait bound `fn() -> F {foo}: Trait` is not satisfied + --> $DIR/self-coercion-errors.rs:43:49 + | +LL | reuse Trait::{by_value, by_mut_ref, by_ref} { + | ___________________--------______________________^ + | | | + | | required by a bound introduced by this call +... | +LL | | foo + | | --- this tail expression is of type `fn() -> F {foo}` +LL | | } + | |_____^ the trait `Trait` is not implemented for fn item `fn() -> F {foo}` + | +help: use parentheses to call this function + | +LL | }() + | ++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:43:49 + | +LL | reuse Trait::{by_value, by_mut_ref, by_ref} { + | _____________________________----------__________^ + | | | + | | arguments to this function are incorrect +... | +LL | | foo +LL | | } + | |_____^ expected `&mut _`, found fn item + | + = note: expected mutable reference `&mut _` + found fn item `fn() -> F {foo}` +note: method defined here + --> $DIR/self-coercion-errors.rs:12:8 + | +LL | fn by_mut_ref(&mut self) -> i32 { 2 } + | ^^^^^^^^^^ --------- +help: consider mutably borrowing here + | +LL | &mut foo + | ++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:43:49 + | +LL | reuse Trait::{by_value, by_mut_ref, by_ref} { + | _________________________________________------__^ + | | | + | | arguments to this function are incorrect +... | +LL | | foo +LL | | } + | |_____^ expected `&_`, found fn item + | + = note: expected reference `&_` + found fn item `fn() -> F {foo}` +note: method defined here + --> $DIR/self-coercion-errors.rs:13:8 + | +LL | fn by_ref(&self) -> i32 { 3 } + | ^^^^^^ ----- +help: consider borrowing here + | +LL | &foo + | + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Box<_>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found mutable reference `&mut F` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: store this in the heap by calling `Box::new` + | +LL | reuse Trait::* { Box::new(&mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Arc<_>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&mut F` into `Arc<_>` + | +LL | reuse Trait::* { (&mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Rc<_>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&mut F` into `Rc<_>` + | +LL | reuse Trait::* { (&mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Pin>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(&mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Pin>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Pin>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ expected `Box>`, found `&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found mutable reference `&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Box<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found reference `&F` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: store this in the heap by calling `Box::new` + | +LL | reuse Trait::* { Box::new(&self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Arc<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&F` into `Arc<_>` + | +LL | reuse Trait::* { (&self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Rc<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&F` into `Rc<_>` + | +LL | reuse Trait::* { (&self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(&self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ expected `Box>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Box<_>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found reference `&&&&F` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: store this in the heap by calling `Box::new` + | +LL | reuse Trait::* { Box::new(&&&&self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Arc<_>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&&&&F` into `Arc<_>` + | +LL | reuse Trait::* { (&&&&self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Rc<_>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&&&&F` into `Rc<_>` + | +LL | reuse Trait::* { (&&&&self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Pin>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(&&&&self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Pin>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Pin>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ expected `Box>`, found `&&&&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found reference `&&&&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Box<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: try removing the method call + | +LL - reuse Trait::* { self.0.as_ref() } +LL + reuse Trait::* { self.0 } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Arc<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&F` into `Arc<_>` + | +LL | reuse Trait::* { self.0.as_ref().into() } + | +++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Rc<_>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&F` into `Rc<_>` + | +LL | reuse Trait::* { self.0.as_ref().into() } + | +++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(self.0.as_ref()) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Pin>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ expected `Box>`, found `&F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found reference `&F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Box<_>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found mutable reference `&mut &mut &mut F` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: store this in the heap by calling `Box::new` + | +LL | reuse Trait::* { Box::new(&mut &mut &mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Arc<_>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&mut &mut &mut F` into `Arc<_>` + | +LL | reuse Trait::* { (&mut &mut &mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Rc<_>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&mut &mut &mut F` into `Rc<_>` + | +LL | reuse Trait::* { (&mut &mut &mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Pin>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(&mut &mut &mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Pin>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Pin>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ expected `Box>`, found `&mut &mut &mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found mutable reference `&mut &mut &mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Box<_>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<_>` + found reference `&&mut F` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: store this in the heap by calling `Box::new` + | +LL | reuse Trait::* { Box::new(&&mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Arc<_>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: call `Into::into` on this expression to convert `&&mut F` into `Arc<_>` + | +LL | reuse Trait::* { (&&mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Rc<_>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: call `Into::into` on this expression to convert `&&mut F` into `Rc<_>` + | +LL | reuse Trait::* { (&&mut self.0).into() } + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Pin>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: you need to pin and box this expression + | +LL | reuse Trait::* { Box::pin(&&mut self.0) } + | +++++++++ + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Pin>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Pin>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ expected `Box>`, found `&&mut F` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box>` + found reference `&&mut F` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Arc<_>`, found `Box` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Rc<_>`, found `Box` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:178:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box>`, found `Box` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box>` with type `std::ptr::Unique>` but it is private; `0` from `X6` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:175:8 + | +LL | struct X6(Box); + | -- ------ this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box>` + found struct `Box` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Arc<_>`, found `Box>>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: consider unboxing the value + | +LL | reuse Trait::* { *self.0 } + | + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Rc<_>`, found `Box>>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box>>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box>>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Box>>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box>`, found `Box>>` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box>` with type `std::ptr::Unique>` but it is private; `0` from `X7` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:187:8 + | +LL | struct X7(Box>>); + | -- ---------------- this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box>` + found struct `Box>>` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box<_>`, found `Pin>` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box` with type `std::ptr::Unique` but it is private; `0` from `X8` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:202:8 + | +LL | struct X8(Pin>); + | -- ----------- this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box<_>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Arc<_>`, found `Pin>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Rc<_>`, found `Pin>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Pin>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `Pin>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box>`, found `Pin>` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box>` with type `std::ptr::Unique>` but it is private; `0` from `X8` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:202:8 + | +LL | struct X8(Pin>); + | -- ----------- this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box>` + found struct `Pin>` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0277]: the trait bound `OtherStruct: Trait` is not satisfied + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | +help: the trait `Trait` is not implemented for `OtherStruct` + --> $DIR/self-coercion-errors.rs:217:1 + | +LL | struct OtherStruct; + | ^^^^^^^^^^^^^^^^^^ +help: the trait `Trait` is implemented for `F` + --> $DIR/self-coercion-errors.rs:24:1 + | +LL | impl Trait for F {} + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `&mut _`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected mutable reference `&mut _` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:12:8 + | +LL | fn by_mut_ref(&mut self) -> i32 { 2 } + | ^^^^^^^^^^ --------- +help: consider mutably borrowing here + | +LL | reuse Trait::* { &mut self.0 } + | ++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `&_`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected reference `&_` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:13:8 + | +LL | fn by_ref(&self) -> i32 { 3 } + | ^^^^^^ ----- +help: consider borrowing here + | +LL | reuse Trait::* { &self.0 } + | + + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box<_>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box` with type `std::ptr::Unique` but it is private; `0` from `X9` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:218:8 + | +LL | struct X9(OtherStruct); + | -- ----------- this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box<_>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:14:8 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Arc<_>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected struct `Arc<_>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:15:8 + | +LL | fn arc(self: Arc) -> i32 { 5 } + | ^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Rc<_>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected struct `Rc<_>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:16:8 + | +LL | fn rc(self: Rc) -> i32 { 6 } + | ^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:17:8 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:18:8 + | +LL | fn pin_rc(self: Pin>) -> i32 { 8 } + | ^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Pin>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:19:8 + | +LL | fn pin_arc(self: Pin>) -> i32 { 9 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0308]: mismatched types + --> $DIR/self-coercion-errors.rs:221:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ expected `Box>`, found `OtherStruct` + | | + | arguments to this function are incorrect + | +note: there is a field `0` on `Box>` with type `std::ptr::Unique>` but it is private; `0` from `X9` was accessed through auto-deref instead + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: in this struct + ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: if this field wasn't private, it would be accessible + | + ::: $DIR/self-coercion-errors.rs:218:8 + | +LL | struct X9(OtherStruct); + | -- ----------- this is the field that was accessed + | | + | this struct is accessible through auto-deref + = note: expected struct `Box>` + found struct `OtherStruct` +note: method defined here + --> $DIR/self-coercion-errors.rs:20:8 + | +LL | fn box_box(self: Box>) -> i32 { 10 } + | ^^^^^^^ ---- +help: consider removing the tuple struct field `0` + | +LL - reuse Trait::* { self.0 } +LL + reuse Trait::* { self } + | + +error[E0507]: cannot move out of a mutable reference + --> $DIR/self-coercion-errors.rs:73:9 + | +LL | reuse Trait::{by_value, by_mut_ref, by_ref} { + | -------- value moved due to this method call +... +LL | &mut x + | ^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | &mut x + | ------ you could clone this value + +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> $DIR/self-coercion-errors.rs:73:9 + | +LL | &mut x + | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = foo(); + | +++ + +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> $DIR/self-coercion-errors.rs:73:9 + | +LL | &mut x + | ^^^^^^ cannot borrow as mutable + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider changing this to be mutable + | +LL | let mut x = foo(); + | +++ + +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> $DIR/self-coercion-errors.rs:73:9 + | +LL | &mut x + | ^^^^^^ cannot borrow as mutable + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider changing this to be mutable + | +LL | let mut x = foo(); + | +++ + +error[E0507]: cannot move out of a mutable reference + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | - ^^^^^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { &mut self.0 } + | ----------- you could clone this value + +error[E0596]: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | ^^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | reuse Trait::mut * { &mut self.0 } + | +++ + +error[E0596]: cannot borrow `self.0` as mutable, as it is behind a `&` reference + --> $DIR/self-coercion-errors.rs:84:22 + | +LL | reuse Trait::* { &mut self.0 } + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable + | +help: consider changing this to be a mutable reference + | +LL - reuse Trait::* { &mut self.0 } +LL + reuse Trait::&mut self { &mut self.0 } + | + +error[E0507]: cannot move out of a shared reference + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | - ^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { &self.0 } + | ------- you could clone this value + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/self-coercion-errors.rs:100:22 + | +LL | reuse Trait::* { &self.0 } + | ^^^^^^^ cannot borrow as mutable + +error[E0507]: cannot move out of a shared reference + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | - ^^^^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { &&&&self.0 } + | ---------- you could clone this value + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/self-coercion-errors.rs:115:22 + | +LL | reuse Trait::* { &&&&self.0 } + | ^^^^^^^^^^ cannot borrow as mutable + +error[E0507]: cannot move out of a shared reference + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | - ^^^^^^^^^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { self.0.as_ref() } + | --------------- you could clone this value + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/self-coercion-errors.rs:130:22 + | +LL | reuse Trait::* { self.0.as_ref() } + | ^^^^^^^^^^^^^^^ cannot borrow as mutable + +error[E0507]: cannot move out of a mutable reference + --> $DIR/self-coercion-errors.rs:145:22 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | - ^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { &mut &mut &mut self.0 } + | --------------------- you could clone this value + +error[E0596]: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + --> $DIR/self-coercion-errors.rs:145:32 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | ^^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | reuse Trait::mut * { &mut &mut &mut self.0 } + | +++ + +error[E0596]: cannot borrow `self.0` as mutable, as it is behind a `&` reference + --> $DIR/self-coercion-errors.rs:145:32 + | +LL | reuse Trait::* { &mut &mut &mut self.0 } + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable + | +help: consider changing this to be a mutable reference + | +LL - reuse Trait::* { &mut &mut &mut self.0 } +LL + reuse Trait::&mut self { &mut &mut &mut self.0 } + | + +error[E0507]: cannot move out of a shared reference + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | - ^^^^^^^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { &&mut self.0 } + | ------------ you could clone this value + +error[E0596]: cannot borrow `self.0` as mutable, as `self` is not declared as mutable + --> $DIR/self-coercion-errors.rs:161:23 + | +LL | reuse Trait::* { &&mut self.0 } + | ^^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | reuse Trait::mut * { &&mut self.0 } + | +++ + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/self-coercion-errors.rs:161:22 + | +LL | reuse Trait::* { &&mut self.0 } + | ^^^^^^^^^^^^ cannot borrow as mutable + +error[E0596]: cannot borrow `self.0` as mutable, as it is behind a `&` reference + --> $DIR/self-coercion-errors.rs:161:23 + | +LL | reuse Trait::* { &&mut self.0 } + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable + | +help: consider changing this to be a mutable reference + | +LL - reuse Trait::* { &&mut self.0 } +LL + reuse Trait::&mut self { &&mut self.0 } + | + +error[E0507]: cannot move out of an `Arc` + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { self.0 } + | ------ you could clone this value + +error[E0596]: cannot borrow data in an `Arc` as mutable + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | ^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc>` + +error[E0507]: cannot move out of an `Arc` + --> $DIR/self-coercion-errors.rs:190:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ move occurs because value has type `Box`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::r#box` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:14:14 + | +LL | fn r#box(self: Box) -> i32 { 4 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { self.0 } + | ------ you could clone this value +help: you could `clone` the value and consume it, if the `F: Clone` trait bound could be satisfied + | +LL | reuse Trait::* { as Clone>::clone(&self.0) } + | ++++++++++++++++++++++++++ + +help: consider annotating `F` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct F; + | + +error[E0507]: cannot move out of dereference of `Pin>` + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ move occurs because value has type `F`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::by_value` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:11:17 + | +LL | fn by_value(self) -> i32 { 1 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { self.0 } + | ------ you could clone this value + +error[E0596]: cannot borrow data in dereference of `Pin>` as mutable + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | ^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin>` + +error[E0507]: cannot move out of dereference of `Pin>` + --> $DIR/self-coercion-errors.rs:205:22 + | +LL | reuse Trait::* { self.0 } + | - ^^^^^^ move occurs because value has type `Pin>`, which does not implement the `Copy` trait + | | + | value moved due to this method call + | +note: `Trait::pin_box` takes ownership of the receiver `self`, which moves value + --> $DIR/self-coercion-errors.rs:17:16 + | +LL | fn pin_box(self: Pin>) -> i32 { 7 } + | ^^^^ +note: if `F` implemented `Clone`, you could clone the value + --> $DIR/self-coercion-errors.rs:23:1 + | +LL | struct F; + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | reuse Trait::* { self.0 } + | ------ you could clone this value +help: you could `clone` the value and consume it, if the `F: Clone` trait bound could be satisfied + | +LL | reuse Trait::* { > as Clone>::clone(&self.0) } + | +++++++++++++++++++++++++++++++ + +help: consider annotating `F` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct F; + | + +error: aborting due to 99 previous errors + +Some errors have detailed explanations: E0277, E0308, E0507, E0596. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/self-coercion-static-free.rs b/tests/ui/delegation/self-coercion-static-free.rs new file mode 100644 index 0000000000000..f61d4247a1d94 --- /dev/null +++ b/tests/ui/delegation/self-coercion-static-free.rs @@ -0,0 +1,52 @@ +// Test that we do not adjust first argument type to first parameter type +// in delegations to static associated functions (we only do it for methods). +// Also test that we do not adjust first arg. type in delegations to free function. + +#![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 } +} + +#[derive(Default)] +struct F; +impl Trait for F {} + +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 + } +} + +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 + } +} + +mod to_reuse { + use super::Trait; + pub fn value(_: impl Trait) -> i32 { 1 } + pub fn mut_ref(_: &mut impl Trait) -> i32 { 2 } + pub fn r#ref(_: &impl Trait) -> i32 { 3 } +} + +reuse to_reuse::{value, mut_ref, r#ref} { F } +//~^ ERROR: mismatched types +//~| ERROR: mismatched types + +fn main() {} diff --git a/tests/ui/delegation/self-coercion-static-free.stderr b/tests/ui/delegation/self-coercion-static-free.stderr new file mode 100644 index 0000000000000..5f78272815aa5 --- /dev/null +++ b/tests/ui/delegation/self-coercion-static-free.stderr @@ -0,0 +1,87 @@ +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:24:9 + | +LL | S::static_self() + | ^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` + | +help: consider mutably borrowing here + | +LL | &mut S::static_self() + | ++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:24:9 + | +LL | S::static_self() + | ^^^^^^^^^^^^^^^^ expected `&F`, found `F` + | +help: consider borrowing here + | +LL | &S::static_self() + | + + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:35:9 + | +LL | S1::static_self() + | ^^^^^^^^^^^^^^^^^ expected `&mut F`, found `F` + | +help: consider mutably borrowing here + | +LL | &mut S1::static_self() + | ++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:35:9 + | +LL | S1::static_self() + | ^^^^^^^^^^^^^^^^^ expected `&F`, found `F` + | +help: consider borrowing here + | +LL | &S1::static_self() + | + + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:48:43 + | +LL | reuse to_reuse::{value, mut_ref, r#ref} { F } + | ------- ^ expected `&mut _`, found `F` + | | + | arguments to this function are incorrect + | + = note: expected mutable reference `&mut _` + found struct `F` +note: function defined here + --> $DIR/self-coercion-static-free.rs:44:12 + | +LL | pub fn mut_ref(_: &mut impl Trait) -> i32 { 2 } + | ^^^^^^^ ------------------ +help: consider mutably borrowing here + | +LL | reuse to_reuse::{value, mut_ref, r#ref} { &mut F } + | ++++ + +error[E0308]: mismatched types + --> $DIR/self-coercion-static-free.rs:48:43 + | +LL | reuse to_reuse::{value, mut_ref, r#ref} { F } + | ----- ^ expected `&_`, found `F` + | | + | arguments to this function are incorrect + | + = note: expected reference `&_` + found struct `F` +note: function defined here + --> $DIR/self-coercion-static-free.rs:45:12 + | +LL | pub fn r#ref(_: &impl Trait) -> i32 { 3 } + | ^^^^^ -------------- +help: consider borrowing here + | +LL | reuse to_reuse::{value, mut_ref, r#ref} { &F } + | + + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/self-coercion.rs b/tests/ui/delegation/self-coercion.rs index e6c71ec1e257b..21b2b0cd2f56b 100644 --- a/tests/ui/delegation/self-coercion.rs +++ b/tests/ui/delegation/self-coercion.rs @@ -2,12 +2,13 @@ #![feature(fn_delegation)] -trait Trait : Sized { +trait Trait: Sized { fn by_value(self) -> i32 { 1 } fn by_mut_ref(&mut self) -> i32 { 2 } fn by_ref(&self) -> i32 { 3 } } +#[derive(Default)] struct F; impl Trait for F {} @@ -17,9 +18,20 @@ impl Trait for S { reuse Trait::{by_value, by_mut_ref, by_ref} { self.0 } } +struct S1(Box>>>>>); + +impl Trait for S1 { + reuse Trait::{by_value, by_mut_ref, by_ref} { self.0 } +} + fn main() { let mut s = S(F); assert_eq!(s.by_ref(), 3); assert_eq!(s.by_mut_ref(), 2); assert_eq!(s.by_value(), 1); + + let mut s = S1(Default::default()); + assert_eq!(s.by_ref(), 3); + assert_eq!(s.by_mut_ref(), 2); + assert_eq!(s.by_value(), 1); } diff --git a/tests/ui/delegation/wrong-lifetime-rib.rs b/tests/ui/delegation/wrong-lifetime-rib.rs index 825ac6a64008a..01645f20bf7b1 100644 --- a/tests/ui/delegation/wrong-lifetime-rib.rs +++ b/tests/ui/delegation/wrong-lifetime-rib.rs @@ -33,7 +33,7 @@ mod ice_156806 { trait X {} impl X { //~ ERROR: expected a type, found a trait - reuse Iterator::fold { //~ ERROR: `()` is not an iterator + reuse Iterator::fold { let _: &X; //~ ERROR: expected a type, found a trait } } diff --git a/tests/ui/delegation/wrong-lifetime-rib.stderr b/tests/ui/delegation/wrong-lifetime-rib.stderr index 07ddc94f7a4ae..0c4499eec192d 100644 --- a/tests/ui/delegation/wrong-lifetime-rib.stderr +++ b/tests/ui/delegation/wrong-lifetime-rib.stderr @@ -66,17 +66,7 @@ help: you can add the `dyn` keyword if you want a trait object LL | let _: &dyn X; | +++ -error[E0599]: `()` is not an iterator - --> $DIR/wrong-lifetime-rib.rs:36:25 - | -LL | reuse Iterator::fold { - | ^^^^ `()` is not an iterator - | - = note: the following trait bounds were not satisfied: - `(): Iterator` - which is required by `&mut (): Iterator` - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0116, E0223, E0423, E0599, E0782. +Some errors have detailed explanations: E0116, E0223, E0423, E0782. For more information about an error, try `rustc --explain E0116`.