From f2f9aab3806916105518ce8e4ccb143028ab81ff Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Thu, 30 May 2024 22:00:44 +0300 Subject: [PATCH] Delegation: support generics for delegation from free functions --- compiler/rustc_ast_lowering/src/delegation.rs | 2 +- compiler/rustc_hir_analysis/messages.ftl | 3 +- .../src/collect/generics_of.rs | 8 + .../src/collect/predicates_of.rs | 8 + compiler/rustc_hir_analysis/src/delegation.rs | 259 ++++++++++++++++++ compiler/rustc_hir_analysis/src/errors.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 94 +------ compiler/rustc_hir_analysis/src/lib.rs | 5 + compiler/rustc_middle/src/hir/map/mod.rs | 15 + compiler/rustc_middle/src/query/mod.rs | 4 + tests/ui/delegation/explicit-paths.rs | 2 - tests/ui/delegation/explicit-paths.stderr | 46 +--- .../generics/free-fn-to-free-fn-pass.rs | 28 ++ .../delegation/generics/free-fn-to-free-fn.rs | 27 ++ .../generics/free-fn-to-free-fn.stderr | 54 ++++ .../generics/free-fn-to-trait-method-pass.rs | 30 ++ .../generics/free-fn-to-trait-method.rs | 56 ++++ .../generics/free-fn-to-trait-method.stderr | 88 ++++++ tests/ui/delegation/ice-issue-124347.rs | 3 +- tests/ui/delegation/ice-issue-124347.stderr | 15 +- tests/ui/delegation/not-supported.rs | 35 ++- tests/ui/delegation/not-supported.stderr | 103 +++---- tests/ui/delegation/target-expr.rs | 5 +- tests/ui/delegation/target-expr.stderr | 43 +-- 24 files changed, 702 insertions(+), 233 deletions(-) create mode 100644 compiler/rustc_hir_analysis/src/delegation.rs create mode 100644 tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs create mode 100644 tests/ui/delegation/generics/free-fn-to-free-fn.rs create mode 100644 tests/ui/delegation/generics/free-fn-to-free-fn.stderr create mode 100644 tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs create mode 100644 tests/ui/delegation/generics/free-fn-to-trait-method.rs create mode 100644 tests/ui/delegation/generics/free-fn-to-trait-method.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 378d98e5c34..6e8ff72cf87 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -33,7 +33,7 @@ //! HIR ty lowering. //! //! Similarly generics, predicates and header are set to the "default" values. -//! In case of discrepancy with callee function the `NotSupportedDelegation` error will +//! In case of discrepancy with callee function the `UnsupportedDelegation` error will //! also be emitted during HIR ty lowering. use std::iter; diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 367f6e17e7f..bde94be6f51 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -341,8 +341,7 @@ hir_analysis_must_implement_not_function_span_note = required by this annotation hir_analysis_must_implement_one_of_attribute = the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args -hir_analysis_not_supported_delegation = - {$descr} is not supported yet +hir_analysis_not_supported_delegation = {$descr} .label = callee defined here hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 41ffb038341..80a65aa2988 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -10,6 +10,7 @@ use rustc_session::lint; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; +use crate::delegation::inherit_generics_for_delegation_item; use crate::middle::resolve_bound_vars as rbv; #[instrument(level = "debug", skip(tcx), ret)] @@ -53,6 +54,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { }; } + // For a delegation item inherit generics from callee. + if let Some(sig_id) = tcx.hir().opt_delegation_sig_id(def_id) + && let Some(generics) = inherit_generics_for_delegation_item(tcx, def_id, sig_id) + { + return generics; + } + let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 783365bdacc..ae52dbd56f9 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP}; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; +use crate::delegation::inherit_predicates_for_delegation_item; use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason}; /// Returns a list of all type predicates (explicit and implicit) for the definition with @@ -114,6 +115,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen None => {} } + // For a delegation item inherit predicates from callee. + if let Some(sig_id) = tcx.hir().opt_delegation_sig_id(def_id) + && let Some(predicates) = inherit_predicates_for_delegation_item(tcx, def_id, sig_id) + { + return predicates; + } + let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs new file mode 100644 index 00000000000..e21ed55bce3 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -0,0 +1,259 @@ +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::ErrorGuaranteed; +use rustc_type_ir::visit::TypeVisitableExt; + +type RemapTable = FxHashMap; + +struct ParamIndexRemapper<'tcx> { + tcx: TyCtxt<'tcx>, + remap_table: RemapTable, +} + +impl<'tcx> TypeFolder> for ParamIndexRemapper<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.has_param() { + return ty; + } + + if let ty::Param(param) = ty.kind() + && let Some(index) = self.remap_table.get(¶m.index) + { + return Ty::new_param(self.tcx, *index, param.name); + } + ty.super_fold_with(self) + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if let ty::ReEarlyParam(param) = r.kind() + && let Some(index) = self.remap_table.get(¶m.index).copied() + { + return ty::Region::new_early_param( + self.tcx, + ty::EarlyParamRegion { index, name: param.name }, + ); + } + r + } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if let ty::ConstKind::Param(param) = ct.kind() + && let Some(idx) = self.remap_table.get(¶m.index) + { + let param = ty::ParamConst::new(*idx, param.name); + return ty::Const::new_param(self.tcx, param); + } + ct.super_fold_with(self) + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +enum FnKind { + Free, + AssocInherentImpl, + AssocTrait, + AssocTraitImpl, +} + +fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind { + debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn)); + + let parent = tcx.parent(def_id); + match tcx.def_kind(parent) { + DefKind::Trait => FnKind::AssocTrait, + DefKind::Impl { of_trait: true } => FnKind::AssocTraitImpl, + DefKind::Impl { of_trait: false } => FnKind::AssocInherentImpl, + _ => FnKind::Free, + } +} + +fn create_generic_args<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> ty::GenericArgsRef<'tcx> { + let caller_generics = tcx.generics_of(def_id); + let callee_generics = tcx.generics_of(sig_id); + + let caller_kind = fn_kind(tcx, def_id.into()); + let callee_kind = fn_kind(tcx, sig_id); + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + match (caller_kind, callee_kind) { + (FnKind::Free, _) => { + // Lifetime parameters must be declared before type and const parameters. + // Therefore, When delegating from a free function to a associated function, + // generic parameters need to be reordered: + // + // trait Trait<'a, A> { + // fn foo<'b, B>(...) {...} + // } + // + // reuse Trait::foo; + // desugaring: + // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) { + // Trait::foo(...) + // } + let mut remap_table = RemapTable::default(); + for caller_param in &caller_generics.own_params { + let callee_index = + callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap(); + remap_table.insert(callee_index, caller_param.index); + } + let mut folder = ParamIndexRemapper { tcx, remap_table }; + ty::GenericArgs::identity_for_item(tcx, sig_id).fold_with(&mut folder) + } + // FIXME(fn_delegation): Only `Self` param supported here. + (FnKind::AssocTraitImpl, FnKind::AssocTrait) + | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { + let parent = tcx.parent(def_id.into()); + let self_ty = tcx.type_of(parent).instantiate_identity(); + let generic_self_ty = ty::GenericArg::from(self_ty); + tcx.mk_args_from_iter(std::iter::once(generic_self_ty)) + } + _ => ty::GenericArgs::identity_for_item(tcx, sig_id), + } +} + +pub(crate) fn inherit_generics_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Option { + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + if fn_kind(tcx, def_id.into()) != FnKind::Free { + return None; + } + + let mut own_params = vec![]; + + let callee_generics = tcx.generics_of(sig_id); + if let Some(parent_sig_id) = callee_generics.parent { + let parent_sig_generics = tcx.generics_of(parent_sig_id); + own_params.append(&mut parent_sig_generics.own_params.clone()); + } + own_params.append(&mut callee_generics.own_params.clone()); + + // Lifetimes go first. + own_params.sort_by_key(|key| key.kind.is_ty_or_const()); + + for (idx, param) in own_params.iter_mut().enumerate() { + param.index = idx as u32; + // Default parameters are not inherited: they are not allowed + // in fn's. + if let ty::GenericParamDefKind::Type { has_default, .. } + | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind + { + *has_default = false; + } + } + + let param_def_id_to_index = + own_params.iter().map(|param| (param.def_id, param.index)).collect(); + + Some(ty::Generics { + parent: None, + parent_count: 0, + own_params, + param_def_id_to_index, + has_self: false, + has_late_bound_regions: callee_generics.has_late_bound_regions, + host_effect_index: callee_generics.host_effect_index, + }) +} + +pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Option> { + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + if fn_kind(tcx, def_id.into()) != FnKind::Free { + return None; + } + + let callee_predicates = tcx.predicates_of(sig_id); + let args = create_generic_args(tcx, def_id, sig_id); + + let mut preds = vec![]; + if let Some(parent_id) = callee_predicates.parent { + preds.extend(tcx.predicates_of(parent_id).instantiate_own(tcx, args)); + } + preds.extend(callee_predicates.instantiate_own(tcx, args)); + + Some(ty::GenericPredicates { + parent: None, + predicates: tcx.arena.alloc_from_iter(preds), + effects_min_tys: ty::List::empty(), + }) +} + +fn check_constraints<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Result<(), ErrorGuaranteed> { + let mut ret = Ok(()); + + let mut emit = |descr| { + ret = Err(tcx.dcx().emit_err(crate::errors::UnsupportedDelegation { + span: tcx.def_span(def_id), + descr, + callee_span: tcx.def_span(sig_id), + })); + }; + + if tcx.has_host_param(sig_id) { + emit("delegation to a function with effect parameter is not supported yet"); + } + + if let Some(local_sig_id) = sig_id.as_local() + && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() + { + emit("recursive delegation is not supported yet"); + } + + if fn_kind(tcx, def_id.into()) != FnKind::Free { + let sig_generics = tcx.generics_of(sig_id); + let parent = tcx.parent(def_id.into()); + let parent_generics = tcx.generics_of(parent); + + let parent_has_self = parent_generics.has_self as usize; + let sig_has_self = sig_generics.has_self as usize; + + if sig_generics.count() > sig_has_self || parent_generics.count() > parent_has_self { + emit("early bound generics are not supported for associated delegation items"); + } + } + + ret +} + +pub(crate) fn inherit_sig_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> &'tcx [Ty<'tcx>] { + let sig_id = tcx.hir().delegation_sig_id(def_id); + let caller_sig = tcx.fn_sig(sig_id); + if let Err(err) = check_constraints(tcx, def_id, sig_id) { + let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; + let err_type = Ty::new_error(tcx, err); + return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type)); + } + let args = create_generic_args(tcx, def_id, sig_id); + + // Bound vars are also inherited from `sig_id`. + // They will be rebound later in `lower_fn_ty`. + let sig = caller_sig.instantiate(tcx, args).skip_binder(); + let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output())); + tcx.arena.alloc_from_iter(sig_iter) +} diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index b1ac973ef2e..7034735aec0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1575,7 +1575,7 @@ pub struct RefOfMutStatic<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_not_supported_delegation)] -pub struct NotSupportedDelegation<'a> { +pub struct UnsupportedDelegation<'a> { #[primary_span] pub span: Span, pub descr: &'a str, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 52b2411cd37..d865357b829 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2007,93 +2007,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_ty_common(hir_ty, false, true) } - fn check_delegation_constraints(&self, sig_id: DefId, span: Span, emit: bool) -> bool { - let mut error_occured = false; - let sig_span = self.tcx().def_span(sig_id); - let mut try_emit = |descr| { - if emit { - self.dcx().emit_err(crate::errors::NotSupportedDelegation { - span, - descr, - callee_span: sig_span, - }); - } - error_occured = true; - }; - - if let Some(node) = self.tcx().hir().get_if_local(sig_id) - && let Some(decl) = node.fn_decl() - && let hir::FnRetTy::Return(ty) = decl.output - && let hir::TyKind::InferDelegation(_, _) = ty.kind - { - try_emit("recursive delegation"); - } - - let sig_generics = self.tcx().generics_of(sig_id); - let parent = self.tcx().local_parent(self.item_def_id()); - let parent_generics = self.tcx().generics_of(parent); - - let parent_is_trait = (self.tcx().def_kind(parent) == DefKind::Trait) as usize; - let sig_has_self = sig_generics.has_self as usize; - - if sig_generics.count() > sig_has_self || parent_generics.count() > parent_is_trait { - try_emit("delegation with early bound generics"); - } - - // There is no way to instantiate `Self` param for caller if - // 1. callee is a trait method - // 2. delegation item isn't an associative item - if let DefKind::AssocFn = self.tcx().def_kind(sig_id) - && let DefKind::Fn = self.tcx().def_kind(self.item_def_id()) - && self.tcx().associated_item(sig_id).container - == ty::AssocItemContainer::TraitContainer - { - try_emit("delegation to a trait method from a free function"); - } - - error_occured - } - - fn lower_delegation_ty( - &self, - sig_id: DefId, - idx: hir::InferDelegationKind, - span: Span, - ) -> Ty<'tcx> { - if self.check_delegation_constraints(sig_id, span, idx == hir::InferDelegationKind::Output) - { - let e = self.dcx().span_delayed_bug(span, "not supported delegation case"); - return Ty::new_error(self.tcx(), e); - }; - let sig = self.tcx().fn_sig(sig_id); - let sig_generics = self.tcx().generics_of(sig_id); - - let parent = self.tcx().local_parent(self.item_def_id()); - let parent_def_kind = self.tcx().def_kind(parent); - - let sig = if let DefKind::Impl { .. } = parent_def_kind - && sig_generics.has_self - { - // Generic params can't be here except the trait self type. - // They are not supported yet. - assert_eq!(sig_generics.count(), 1); - assert_eq!(self.tcx().generics_of(parent).count(), 0); - - let self_ty = self.tcx().type_of(parent).instantiate_identity(); - let generic_self_ty = ty::GenericArg::from(self_ty); - let args = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty)); - sig.instantiate(self.tcx(), args) - } else { - sig.instantiate_identity() - }; - - // Bound vars are also inherited from `sig_id`. - // They will be rebound later in `lower_fn_ty`. - let sig = sig.skip_binder(); - + fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { + let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { - hir::InferDelegationKind::Input(id) => sig.inputs()[id], - hir::InferDelegationKind::Output => sig.output(), + hir::InferDelegationKind::Input(idx) => delegation_sig[idx], + hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(), } } @@ -2110,9 +2028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let result_ty = match &hir_ty.kind { - hir::TyKind::InferDelegation(sig_id, idx) => { - self.lower_delegation_ty(*sig_id, *idx, hir_ty.span) - } + hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx), hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl), hir::TyKind::Ref(region, mt) => { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 8154e7cfd36..061db14ad0a 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -83,6 +83,7 @@ pub mod autoderef; mod bounds; mod check_unused; mod coherence; +mod delegation; pub mod hir_ty_lowering; // FIXME: This module shouldn't be public. pub mod collect; @@ -146,6 +147,10 @@ pub fn provide(providers: &mut Providers) { variance::provide(providers); outlives::provide(providers); hir_wf_check::provide(providers); + *providers = Providers { + inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item, + ..*providers + }; } pub fn check_crate(tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1c223481a07..1705c016437 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -746,6 +746,21 @@ impl<'hir> Map<'hir> { } } + pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { + if let Some(ret) = self.get_fn_output(def_id) + && let FnRetTy::Return(ty) = ret + && let TyKind::InferDelegation(sig_id, _) = ty.kind + { + return Some(sig_id); + } + None + } + + #[inline] + pub fn delegation_sig_id(self, def_id: LocalDefId) -> DefId { + self.opt_delegation_sig_id(def_id).unwrap() + } + #[inline] fn opt_ident(self, id: HirId) -> Option { match self.tcx.hir_node(id) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ff8ee9f6456..c22c2e985ab 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1722,6 +1722,10 @@ rustc_queries! { desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } } + query inherit_sig_for_delegation_item(def_id: LocalDefId) -> &'tcx [Ty<'tcx>] { + desc { "inheriting delegation signature" } + } + /// Does lifetime resolution on items. Importantly, we can't resolve /// lifetimes directly on things like trait methods, because of trait params. /// See `rustc_resolve::late::lifetimes` for details. diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs index d42e305b252..3b0454eb524 100644 --- a/tests/ui/delegation/explicit-paths.rs +++ b/tests/ui/delegation/explicit-paths.rs @@ -22,9 +22,7 @@ mod fn_to_other { use super::*; reuse Trait::foo1; - //~^ ERROR delegation to a trait method from a free function is not supported yet reuse ::foo2; - //~^ ERROR delegation to a trait method from a free function is not supported yet reuse to_reuse::foo3; reuse S::foo4; //~^ ERROR cannot find function `foo4` in `S` diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index b5afe19f878..8098ea8c54f 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -1,5 +1,5 @@ error[E0407]: method `foo3` is not a member of trait `Trait` - --> $DIR/explicit-paths.rs:51:9 + --> $DIR/explicit-paths.rs:49:9 | LL | reuse to_reuse::foo3; | ^^^^^^^^^^^^^^^^----^ @@ -8,7 +8,7 @@ LL | reuse to_reuse::foo3; | not a member of trait `Trait` error[E0407]: method `foo4` is not a member of trait `Trait` - --> $DIR/explicit-paths.rs:53:9 + --> $DIR/explicit-paths.rs:51:9 | LL | reuse F::foo4 { &self.0 } | ^^^^^^^^^----^^^^^^^^^^^^ @@ -17,49 +17,49 @@ LL | reuse F::foo4 { &self.0 } | not a member of trait `Trait` error[E0425]: cannot find function `foo4` in `S` - --> $DIR/explicit-paths.rs:29:14 + --> $DIR/explicit-paths.rs:27:14 | LL | reuse S::foo4; | ^^^^ not found in `S` error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:40:18 + --> $DIR/explicit-paths.rs:38:18 | LL | reuse F::foo4 { &self.0 } | ^^^^ not found in `F` | note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:29:5 + --> $DIR/explicit-paths.rs:27:5 | LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:53:18 + --> $DIR/explicit-paths.rs:51:18 | LL | reuse F::foo4 { &self.0 } | ^^^^ not found in `F` | note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:29:5 + --> $DIR/explicit-paths.rs:27:5 | LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible error[E0425]: cannot find function `foo4` in `F` - --> $DIR/explicit-paths.rs:67:18 + --> $DIR/explicit-paths.rs:65:18 | LL | reuse F::foo4 { &F } | ^^^^ not found in `F` | note: function `fn_to_other::foo4` exists but is inaccessible - --> $DIR/explicit-paths.rs:29:5 + --> $DIR/explicit-paths.rs:27:5 | LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible error[E0119]: conflicting implementations of trait `Trait` for type `S` - --> $DIR/explicit-paths.rs:76:5 + --> $DIR/explicit-paths.rs:74:5 | LL | impl Trait for S { | ---------------- first implementation here @@ -67,26 +67,8 @@ LL | impl Trait for S { LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ conflicting implementation for `S` -error: delegation to a trait method from a free function is not supported yet - --> $DIR/explicit-paths.rs:24:18 - | -LL | fn foo1(&self, x: i32) -> i32 { x } - | ----------------------------- callee defined here -... -LL | reuse Trait::foo1; - | ^^^^ - -error: delegation to a trait method from a free function is not supported yet - --> $DIR/explicit-paths.rs:26:25 - | -LL | fn foo2(x: i32) -> i32 { x } - | ---------------------- callee defined here -... -LL | reuse ::foo2; - | ^^^^ - error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:63:36 + --> $DIR/explicit-paths.rs:61:36 | LL | trait Trait2 : Trait { | -------------------- found this type parameter @@ -104,7 +86,7 @@ LL | fn foo1(&self, x: i32) -> i32 { x } | ^^^^ ----- error[E0277]: the trait bound `S2: Trait` is not satisfied - --> $DIR/explicit-paths.rs:78:16 + --> $DIR/explicit-paths.rs:76:16 | LL | reuse ::foo1; | ^^ the trait `Trait` is not implemented for `S2` @@ -114,7 +96,7 @@ LL | reuse ::foo1; S error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:78:30 + --> $DIR/explicit-paths.rs:76:30 | LL | reuse ::foo1; | ^^^^ @@ -130,7 +112,7 @@ note: method defined here LL | fn foo1(&self, x: i32) -> i32 { x } | ^^^^ ----- -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs b/tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs new file mode 100644 index 00000000000..625bbdd758c --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs @@ -0,0 +1,28 @@ +//@ run-pass +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn types(x: U, y: T) -> (T, U) { + (y, x) + } + pub fn late<'a, 'b>(x: &'a u8, y: &'b u8) -> u8 { + *x + *y + } + pub fn early<'a: 'a>(x: &'a str) -> &'a str { + x + } +} + +reuse to_reuse::types; +reuse to_reuse::late; +reuse to_reuse::early; + +fn main() { + assert_eq!(types(0, "str"), ("str", 0)); + assert_eq!(late(&1u8, &2u8), 3); + { + let s: &'static str = "hello world"; + assert_eq!(early::<'static>(s), "hello world"); + } +} diff --git a/tests/ui/delegation/generics/free-fn-to-free-fn.rs b/tests/ui/delegation/generics/free-fn-to-free-fn.rs new file mode 100644 index 00000000000..3741ad66485 --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-free-fn.rs @@ -0,0 +1,27 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn consts() -> i32 { + N + } + pub fn late<'a>(x: &'a u8) -> u8 { + *x + } + pub fn bounds(_: T) {} +} + +// FIXME(fn_delegation): this is supposed to work eventually +reuse to_reuse::consts; +//~^ ERROR type annotations needed +reuse to_reuse::late; +reuse to_reuse::bounds; + +fn main() { + late::<'static>(&0u8); + //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + + struct S; + bounds(S); + //~^ ERROR the trait bound `S: Clone` is not satisfied +} diff --git a/tests/ui/delegation/generics/free-fn-to-free-fn.stderr b/tests/ui/delegation/generics/free-fn-to-free-fn.stderr new file mode 100644 index 00000000000..5ba56ce1718 --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-free-fn.stderr @@ -0,0 +1,54 @@ +error[E0284]: type annotations needed + --> $DIR/free-fn-to-free-fn.rs:15:17 + | +LL | reuse to_reuse::consts; + | ^^^^^^ cannot infer the value of the const parameter `N` declared on the function `consts` + | +note: required by a const generic parameter in `to_reuse::consts` + --> $DIR/free-fn-to-free-fn.rs:5:19 + | +LL | pub fn consts() -> i32 { + | ^^^^^^^^^^^^ required by this const generic parameter in `consts` +help: consider specifying the generic argument + | +LL | reuse to_reuse::consts::; + | +++++ + +error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/free-fn-to-free-fn.rs:21:12 + | +LL | late::<'static>(&0u8); + | ^^^^^^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/free-fn-to-free-fn.rs:8:17 + | +LL | pub fn late<'a>(x: &'a u8) -> u8 { + | ^^ + +error[E0277]: the trait bound `S: Clone` is not satisfied + --> $DIR/free-fn-to-free-fn.rs:25:12 + | +LL | bounds(S); + | ------ ^ the trait `Clone` is not implemented for `S` + | | + | required by a bound introduced by this call + | +note: required by a bound in `bounds` + --> $DIR/free-fn-to-free-fn.rs:11:22 + | +LL | pub fn bounds(_: T) {} + | ^^^^^ required by this bound in `bounds` +... +LL | reuse to_reuse::bounds; + | ------ required by a bound in this function +help: consider annotating `S` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct S; + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0284, E0794. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs b/tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs new file mode 100644 index 00000000000..f7b7c09e2ca --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs @@ -0,0 +1,30 @@ +//@ run-pass +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod types { + pub trait Trait { + fn foo(&self, x: U, y: T) -> (T, U) {(y, x)} + } + impl Trait for u8 {} +} + +mod types_and_lifetimes { + pub trait Trait<'a, T> { + fn foo<'b, U>(&self, _: &'b U, _: &'a T) -> bool { + true + } + } + impl<'a, T> Trait<'a, T> for u8 {} +} + +reuse types::Trait::foo as types; +reuse types_and_lifetimes::Trait::foo as types_and_lifetimes; + +fn main() { + assert_eq!(types(&2, "str", 1), (1, "str")); + + struct T; + struct U; + assert_eq!(types_and_lifetimes::(&1, &U, &T), true); +} diff --git a/tests/ui/delegation/generics/free-fn-to-trait-method.rs b/tests/ui/delegation/generics/free-fn-to-trait-method.rs new file mode 100644 index 00000000000..70be1a4ace7 --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-trait-method.rs @@ -0,0 +1,56 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod default_param { + pub trait Trait { + fn foo(&self, _: T) {} + } + + impl Trait for u8 {} +} + +mod types_and_lifetimes { + pub trait Trait<'a, T> { + fn foo<'b: 'b>(&'a self, x: &'b T) { + loop {} + } + } + impl<'a, T> Trait<'a, T> for u8 {} +} + +mod bounds { + pub trait Trait { + fn foo(&self, t: T, u: U) where T: Copy {} + } + + impl Trait for u8 {} +} + +mod generic_arguments { + trait Trait { + fn foo(&self, _: U, _: T) {} + } + + impl Trait for u8 {} + + reuse Trait::<_>::foo:: as generic_arguments1; + //~^ ERROR mismatched types + reuse >::foo as generic_arguments2; + //~^ ERROR mismatched types + reuse <_ as Trait<_>>::foo as generic_arguments3; // OK +} + +reuse default_param::Trait::foo as default_param; +reuse types_and_lifetimes::Trait::foo as types_and_lifetimes; +reuse bounds::Trait::foo as bounds; + +fn main() { + default_param(&0u8, "hello world"); // OK, default params are not substituted + types_and_lifetimes::<'static, 'static, _, _>(&0u8, &0u16); // OK, lifetimes go first + + struct S; + struct U; + bounds(&0u8, S, U); + //~^ ERROR the trait bound `S: Copy` is not satisfied + //~| ERROR the trait bound `U: Clone` is not satisfied +} diff --git a/tests/ui/delegation/generics/free-fn-to-trait-method.stderr b/tests/ui/delegation/generics/free-fn-to-trait-method.stderr new file mode 100644 index 00000000000..d8299d00c7e --- /dev/null +++ b/tests/ui/delegation/generics/free-fn-to-trait-method.stderr @@ -0,0 +1,88 @@ +error[E0308]: mismatched types + --> $DIR/free-fn-to-trait-method.rs:36:23 + | +LL | fn foo(&self, _: U, _: T) {} + | - found this type parameter +... +LL | reuse Trait::<_>::foo:: as generic_arguments1; + | ^^^ + | | + | expected `i32`, found type parameter `U` + | arguments to this function are incorrect + | + = note: expected type `i32` + found type parameter `U` +note: method defined here + --> $DIR/free-fn-to-trait-method.rs:31:12 + | +LL | fn foo(&self, _: U, _: T) {} + | ^^^ ---- + +error[E0308]: mismatched types + --> $DIR/free-fn-to-trait-method.rs:38:29 + | +LL | trait Trait { + | -------------- found this type parameter +... +LL | reuse >::foo as generic_arguments2; + | ^^^ + | | + | expected `&u8`, found `&Self` + | arguments to this function are incorrect + | + = note: expected reference `&u8` + found reference `&Self` +note: method defined here + --> $DIR/free-fn-to-trait-method.rs:31:12 + | +LL | fn foo(&self, _: U, _: T) {} + | ^^^ ----- + +error[E0277]: the trait bound `S: Copy` is not satisfied + --> $DIR/free-fn-to-trait-method.rs:53:18 + | +LL | bounds(&0u8, S, U); + | ------ ^ the trait `Copy` is not implemented for `S` + | | + | required by a bound introduced by this call + | +note: required by a bound in `bounds` + --> $DIR/free-fn-to-trait-method.rs:23:54 + | +LL | fn foo(&self, t: T, u: U) where T: Copy {} + | ^^^^ required by this bound in `bounds` +... +LL | reuse bounds::Trait::foo as bounds; + | ------ required by a bound in this function +help: consider annotating `S` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct S; + | + +error[E0277]: the trait bound `U: Clone` is not satisfied + --> $DIR/free-fn-to-trait-method.rs:53:21 + | +LL | bounds(&0u8, S, U); + | ------ ^ the trait `Clone` is not implemented for `U` + | | + | required by a bound introduced by this call + | +note: required by a bound in `bounds` + --> $DIR/free-fn-to-trait-method.rs:23:19 + | +LL | fn foo(&self, t: T, u: U) where T: Copy {} + | ^^^^^ required by this bound in `bounds` +... +LL | reuse bounds::Trait::foo as bounds; + | ------ required by a bound in this function +help: consider annotating `U` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct U; + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index 82a96055099..3bfae8face5 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -6,7 +6,8 @@ trait Trait { //~^ ERROR recursive delegation is not supported yet } +// FIXME(fn_delegation): `recursive delegation` error should be emitted here reuse foo; -//~^ ERROR recursive delegation is not supported yet +//~^ ERROR cycle detected when computing generics of `foo` fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index 5a3f4525d29..87dd75ffec8 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -4,11 +4,20 @@ error: recursive delegation is not supported yet LL | reuse Trait::foo { &self.0 } | ^^^ callee defined here -error: recursive delegation is not supported yet - --> $DIR/ice-issue-124347.rs:9:7 +error[E0391]: cycle detected when computing generics of `foo` + --> $DIR/ice-issue-124347.rs:10:7 | LL | reuse foo; - | ^^^ callee defined here + | ^^^ + | + = note: ...which immediately requires computing generics of `foo` again +note: cycle used when checking that `foo` is well-formed + --> $DIR/ice-issue-124347.rs:10:7 + | +LL | reuse foo; + | ^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs index 25d7a4cb895..5701cc6055d 100644 --- a/tests/ui/delegation/not-supported.rs +++ b/tests/ui/delegation/not-supported.rs @@ -1,4 +1,6 @@ +#![feature(const_trait_impl)] #![feature(c_variadic)] +#![feature(effects)] #![feature(fn_delegation)] #![allow(incomplete_features)] @@ -14,9 +16,9 @@ mod generics { fn foo3<'a: 'a>(_: &'a u32) {} reuse GenericTrait::bar; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items reuse GenericTrait::bar1; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items } struct F; @@ -27,37 +29,37 @@ mod generics { impl GenericTrait for S { reuse >::bar { &self.0 } - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items reuse GenericTrait::::bar1; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items } impl GenericTrait<()> for () { reuse GenericTrait::bar { &F } - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items reuse GenericTrait::bar1; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items } impl Trait for &S { reuse Trait::foo; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items } impl Trait for S { reuse Trait::foo1 { &self.0 } reuse Trait::foo2 { &self.0 } - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items //~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter reuse ::foo3; - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items //~| ERROR lifetime parameters or bounds on method `foo3` do not match the trait declaration } struct GenericS(T); impl Trait for GenericS { reuse Trait::foo { &self.0 } - //~^ ERROR delegation with early bound generics is not supported yet + //~^ ERROR early bound generics are not supported for associated delegation items } } @@ -68,13 +70,10 @@ mod opaque { mod to_reuse { use super::Trait; - pub fn opaque_arg(_: impl Trait) -> i32 { 0 } pub fn opaque_ret() -> impl Trait { unimplemented!() } //~^ warn: this function depends on never type fallback being `()` //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } - reuse to_reuse::opaque_arg; - //~^ ERROR delegation with early bound generics is not supported yet trait ToReuse { fn opaque_ret() -> impl Trait { unimplemented!() } @@ -104,4 +103,14 @@ mod recursive { //~^ ERROR recursive delegation is not supported yet } +mod effects { + #[const_trait] + trait Trait { + fn foo(); + } + + reuse Trait::foo; + //~^ ERROR delegation to a function with effect parameter is not supported yet +} + fn main() {} diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr index 4ce01fd5d88..e7ba9fc6719 100644 --- a/tests/ui/delegation/not-supported.stderr +++ b/tests/ui/delegation/not-supported.stderr @@ -1,5 +1,10 @@ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:16:29 +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:18:29 | LL | fn bar(&self, x: T) -> T { x } | ------------------------ callee defined here @@ -7,8 +12,8 @@ LL | fn bar(&self, x: T) -> T { x } LL | reuse GenericTrait::bar; | ^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:18:29 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:20:29 | LL | fn bar1() {} | --------- callee defined here @@ -16,8 +21,8 @@ LL | fn bar1() {} LL | reuse GenericTrait::bar1; | ^^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:29:39 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:31:39 | LL | fn bar(&self, x: T) -> T { x } | ------------------------ callee defined here @@ -25,8 +30,8 @@ LL | fn bar(&self, x: T) -> T { x } LL | reuse >::bar { &self.0 } | ^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:31:34 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:33:34 | LL | fn bar1() {} | --------- callee defined here @@ -34,8 +39,8 @@ LL | fn bar1() {} LL | reuse GenericTrait::::bar1; | ^^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:36:29 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:38:29 | LL | fn bar(&self, x: T) -> T { x } | ------------------------ callee defined here @@ -43,8 +48,8 @@ LL | fn bar(&self, x: T) -> T { x } LL | reuse GenericTrait::bar { &F } | ^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:38:29 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:40:29 | LL | fn bar1() {} | --------- callee defined here @@ -52,8 +57,8 @@ LL | fn bar1() {} LL | reuse GenericTrait::bar1; | ^^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:43:22 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:45:22 | LL | fn foo(&self, x: i32) -> i32 { x } | ---------------------------- callee defined here @@ -62,7 +67,7 @@ LL | reuse Trait::foo; | ^^^ error[E0049]: method `foo2` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/not-supported.rs:49:22 + --> $DIR/not-supported.rs:51:22 | LL | fn foo2(&self, x: T) -> T { x } | - expected 1 type parameter @@ -70,8 +75,8 @@ LL | fn foo2(&self, x: T) -> T { x } LL | reuse Trait::foo2 { &self.0 } | ^^^^ found 0 type parameters -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:52:29 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:54:29 | LL | fn foo3<'a: 'a>(_: &'a u32) {} | --------------------------- callee defined here @@ -80,7 +85,7 @@ LL | reuse ::foo3; | ^^^^ error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration - --> $DIR/not-supported.rs:52:29 + --> $DIR/not-supported.rs:54:29 | LL | fn foo3<'a: 'a>(_: &'a u32) {} | -------- lifetimes in impl do not match this method in trait @@ -88,8 +93,17 @@ LL | fn foo3<'a: 'a>(_: &'a u32) {} LL | reuse ::foo3; | ^^^^ lifetimes do not match method in trait -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:59:22 +error: delegation to a function with effect parameter is not supported yet + --> $DIR/not-supported.rs:112:18 + | +LL | fn foo(); + | --------- callee defined here +... +LL | reuse Trait::foo; + | ^^^ + +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:61:22 | LL | fn foo(&self, x: i32) -> i32 { x } | ---------------------------- callee defined here @@ -97,8 +111,8 @@ LL | fn foo(&self, x: i32) -> i32 { x } LL | reuse Trait::foo { &self.0 } | ^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:49:22 +error: early bound generics are not supported for associated delegation items + --> $DIR/not-supported.rs:51:22 | LL | fn foo2(&self, x: T) -> T { x } | ---------------------------- callee defined here @@ -106,17 +120,8 @@ LL | fn foo2(&self, x: T) -> T { x } LL | reuse Trait::foo2 { &self.0 } | ^^^^ -error: delegation with early bound generics is not supported yet - --> $DIR/not-supported.rs:76:21 - | -LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 } - | --------------------------------------- callee defined here -... -LL | reuse to_reuse::opaque_arg; - | ^^^^^^^^^^ - warning: this function depends on never type fallback being `()` - --> $DIR/not-supported.rs:80:9 + --> $DIR/not-supported.rs:79:9 | LL | fn opaque_ret() -> impl Trait { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,33 +130,33 @@ LL | fn opaque_ret() -> impl Trait { unimplemented!() } = note: for more information, see issue #123748 = help: specify the types explicitly note: in edition 2024, the requirement `!: opaque::Trait` will fail - --> $DIR/not-supported.rs:80:28 + --> $DIR/not-supported.rs:79:28 | LL | fn opaque_ret() -> impl Trait { unimplemented!() } | ^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default -error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` - --> $DIR/not-supported.rs:87:25 +error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` + --> $DIR/not-supported.rs:86:25 | LL | reuse to_reuse::opaque_ret; | ^^^^^^^^^^ | note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... - --> $DIR/not-supported.rs:87:25 + --> $DIR/not-supported.rs:86:25 | LL | reuse to_reuse::opaque_ret; | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle -note: cycle used when checking that `opaque::` is well-formed - --> $DIR/not-supported.rs:86:5 + = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle +note: cycle used when checking that `opaque::` is well-formed + --> $DIR/not-supported.rs:85:5 | LL | impl ToReuse for u8 { | ^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information warning: this function depends on never type fallback being `()` - --> $DIR/not-supported.rs:72:9 + --> $DIR/not-supported.rs:73:9 | LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,32 +165,32 @@ LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } = note: for more information, see issue #123748 = help: specify the types explicitly note: in edition 2024, the requirement `!: opaque::Trait` will fail - --> $DIR/not-supported.rs:72:32 + --> $DIR/not-supported.rs:73:32 | LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } | ^^^^^^^^^^ -error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` - --> $DIR/not-supported.rs:90:24 +error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` + --> $DIR/not-supported.rs:89:24 | LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ | note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... - --> $DIR/not-supported.rs:90:24 + --> $DIR/not-supported.rs:89:24 | LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle -note: cycle used when checking that `opaque::` is well-formed - --> $DIR/not-supported.rs:89:5 + = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle +note: cycle used when checking that `opaque::` is well-formed + --> $DIR/not-supported.rs:88:5 | LL | impl ToReuse for u16 { | ^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: recursive delegation is not supported yet - --> $DIR/not-supported.rs:103:22 + --> $DIR/not-supported.rs:102:22 | LL | pub reuse to_reuse2::foo; | --- callee defined here @@ -193,7 +198,7 @@ LL | pub reuse to_reuse2::foo; LL | reuse to_reuse1::foo; | ^^^ -error: aborting due to 16 previous errors; 2 warnings emitted +error: aborting due to 17 previous errors; 2 warnings emitted Some errors have detailed explanations: E0049, E0195, E0391. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs index fd7ea943b9d..f766ca7356a 100644 --- a/tests/ui/delegation/target-expr.rs +++ b/tests/ui/delegation/target-expr.rs @@ -14,9 +14,7 @@ fn foo(x: i32) -> i32 { x } fn bar(_: T) { reuse Trait::static_method { - //~^ ERROR delegation to a trait method from a free function is not supported yet - //~| ERROR delegation with early bound generics is not supported yet - //~| ERROR mismatched types + //~^ ERROR mismatched types let _ = T::Default(); //~^ ERROR can't use generic parameters from outer item } @@ -25,7 +23,6 @@ fn bar(_: T) { fn main() { let y = 0; reuse ::static_method { - //~^ ERROR delegation to a trait method from a free function is not supported yet let x = y; //~^ ERROR can't capture dynamic environment in a fn item foo(self); diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index b30f0c474c6..f5556bf9f45 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -1,16 +1,16 @@ error[E0401]: can't use generic parameters from outer item - --> $DIR/target-expr.rs:20:17 + --> $DIR/target-expr.rs:18:17 | LL | fn bar(_: T) { | - type parameter from outer item LL | reuse Trait::static_method { | - help: try introducing a local generic parameter here: `T,` -... +LL | LL | let _ = T::Default(); | ^^^^^^^^^^ use of generic parameter from outer item error[E0434]: can't capture dynamic environment in a fn item - --> $DIR/target-expr.rs:29:17 + --> $DIR/target-expr.rs:26:17 | LL | let x = y; | ^ @@ -18,7 +18,7 @@ LL | let x = y; = help: use the `|| { ... }` closure form instead error[E0424]: expected value, found module `self` - --> $DIR/target-expr.rs:36:5 + --> $DIR/target-expr.rs:33:5 | LL | fn main() { | ---- this function can't have a `self` parameter @@ -27,58 +27,29 @@ LL | self.0; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter error[E0425]: cannot find value `x` in this scope - --> $DIR/target-expr.rs:38:13 + --> $DIR/target-expr.rs:35:13 | LL | let z = x; | ^ | help: the binding `x` is available in a different scope in the same function - --> $DIR/target-expr.rs:29:13 + --> $DIR/target-expr.rs:26:13 | LL | let x = y; | ^ -error: delegation with early bound generics is not supported yet - --> $DIR/target-expr.rs:16:18 - | -LL | fn static_method(x: i32) -> i32 { x } - | ------------------------------- callee defined here -... -LL | reuse Trait::static_method { - | ^^^^^^^^^^^^^ - -error: delegation to a trait method from a free function is not supported yet - --> $DIR/target-expr.rs:16:18 - | -LL | fn static_method(x: i32) -> i32 { x } - | ------------------------------- callee defined here -... -LL | reuse Trait::static_method { - | ^^^^^^^^^^^^^ - -error: delegation to a trait method from a free function is not supported yet - --> $DIR/target-expr.rs:27:25 - | -LL | fn static_method(x: i32) -> i32 { x } - | ------------------------------- callee defined here -... -LL | reuse ::static_method { - | ^^^^^^^^^^^^^ - error[E0308]: mismatched types --> $DIR/target-expr.rs:16:32 | LL | reuse Trait::static_method { | ________________________________^ LL | | -LL | | -LL | | LL | | let _ = T::Default(); LL | | LL | | } | |_____^ expected `i32`, found `()` -error: aborting due to 8 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434. For more information about an error, try `rustc --explain E0308`.