mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
commit
1ddedbaa59
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
259
compiler/rustc_hir_analysis/src/delegation.rs
Normal file
259
compiler/rustc_hir_analysis/src/delegation.rs
Normal 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(¶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<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)
|
||||||
|
}
|
@ -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,
|
||||||
|
@ -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) => {
|
||||||
|
@ -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<'_>) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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.
|
||||||
|
@ -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`
|
||||||
|
@ -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`.
|
||||||
|
28
tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs
Normal file
28
tests/ui/delegation/generics/free-fn-to-free-fn-pass.rs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
27
tests/ui/delegation/generics/free-fn-to-free-fn.rs
Normal file
27
tests/ui/delegation/generics/free-fn-to-free-fn.rs
Normal 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
|
||||||
|
}
|
54
tests/ui/delegation/generics/free-fn-to-free-fn.stderr
Normal file
54
tests/ui/delegation/generics/free-fn-to-free-fn.stderr
Normal 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`.
|
30
tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs
Normal file
30
tests/ui/delegation/generics/free-fn-to-trait-method-pass.rs
Normal 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);
|
||||||
|
}
|
56
tests/ui/delegation/generics/free-fn-to-trait-method.rs
Normal file
56
tests/ui/delegation/generics/free-fn-to-trait-method.rs
Normal 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
|
||||||
|
}
|
88
tests/ui/delegation/generics/free-fn-to-trait-method.stderr
Normal file
88
tests/ui/delegation/generics/free-fn-to-trait-method.stderr
Normal 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`.
|
@ -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() {}
|
||||||
|
@ -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`.
|
||||||
|
@ -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() {}
|
||||||
|
@ -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`.
|
||||||
|
@ -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);
|
||||||
|
@ -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`.
|
||||||
|
Loading…
Reference in New Issue
Block a user