Auto merge of #125929 - Bryanskiy:delegation-generics-3, r=petrochenkov

Delegation: support generics for delegation from free functions

(The PR was split from https://github.com/rust-lang/rust/pull/123958, explainer - https://github.com/Bryanskiy/posts/blob/master/delegation%20in%20generic%20contexts.md)

This PR implements generics inheritance from free functions to free functions and trait methods.

#### free functions to free functions:

```rust
fn to_reuse<T: Clone>(_: T) {}

reuse to_reuse as bar;
// desugaring:
fn bar<T: Clone>(x: T) {
  to_reuse(x)
}
```

Generics, predicates and signature are simply copied. Generic arguments in paths are ignored during generics inheritance:

```rust
fn to_reuse<T: Clone>(_: T) {}

reuse to_reuse::<u8> as bar;
// desugaring:
fn bar<T: Clone>(x: T) {
  to_reuse::<u8>(x) // ERROR: mismatched types
}
```

Due to implementation limitations callee path is lowered without modifications. Therefore, it is a compilation error at the moment.

#### free functions to trait methods:

```rust
trait Trait<'a, A> {
    fn foo<'b, B>(&self, x: A, y: B) {...}
}

reuse Trait::foo;
// desugaring:
fn foo<'a, 'b, This: Trait<'a, A>, A, B>(this: &This, x: A, y: B) {
  Trait::foo(this, x, y)
}
```

The inheritance is similar to the previous case but with some corrections:

- `Self` parameter converted into `T: Trait`
- generic parameters need to be reordered so that lifetimes go first

Arguments are similarly ignored.

---

In the future, we plan to  support generic inheritance for delegating from all contexts to all contexts (from free/trait/impl to free/trait /impl). These cases were considered first as the simplest from the implementation perspective.
This commit is contained in:
bors 2024-07-30 10:39:33 +00:00
commit 1ddedbaa59
24 changed files with 702 additions and 233 deletions

View File

@ -33,7 +33,7 @@
//! HIR ty lowering. //! HIR ty lowering.
//! //!
//! Similarly generics, predicates and header are set to the "default" values. //! 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. //! also be emitted during HIR ty lowering.
use std::iter; use std::iter;

View File

@ -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_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 = hir_analysis_not_supported_delegation = {$descr}
{$descr} is not supported yet
.label = callee defined here .label = callee defined here
hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate

View File

@ -10,6 +10,7 @@ use rustc_session::lint;
use rustc_span::symbol::{kw, Symbol}; use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span; use rustc_span::Span;
use crate::delegation::inherit_generics_for_delegation_item;
use crate::middle::resolve_bound_vars as rbv; use crate::middle::resolve_bound_vars as rbv;
#[instrument(level = "debug", skip(tcx), ret)] #[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 hir_id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir_node(hir_id); let node = tcx.hir_node(hir_id);

View File

@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP};
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::collect::ItemCtxt; use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp; use crate::constrained_generic_params as cgp;
use crate::delegation::inherit_predicates_for_delegation_item;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason}; use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
/// Returns a list of all type predicates (explicit and implicit) for the definition with /// 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 => {} 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 hir_id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir_node(hir_id); let node = tcx.hir_node(hir_id);

View File

@ -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<u32, u32>;
struct ParamIndexRemapper<'tcx> {
tcx: TyCtxt<'tcx>,
remap_table: RemapTable,
}
impl<'tcx> TypeFolder<TyCtxt<'tcx>> 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(&param.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(&param.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(&param.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<ty::Generics> {
// 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<ty::GenericPredicates<'tcx>> {
// 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)
}

View File

@ -1575,7 +1575,7 @@ pub struct RefOfMutStatic<'a> {
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(hir_analysis_not_supported_delegation)] #[diag(hir_analysis_not_supported_delegation)]
pub struct NotSupportedDelegation<'a> { pub struct UnsupportedDelegation<'a> {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,
pub descr: &'a str, pub descr: &'a str,

View File

@ -2007,93 +2007,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.lower_ty_common(hir_ty, false, true) self.lower_ty_common(hir_ty, false, true)
} }
fn check_delegation_constraints(&self, sig_id: DefId, span: Span, emit: bool) -> bool { fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
let mut error_occured = false; let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
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();
match idx { match idx {
hir::InferDelegationKind::Input(id) => sig.inputs()[id], hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
hir::InferDelegationKind::Output => sig.output(), hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
} }
} }
@ -2110,9 +2028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let tcx = self.tcx(); let tcx = self.tcx();
let result_ty = match &hir_ty.kind { let result_ty = match &hir_ty.kind {
hir::TyKind::InferDelegation(sig_id, idx) => { hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
self.lower_delegation_ty(*sig_id, *idx, hir_ty.span)
}
hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), 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::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
hir::TyKind::Ref(region, mt) => { hir::TyKind::Ref(region, mt) => {

View File

@ -83,6 +83,7 @@ pub mod autoderef;
mod bounds; mod bounds;
mod check_unused; mod check_unused;
mod coherence; mod coherence;
mod delegation;
pub mod hir_ty_lowering; pub mod hir_ty_lowering;
// FIXME: This module shouldn't be public. // FIXME: This module shouldn't be public.
pub mod collect; pub mod collect;
@ -146,6 +147,10 @@ pub fn provide(providers: &mut Providers) {
variance::provide(providers); variance::provide(providers);
outlives::provide(providers); outlives::provide(providers);
hir_wf_check::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<'_>) { pub fn check_crate(tcx: TyCtxt<'_>) {

View File

@ -746,6 +746,21 @@ impl<'hir> Map<'hir> {
} }
} }
pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option<DefId> {
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] #[inline]
fn opt_ident(self, id: HirId) -> Option<Ident> { fn opt_ident(self, id: HirId) -> Option<Ident> {
match self.tcx.hir_node(id) { match self.tcx.hir_node(id) {

View File

@ -1722,6 +1722,10 @@ rustc_queries! {
desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } 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 /// Does lifetime resolution on items. Importantly, we can't resolve
/// lifetimes directly on things like trait methods, because of trait params. /// lifetimes directly on things like trait methods, because of trait params.
/// See `rustc_resolve::late::lifetimes` for details. /// See `rustc_resolve::late::lifetimes` for details.

View File

@ -22,9 +22,7 @@ mod fn_to_other {
use super::*; use super::*;
reuse Trait::foo1; reuse Trait::foo1;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse <S as Trait>::foo2; reuse <S as Trait>::foo2;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse to_reuse::foo3; reuse to_reuse::foo3;
reuse S::foo4; reuse S::foo4;
//~^ ERROR cannot find function `foo4` in `S` //~^ ERROR cannot find function `foo4` in `S`

View File

@ -1,5 +1,5 @@
error[E0407]: method `foo3` is not a member of trait `Trait` 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; LL | reuse to_reuse::foo3;
| ^^^^^^^^^^^^^^^^----^ | ^^^^^^^^^^^^^^^^----^
@ -8,7 +8,7 @@ LL | reuse to_reuse::foo3;
| not a member of trait `Trait` | not a member of trait `Trait`
error[E0407]: method `foo4` is 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 } LL | reuse F::foo4 { &self.0 }
| ^^^^^^^^^----^^^^^^^^^^^^ | ^^^^^^^^^----^^^^^^^^^^^^
@ -17,49 +17,49 @@ LL | reuse F::foo4 { &self.0 }
| not a member of trait `Trait` | not a member of trait `Trait`
error[E0425]: cannot find function `foo4` in `S` error[E0425]: cannot find function `foo4` in `S`
--> $DIR/explicit-paths.rs:29:14 --> $DIR/explicit-paths.rs:27:14
| |
LL | reuse S::foo4; LL | reuse S::foo4;
| ^^^^ not found in `S` | ^^^^ not found in `S`
error[E0425]: cannot find function `foo4` in `F` 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 } LL | reuse F::foo4 { &self.0 }
| ^^^^ not found in `F` | ^^^^ not found in `F`
| |
note: function `fn_to_other::foo4` exists but is inaccessible 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; LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible | ^^^^^^^^^^^^^^ not accessible
error[E0425]: cannot find function `foo4` in `F` 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 } LL | reuse F::foo4 { &self.0 }
| ^^^^ not found in `F` | ^^^^ not found in `F`
| |
note: function `fn_to_other::foo4` exists but is inaccessible 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; LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible | ^^^^^^^^^^^^^^ not accessible
error[E0425]: cannot find function `foo4` in `F` 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 } LL | reuse F::foo4 { &F }
| ^^^^ not found in `F` | ^^^^ not found in `F`
| |
note: function `fn_to_other::foo4` exists but is inaccessible 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; LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible | ^^^^^^^^^^^^^^ not accessible
error[E0119]: conflicting implementations of trait `Trait` for type `S` 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 { LL | impl Trait for S {
| ---------------- first implementation here | ---------------- first implementation here
@ -67,26 +67,8 @@ LL | impl Trait for S {
LL | impl Trait for S { LL | impl Trait for S {
| ^^^^^^^^^^^^^^^^ conflicting implementation 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 <S as Trait>::foo2;
| ^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/explicit-paths.rs:63:36 --> $DIR/explicit-paths.rs:61:36
| |
LL | trait Trait2 : Trait { LL | trait Trait2 : Trait {
| -------------------- found this type parameter | -------------------- 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 error[E0277]: the trait bound `S2: Trait` is not satisfied
--> $DIR/explicit-paths.rs:78:16 --> $DIR/explicit-paths.rs:76:16
| |
LL | reuse <S2 as Trait>::foo1; LL | reuse <S2 as Trait>::foo1;
| ^^ the trait `Trait` is not implemented for `S2` | ^^ the trait `Trait` is not implemented for `S2`
@ -114,7 +96,7 @@ LL | reuse <S2 as Trait>::foo1;
S S
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/explicit-paths.rs:78:30 --> $DIR/explicit-paths.rs:76:30
| |
LL | reuse <S2 as Trait>::foo1; LL | reuse <S2 as Trait>::foo1;
| ^^^^ | ^^^^
@ -130,7 +112,7 @@ note: method defined here
LL | fn foo1(&self, x: i32) -> i32 { x } 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. Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425.
For more information about an error, try `rustc --explain E0119`. For more information about an error, try `rustc --explain E0119`.

View File

@ -0,0 +1,28 @@
//@ run-pass
#![feature(fn_delegation)]
#![allow(incomplete_features)]
mod to_reuse {
pub fn types<T, U>(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");
}
}

View File

@ -0,0 +1,27 @@
#![feature(fn_delegation)]
#![allow(incomplete_features)]
mod to_reuse {
pub fn consts<const N: i32>() -> i32 {
N
}
pub fn late<'a>(x: &'a u8) -> u8 {
*x
}
pub fn bounds<T: Clone>(_: 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
}

View File

@ -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<const N: i32>() -> i32 {
| ^^^^^^^^^^^^ required by this const generic parameter in `consts`
help: consider specifying the generic argument
|
LL | reuse to_reuse::consts::<N>;
| +++++
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: Clone>(_: 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`.

View File

@ -0,0 +1,30 @@
//@ run-pass
#![feature(fn_delegation)]
#![allow(incomplete_features)]
mod types {
pub trait Trait<T> {
fn foo<U>(&self, x: U, y: T) -> (T, U) {(y, x)}
}
impl<T> Trait<T> 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::<u8, T, U>(&1, &U, &T), true);
}

View File

@ -0,0 +1,56 @@
#![feature(fn_delegation)]
#![allow(incomplete_features)]
mod default_param {
pub trait Trait<T = u32> {
fn foo(&self, _: T) {}
}
impl<T> Trait<T> 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<T> {
fn foo<U: Clone>(&self, t: T, u: U) where T: Copy {}
}
impl<T> Trait<T> for u8 {}
}
mod generic_arguments {
trait Trait<T> {
fn foo<U>(&self, _: U, _: T) {}
}
impl<T> Trait<T> for u8 {}
reuse Trait::<_>::foo::<i32> as generic_arguments1;
//~^ ERROR mismatched types
reuse <u8 as Trait<_>>::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
}

View File

@ -0,0 +1,88 @@
error[E0308]: mismatched types
--> $DIR/free-fn-to-trait-method.rs:36:23
|
LL | fn foo<U>(&self, _: U, _: T) {}
| - found this type parameter
...
LL | reuse Trait::<_>::foo::<i32> 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<U>(&self, _: U, _: T) {}
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/free-fn-to-trait-method.rs:38:29
|
LL | trait Trait<T> {
| -------------- found this type parameter
...
LL | reuse <u8 as Trait<_>>::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<U>(&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<U: Clone>(&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<U: Clone>(&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`.

View File

@ -6,7 +6,8 @@ trait Trait {
//~^ ERROR recursive delegation is not supported yet //~^ ERROR recursive delegation is not supported yet
} }
// FIXME(fn_delegation): `recursive delegation` error should be emitted here
reuse foo; reuse foo;
//~^ ERROR recursive delegation is not supported yet //~^ ERROR cycle detected when computing generics of `foo`
fn main() {} fn main() {}

View File

@ -4,11 +4,20 @@ error: recursive delegation is not supported yet
LL | reuse Trait::foo { &self.0 } LL | reuse Trait::foo { &self.0 }
| ^^^ callee defined here | ^^^ callee defined here
error: recursive delegation is not supported yet error[E0391]: cycle detected when computing generics of `foo`
--> $DIR/ice-issue-124347.rs:9:7 --> $DIR/ice-issue-124347.rs:10:7
| |
LL | reuse foo; 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 error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0391`.

View File

@ -1,4 +1,6 @@
#![feature(const_trait_impl)]
#![feature(c_variadic)] #![feature(c_variadic)]
#![feature(effects)]
#![feature(fn_delegation)] #![feature(fn_delegation)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
@ -14,9 +16,9 @@ mod generics {
fn foo3<'a: 'a>(_: &'a u32) {} fn foo3<'a: 'a>(_: &'a u32) {}
reuse GenericTrait::bar; 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; 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; struct F;
@ -27,37 +29,37 @@ mod generics {
impl<T> GenericTrait<T> for S { impl<T> GenericTrait<T> for S {
reuse <F as GenericTrait<T>>::bar { &self.0 } reuse <F as GenericTrait<T>>::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::<T>::bar1; reuse GenericTrait::<T>::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 () { impl GenericTrait<()> for () {
reuse GenericTrait::bar { &F } 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; 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 { impl Trait for &S {
reuse Trait::foo; 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 { impl Trait for S {
reuse Trait::foo1 { &self.0 } reuse Trait::foo1 { &self.0 }
reuse Trait::foo2 { &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 //~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
reuse <F as Trait>::foo3; reuse <F as Trait>::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 //~| ERROR lifetime parameters or bounds on method `foo3` do not match the trait declaration
} }
struct GenericS<T>(T); struct GenericS<T>(T);
impl<T> Trait for GenericS<T> { impl<T> Trait for GenericS<T> {
reuse Trait::foo { &self.0 } 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 { mod to_reuse {
use super::Trait; use super::Trait;
pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
pub fn opaque_ret() -> impl Trait { unimplemented!() } pub fn opaque_ret() -> impl Trait { unimplemented!() }
//~^ warn: this function depends on never type fallback being `()` //~^ 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! //~| 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 { trait ToReuse {
fn opaque_ret() -> impl Trait { unimplemented!() } fn opaque_ret() -> impl Trait { unimplemented!() }
@ -104,4 +103,14 @@ mod recursive {
//~^ ERROR recursive delegation is not supported yet //~^ 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() {} fn main() {}

View File

@ -1,5 +1,10 @@
error: delegation with early bound generics is not supported yet error: using `#![feature(effects)]` without enabling next trait solver globally
--> $DIR/not-supported.rs:16:29 |
= 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 } LL | fn bar(&self, x: T) -> T { x }
| ------------------------ callee defined here | ------------------------ callee defined here
@ -7,8 +12,8 @@ LL | fn bar(&self, x: T) -> T { x }
LL | reuse GenericTrait::bar; LL | reuse GenericTrait::bar;
| ^^^ | ^^^
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:18:29 --> $DIR/not-supported.rs:20:29
| |
LL | fn bar1() {} LL | fn bar1() {}
| --------- callee defined here | --------- callee defined here
@ -16,8 +21,8 @@ LL | fn bar1() {}
LL | reuse GenericTrait::bar1; LL | reuse GenericTrait::bar1;
| ^^^^ | ^^^^
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:29:39 --> $DIR/not-supported.rs:31:39
| |
LL | fn bar(&self, x: T) -> T { x } LL | fn bar(&self, x: T) -> T { x }
| ------------------------ callee defined here | ------------------------ callee defined here
@ -25,8 +30,8 @@ LL | fn bar(&self, x: T) -> T { x }
LL | reuse <F as GenericTrait<T>>::bar { &self.0 } LL | reuse <F as GenericTrait<T>>::bar { &self.0 }
| ^^^ | ^^^
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:31:34 --> $DIR/not-supported.rs:33:34
| |
LL | fn bar1() {} LL | fn bar1() {}
| --------- callee defined here | --------- callee defined here
@ -34,8 +39,8 @@ LL | fn bar1() {}
LL | reuse GenericTrait::<T>::bar1; LL | reuse GenericTrait::<T>::bar1;
| ^^^^ | ^^^^
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:36:29 --> $DIR/not-supported.rs:38:29
| |
LL | fn bar(&self, x: T) -> T { x } LL | fn bar(&self, x: T) -> T { x }
| ------------------------ callee defined here | ------------------------ callee defined here
@ -43,8 +48,8 @@ LL | fn bar(&self, x: T) -> T { x }
LL | reuse GenericTrait::bar { &F } LL | 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
--> $DIR/not-supported.rs:38:29 --> $DIR/not-supported.rs:40:29
| |
LL | fn bar1() {} LL | fn bar1() {}
| --------- callee defined here | --------- callee defined here
@ -52,8 +57,8 @@ LL | fn bar1() {}
LL | reuse GenericTrait::bar1; LL | reuse GenericTrait::bar1;
| ^^^^ | ^^^^
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:43:22 --> $DIR/not-supported.rs:45:22
| |
LL | fn foo(&self, x: i32) -> i32 { x } LL | fn foo(&self, x: i32) -> i32 { x }
| ---------------------------- callee defined here | ---------------------------- 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 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<T>(&self, x: T) -> T { x } LL | fn foo2<T>(&self, x: T) -> T { x }
| - expected 1 type parameter | - expected 1 type parameter
@ -70,8 +75,8 @@ LL | fn foo2<T>(&self, x: T) -> T { x }
LL | reuse Trait::foo2 { &self.0 } LL | reuse Trait::foo2 { &self.0 }
| ^^^^ found 0 type parameters | ^^^^ found 0 type parameters
error: delegation with early bound generics is not supported yet error: early bound generics are not supported for associated delegation items
--> $DIR/not-supported.rs:52:29 --> $DIR/not-supported.rs:54:29
| |
LL | fn foo3<'a: 'a>(_: &'a u32) {} LL | fn foo3<'a: 'a>(_: &'a u32) {}
| --------------------------- callee defined here | --------------------------- callee defined here
@ -80,7 +85,7 @@ LL | reuse <F as Trait>::foo3;
| ^^^^ | ^^^^
error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration 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) {} LL | fn foo3<'a: 'a>(_: &'a u32) {}
| -------- lifetimes in impl do not match this method in trait | -------- lifetimes in impl do not match this method in trait
@ -88,8 +93,17 @@ LL | fn foo3<'a: 'a>(_: &'a u32) {}
LL | reuse <F as Trait>::foo3; LL | reuse <F as Trait>::foo3;
| ^^^^ lifetimes do not match method in trait | ^^^^ lifetimes do not match method in trait
error: delegation with early bound generics is not supported yet error: delegation to a function with effect parameter is not supported yet
--> $DIR/not-supported.rs:59:22 --> $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 } LL | fn foo(&self, x: i32) -> i32 { x }
| ---------------------------- callee defined here | ---------------------------- callee defined here
@ -97,8 +111,8 @@ LL | fn foo(&self, x: i32) -> i32 { x }
LL | reuse Trait::foo { &self.0 } LL | 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
--> $DIR/not-supported.rs:49:22 --> $DIR/not-supported.rs:51:22
| |
LL | fn foo2<T>(&self, x: T) -> T { x } LL | fn foo2<T>(&self, x: T) -> T { x }
| ---------------------------- callee defined here | ---------------------------- callee defined here
@ -106,17 +120,8 @@ LL | fn foo2<T>(&self, x: T) -> T { x }
LL | reuse Trait::foo2 { &self.0 } 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 `()` 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!() } 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 <https://github.com/rust-lang/rust/issues/123748> = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly = help: specify the types explicitly
note: in edition 2024, the requirement `!: opaque::Trait` will fail 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!() } LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^ | ^^^^^^^^^^
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:86:5: 86:24>::{synthetic#0}` error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>::{synthetic#0}`
--> $DIR/not-supported.rs:87:25 --> $DIR/not-supported.rs:86:25
| |
LL | reuse to_reuse::opaque_ret; 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... 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; LL | reuse to_reuse::opaque_ret;
| ^^^^^^^^^^ | ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:86:5: 86:24>::{synthetic#0}`, completing the cycle = note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:86:5: 86:24>` is well-formed note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>` is well-formed
--> $DIR/not-supported.rs:86:5 --> $DIR/not-supported.rs:85:5
| |
LL | impl ToReuse for u8 { 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 = 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 `()` 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!() } 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 <https://github.com/rust-lang/rust/issues/123748> = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly = help: specify the types explicitly
note: in edition 2024, the requirement `!: opaque::Trait` will fail 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!() } LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:89:5: 89:25>::{synthetic#0}` error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>::{synthetic#0}`
--> $DIR/not-supported.rs:90:24 --> $DIR/not-supported.rs:89:24
| |
LL | reuse ToReuse::opaque_ret; LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... 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; LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^ | ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:89:5: 89:25>::{synthetic#0}`, completing the cycle = note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:89:5: 89:25>` is well-formed note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>` is well-formed
--> $DIR/not-supported.rs:89:5 --> $DIR/not-supported.rs:88:5
| |
LL | impl ToReuse for u16 { 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 = 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 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; LL | pub reuse to_reuse2::foo;
| --- callee defined here | --- callee defined here
@ -193,7 +198,7 @@ LL | pub reuse to_reuse2::foo;
LL | reuse to_reuse1::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. Some errors have detailed explanations: E0049, E0195, E0391.
For more information about an error, try `rustc --explain E0049`. For more information about an error, try `rustc --explain E0049`.

View File

@ -14,9 +14,7 @@ fn foo(x: i32) -> i32 { x }
fn bar<T: Default>(_: T) { fn bar<T: Default>(_: T) {
reuse Trait::static_method { reuse Trait::static_method {
//~^ ERROR delegation to a trait method from a free function is not supported yet //~^ ERROR mismatched types
//~| ERROR delegation with early bound generics is not supported yet
//~| ERROR mismatched types
let _ = T::Default(); let _ = T::Default();
//~^ ERROR can't use generic parameters from outer item //~^ ERROR can't use generic parameters from outer item
} }
@ -25,7 +23,6 @@ fn bar<T: Default>(_: T) {
fn main() { fn main() {
let y = 0; let y = 0;
reuse <S as Trait>::static_method { reuse <S as Trait>::static_method {
//~^ ERROR delegation to a trait method from a free function is not supported yet
let x = y; let x = y;
//~^ ERROR can't capture dynamic environment in a fn item //~^ ERROR can't capture dynamic environment in a fn item
foo(self); foo(self);

View File

@ -1,16 +1,16 @@
error[E0401]: can't use generic parameters from outer item 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: Default>(_: T) { LL | fn bar<T: Default>(_: T) {
| - type parameter from outer item | - type parameter from outer item
LL | reuse Trait::static_method { LL | reuse Trait::static_method {
| - help: try introducing a local generic parameter here: `T,` | - help: try introducing a local generic parameter here: `T,`
... LL |
LL | let _ = T::Default(); LL | let _ = T::Default();
| ^^^^^^^^^^ use of generic parameter from outer item | ^^^^^^^^^^ use of generic parameter from outer item
error[E0434]: can't capture dynamic environment in a fn 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; LL | let x = y;
| ^ | ^
@ -18,7 +18,7 @@ LL | let x = y;
= help: use the `|| { ... }` closure form instead = help: use the `|| { ... }` closure form instead
error[E0424]: expected value, found module `self` error[E0424]: expected value, found module `self`
--> $DIR/target-expr.rs:36:5 --> $DIR/target-expr.rs:33:5
| |
LL | fn main() { LL | fn main() {
| ---- this function can't have a `self` parameter | ---- 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 | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
error[E0425]: cannot find value `x` in this scope 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; LL | let z = x;
| ^ | ^
| |
help: the binding `x` is available in a different scope in the same function 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; 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 <S as Trait>::static_method {
| ^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/target-expr.rs:16:32 --> $DIR/target-expr.rs:16:32
| |
LL | reuse Trait::static_method { LL | reuse Trait::static_method {
| ________________________________^ | ________________________________^
LL | | LL | |
LL | |
LL | |
LL | | let _ = T::Default(); LL | | let _ = T::Default();
LL | | LL | |
LL | | } LL | | }
| |_____^ expected `i32`, found `()` | |_____^ 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. Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
For more information about an error, try `rustc --explain E0308`. For more information about an error, try `rustc --explain E0308`.