mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #112988 - spastorino:new-rpitit-24, r=compiler-errors
Replace RPITIT current impl with new strategy that lowers as a GAT This PR replaces the current implementation of RPITITs with the new implementation that we had under -Zlower-impl-trait-in-trait-to-assoc-ty flag that lowers the RPIT as a GAT on the trait and on the impls that implement that trait. Opening this PR as a draft because this goes after #112682, ~#112981~ and ~#112983~. As soon as those are merged, I can rebase and we should run perf, crater and test a lot. r? `@compiler-errors`
This commit is contained in:
commit
8ca44ef9ca
@ -109,8 +109,6 @@ pub enum DefKind {
|
||||
InlineConst,
|
||||
/// Opaque type, aka `impl Trait`.
|
||||
OpaqueTy,
|
||||
/// A return-position `impl Trait` in a trait definition
|
||||
ImplTraitPlaceholder,
|
||||
Field,
|
||||
/// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
|
||||
LifetimeParam,
|
||||
@ -143,7 +141,6 @@ impl DefKind {
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
|
||||
DefKind::OpaqueTy => "opaque type",
|
||||
DefKind::ImplTraitPlaceholder => "opaque type in trait",
|
||||
DefKind::TyAlias => "type alias",
|
||||
DefKind::TraitAlias => "trait alias",
|
||||
DefKind::AssocTy => "associated type",
|
||||
@ -227,8 +224,7 @@ impl DefKind {
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::ImplTraitPlaceholder => None,
|
||||
| DefKind::Impl { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +258,6 @@ impl DefKind {
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Field
|
||||
| DefKind::TyParam
|
||||
|
@ -36,7 +36,6 @@ pub enum Target {
|
||||
GlobalAsm,
|
||||
TyAlias,
|
||||
OpaqueTy,
|
||||
ImplTraitPlaceholder,
|
||||
Enum,
|
||||
Variant,
|
||||
Struct,
|
||||
@ -80,13 +79,7 @@ impl Target {
|
||||
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
||||
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
||||
ItemKind::TyAlias(..) => Target::TyAlias,
|
||||
ItemKind::OpaqueTy(ref opaque) => {
|
||||
if opaque.in_trait {
|
||||
Target::ImplTraitPlaceholder
|
||||
} else {
|
||||
Target::OpaqueTy
|
||||
}
|
||||
}
|
||||
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
|
||||
ItemKind::Enum(..) => Target::Enum,
|
||||
ItemKind::Struct(..) => Target::Struct,
|
||||
ItemKind::Union(..) => Target::Union,
|
||||
@ -110,7 +103,6 @@ impl Target {
|
||||
DefKind::GlobalAsm => Target::GlobalAsm,
|
||||
DefKind::TyAlias => Target::TyAlias,
|
||||
DefKind::OpaqueTy => Target::OpaqueTy,
|
||||
DefKind::ImplTraitPlaceholder => Target::ImplTraitPlaceholder,
|
||||
DefKind::Enum => Target::Enum,
|
||||
DefKind::Struct => Target::Struct,
|
||||
DefKind::Union => Target::Union,
|
||||
@ -165,7 +157,6 @@ impl Target {
|
||||
Target::GlobalAsm => "global asm",
|
||||
Target::TyAlias => "type alias",
|
||||
Target::OpaqueTy => "opaque type",
|
||||
Target::ImplTraitPlaceholder => "opaque type in trait",
|
||||
Target::Enum => "enum",
|
||||
Target::Variant => "enum variant",
|
||||
Target::Struct => "struct",
|
||||
|
@ -2128,7 +2128,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let span = path.span;
|
||||
match path.res {
|
||||
Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
|
||||
Res::Def(DefKind::OpaqueTy, did) => {
|
||||
// Check for desugared `impl Trait`.
|
||||
assert!(tcx.is_type_alias_impl_trait(did));
|
||||
let item_segment = path.segments.split_last().unwrap();
|
||||
@ -2439,7 +2439,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
|
||||
// generate the def_id of an associated type for the trait and return as
|
||||
// type a projection.
|
||||
let def_id = if in_trait && tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
let def_id = if in_trait {
|
||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id()
|
||||
} else {
|
||||
local_def_id.to_def_id()
|
||||
|
@ -302,16 +302,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||
|
||||
if let ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||
in_trait,
|
||||
..
|
||||
}) = item.kind
|
||||
{
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let opaque_identity_ty = if in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
Ty::new_projection(tcx, def_id.to_def_id(), substs)
|
||||
} else {
|
||||
Ty::new_opaque(tcx, def_id.to_def_id(), substs)
|
||||
};
|
||||
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
||||
let mut visitor = ProhibitOpaqueVisitor {
|
||||
opaque_identity_ty,
|
||||
parent_count: tcx.generics_of(def_id).parent_count as u32,
|
||||
@ -576,17 +571,6 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||
check_opaque(tcx, id);
|
||||
}
|
||||
}
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
|
||||
// Only check the validity of this opaque type if the function has a default body
|
||||
if let hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
|
||||
..
|
||||
}) = tcx.hir().get_by_def_id(parent.expect_local())
|
||||
{
|
||||
check_opaque(tcx, id);
|
||||
}
|
||||
}
|
||||
DefKind::TyAlias => {
|
||||
let pty_ty = tcx.type_of(id.owner_id).subst_identity();
|
||||
let generics = tcx.generics_of(id.owner_id);
|
||||
|
@ -113,16 +113,12 @@ pub(super) fn explicit_item_bounds(
|
||||
..
|
||||
}) => associated_type_bounds(tcx, def_id, bounds, *span),
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
|
||||
span,
|
||||
..
|
||||
}) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
Ty::new_projection(tcx, def_id.to_def_id(), substs)
|
||||
} else {
|
||||
Ty::new_opaque(tcx, def_id.to_def_id(), substs)
|
||||
};
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
}
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
|
@ -109,20 +109,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
if !tcx.lower_impl_trait_in_trait_to_assoc_ty()
|
||||
&& item.defaultness(tcx).has_value()
|
||||
&& tcx.impl_method_has_trait_impl_trait_tys(item.def_id)
|
||||
&& let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
table.values().copied().flat_map(|ty| {
|
||||
cgp::parameters_for(&ty.subst_identity(), true)
|
||||
}).collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Const => vec![],
|
||||
ty::AssocKind::Fn | ty::AssocKind::Const => vec![],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -56,7 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
||||
let crate_map = tcx.crate_variances(());
|
||||
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
|
||||
}
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
||||
DefKind::OpaqueTy => {
|
||||
return variance_of_opaque(tcx, item_def_id);
|
||||
}
|
||||
_ => {}
|
||||
@ -115,14 +115,6 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
|
||||
// at all for RPITITs.
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if self.tcx.is_impl_trait_in_trait(*def_id)
|
||||
&& !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
@ -824,7 +824,6 @@ fn should_encode_span(def_kind: DefKind) -> bool {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
@ -867,7 +866,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Generator => false,
|
||||
@ -902,7 +900,6 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
@ -939,7 +936,6 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
@ -966,7 +962,6 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Enum
|
||||
| DefKind::Union
|
||||
| DefKind::Impl { .. }
|
||||
@ -1033,7 +1028,6 @@ fn should_encode_variances(def_kind: DefKind) -> bool {
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Fn
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::AssocFn => true,
|
||||
@ -1083,7 +1077,6 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Field
|
||||
| DefKind::TyParam
|
||||
@ -1134,19 +1127,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
||||
}
|
||||
}
|
||||
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
|
||||
let assoc_item = tcx.associated_item(parent_def_id);
|
||||
match assoc_item.container {
|
||||
// Always encode an RPIT in an impl fn, since it always has a body
|
||||
ty::AssocItemContainer::ImplContainer => true,
|
||||
ty::AssocItemContainer::TraitContainer => {
|
||||
// Encode an RPIT for a trait only if the trait has a default body
|
||||
assoc_item.defaultness(tcx).has_value()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefKind::AssocTy => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
@ -1192,7 +1172,6 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::AssocConst
|
||||
@ -1235,7 +1214,6 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Impl { of_trait: false }
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Generator
|
||||
| DefKind::ConstParam
|
||||
@ -1268,7 +1246,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
||||
| DefKind::Static(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::AssocFn
|
||||
@ -1289,11 +1266,8 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
// We only encode impl trait in trait when using `lower-impl-trait-in-trait-to-assoc-ty` unstable
|
||||
// option.
|
||||
fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty()
|
||||
&& let Some(assoc_item) = tcx.opt_associated_item(def_id)
|
||||
if let Some(assoc_item) = tcx.opt_associated_item(def_id)
|
||||
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
|
||||
&& assoc_item.kind == ty::AssocKind::Fn
|
||||
{
|
||||
@ -1447,9 +1421,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
.is_type_alias_impl_trait
|
||||
.set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
|
||||
}
|
||||
if let DefKind::ImplTraitPlaceholder = def_kind {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
}
|
||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
|
@ -142,7 +142,6 @@ fixed_size_enum! {
|
||||
( AnonConst )
|
||||
( InlineConst )
|
||||
( OpaqueTy )
|
||||
( ImplTraitPlaceholder )
|
||||
( Field )
|
||||
( LifetimeParam )
|
||||
( GlobalAsm )
|
||||
|
@ -195,13 +195,7 @@ impl<'hir> Map<'hir> {
|
||||
ItemKind::Fn(..) => DefKind::Fn,
|
||||
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
||||
ItemKind::Mod(..) => DefKind::Mod,
|
||||
ItemKind::OpaqueTy(ref opaque) => {
|
||||
if opaque.in_trait && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
DefKind::ImplTraitPlaceholder
|
||||
} else {
|
||||
DefKind::OpaqueTy
|
||||
}
|
||||
}
|
||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||
ItemKind::Enum(..) => DefKind::Enum,
|
||||
ItemKind::Struct(..) => DefKind::Struct,
|
||||
|
@ -1036,7 +1036,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
scope_def_id: LocalDefId,
|
||||
) -> Vec<&'tcx hir::Ty<'tcx>> {
|
||||
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
|
||||
let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
|
||||
let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
|
||||
self.hir().fn_decl_by_hir_id(hir_id)
|
||||
else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
@ -2002,16 +2004,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lower_impl_trait_in_trait_to_assoc_ty(self) -> bool {
|
||||
self.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty
|
||||
}
|
||||
|
||||
pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
|
||||
if self.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
self.opt_rpitit_info(def_id).is_some()
|
||||
} else {
|
||||
self.def_kind(def_id) == DefKind::ImplTraitPlaceholder
|
||||
}
|
||||
self.opt_rpitit_info(def_id).is_some()
|
||||
}
|
||||
|
||||
/// Named module children from all kinds of items, including imports.
|
||||
|
@ -2688,7 +2688,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
| Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) => fn_def_id,
|
||||
None => {
|
||||
while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
|
||||
debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
|
||||
def_id = self.parent(def_id);
|
||||
}
|
||||
def_id
|
||||
@ -2720,26 +2719,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
|
||||
|
||||
if self.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
return !self
|
||||
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
||||
.is_empty();
|
||||
}
|
||||
|
||||
// FIXME(RPITIT): This does a somewhat manual walk through the signature
|
||||
// of the trait fn to look for any RPITITs, but that's kinda doing a lot
|
||||
// of work. We can probably remove this when we refactor RPITITs to be
|
||||
// associated types.
|
||||
self.fn_sig(trait_item_def_id).subst_identity().skip_binder().output().walk().any(|arg| {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Alias(ty::Projection, data) = ty.kind()
|
||||
&& self.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
return !self
|
||||
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
||||
.is_empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,15 +567,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
||||
|
||||
// Alias tend to mostly already be handled downstream due to normalization.
|
||||
(&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => {
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This if can be removed
|
||||
// and the assert uncommented once the new desugaring is stable.
|
||||
if a_kind == b_kind {
|
||||
let alias_ty = relation.relate(a_data, b_data)?;
|
||||
// assert_eq!(a_kind, b_kind);
|
||||
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
||||
} else {
|
||||
Err(TypeError::Sorts(expected_found(relation, a, b)))
|
||||
}
|
||||
let alias_ty = relation.relate(a_data, b_data)?;
|
||||
assert_eq!(a_kind, b_kind);
|
||||
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
||||
}
|
||||
|
||||
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
|
||||
|
@ -1237,7 +1237,7 @@ impl<'tcx> AliasTy<'tcx> {
|
||||
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
|
||||
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
|
||||
DefKind::AssocTy => ty::Projection,
|
||||
DefKind::OpaqueTy => ty::Opaque,
|
||||
DefKind::TyAlias => ty::Weak,
|
||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
||||
@ -1265,9 +1265,6 @@ impl<'tcx> AliasTy<'tcx> {
|
||||
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id))
|
||||
}
|
||||
kind => bug!("expected a projection AliasTy; found {kind:?}"),
|
||||
}
|
||||
}
|
||||
@ -1970,7 +1967,6 @@ impl<'tcx> Ty<'tcx> {
|
||||
(kind, tcx.def_kind(alias_ty.def_id)),
|
||||
(ty::Opaque, DefKind::OpaqueTy)
|
||||
| (ty::Projection | ty::Inherent, DefKind::AssocTy)
|
||||
| (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
|
||||
| (ty::Weak, DefKind::TyAlias)
|
||||
);
|
||||
Ty::new(tcx, Alias(kind, alias_ty))
|
||||
|
@ -163,7 +163,6 @@ fn mark_used_by_default_parameters<'tcx>(
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
@ -694,7 +694,6 @@ impl CheckAttrVisitor<'_> {
|
||||
| Target::GlobalAsm
|
||||
| Target::TyAlias
|
||||
| Target::OpaqueTy
|
||||
| Target::ImplTraitPlaceholder
|
||||
| Target::Enum
|
||||
| Target::Variant
|
||||
| Target::Struct
|
||||
|
@ -136,19 +136,7 @@ where
|
||||
|
||||
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
let tcx = self.def_id_visitor.tcx();
|
||||
let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id)
|
||||
!= DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
projection.trait_ref_and_own_substs(tcx)
|
||||
} else {
|
||||
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
|
||||
let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id);
|
||||
let trait_generics = tcx.generics_of(def_id);
|
||||
(
|
||||
ty::TraitRef::new(tcx, def_id, projection.substs.truncate_to(tcx, trait_generics)),
|
||||
&projection.substs[trait_generics.count()..],
|
||||
)
|
||||
};
|
||||
let (trait_ref, assoc_substs) = projection.trait_ref_and_own_substs(tcx);
|
||||
self.visit_trait(trait_ref)?;
|
||||
if V::SHALLOW {
|
||||
ControlFlow::Continue(())
|
||||
@ -651,7 +639,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Fn
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::AssocFn
|
||||
| DefKind::Trait
|
||||
| DefKind::TyParam
|
||||
|
@ -949,7 +949,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
|
@ -1583,9 +1583,6 @@ options! {
|
||||
"what location details should be tracked when using caller_location, either \
|
||||
`none`, or a comma separated list of location details, for which \
|
||||
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
||||
lower_impl_trait_in_trait_to_assoc_ty: bool = (false, parse_bool, [TRACKED],
|
||||
"modify the lowering strategy for `impl Trait` in traits so that they are lowered to \
|
||||
generic associated types"),
|
||||
ls: bool = (false, parse_bool, [UNTRACKED],
|
||||
"list the symbols defined by a library crate (default: no)"),
|
||||
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
@ -131,8 +131,6 @@ enum ProjectionCandidate<'tcx> {
|
||||
|
||||
/// From an "impl" (or a "pseudo-impl" returned by select)
|
||||
Select(Selection<'tcx>),
|
||||
|
||||
ImplTraitInTrait(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
|
||||
}
|
||||
|
||||
enum ProjectionCandidateSet<'tcx> {
|
||||
@ -1472,8 +1470,6 @@ fn project<'cx, 'tcx>(
|
||||
|
||||
let mut candidates = ProjectionCandidateSet::None;
|
||||
|
||||
assemble_candidate_for_impl_trait_in_trait(selcx, obligation, &mut candidates);
|
||||
|
||||
// Make sure that the following procedures are kept in order. ParamEnv
|
||||
// needs to be first because it has highest priority, and Select checks
|
||||
// the return value of push_candidate which assumes it's ran at last.
|
||||
@ -1499,7 +1495,7 @@ fn project<'cx, 'tcx>(
|
||||
ProjectionCandidateSet::None => {
|
||||
let tcx = selcx.tcx();
|
||||
let term = match tcx.def_kind(obligation.predicate.def_id) {
|
||||
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => Ty::new_projection(
|
||||
DefKind::AssocTy => Ty::new_projection(
|
||||
tcx,
|
||||
obligation.predicate.def_id,
|
||||
obligation.predicate.substs,
|
||||
@ -1530,47 +1526,6 @@ fn project<'cx, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
/// If the predicate's item is an `ImplTraitPlaceholder`, we do a select on the
|
||||
/// corresponding trait ref. If this yields an `impl`, then we're able to project
|
||||
/// to a concrete type, since we have an `impl`'s method to provide the RPITIT.
|
||||
fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
let tcx = selcx.tcx();
|
||||
if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
|
||||
let trait_def_id = tcx.parent(trait_fn_def_id);
|
||||
let trait_substs =
|
||||
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
|
||||
let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs);
|
||||
|
||||
let _ = selcx.infcx.commit_if_ok(|_| {
|
||||
match selcx.select(&obligation.with(tcx, trait_predicate)) {
|
||||
Ok(Some(super::ImplSource::UserDefined(data))) => {
|
||||
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data));
|
||||
Ok(())
|
||||
}
|
||||
Ok(None) => {
|
||||
candidate_set.mark_ambiguous();
|
||||
Err(())
|
||||
}
|
||||
Ok(Some(_)) => {
|
||||
// Don't know enough about the impl to provide a useful signature
|
||||
Err(())
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(error = ?e, "selection error");
|
||||
candidate_set.mark_error(e);
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// The first thing we have to do is scan through the parameter
|
||||
/// environment to see whether there are any projection predicates
|
||||
/// there that can answer this question.
|
||||
@ -1739,11 +1694,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
// Can't assemble candidate from impl for RPITIT
|
||||
if selcx.tcx().def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
|
||||
// start out by selecting the predicate `T as TraitRef<...>`:
|
||||
let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
|
||||
@ -2012,9 +1962,6 @@ fn confirm_candidate<'cx, 'tcx>(
|
||||
ProjectionCandidate::Select(impl_source) => {
|
||||
confirm_select_candidate(selcx, obligation, impl_source)
|
||||
}
|
||||
ProjectionCandidate::ImplTraitInTrait(data) => {
|
||||
confirm_impl_trait_in_trait_candidate(selcx, obligation, data)
|
||||
}
|
||||
};
|
||||
|
||||
// When checking for cycle during evaluation, we compare predicates with
|
||||
@ -2240,8 +2187,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let ty::Closure(_, substs) =
|
||||
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
let ty::Closure(_, substs) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
@ -2419,103 +2365,6 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
data: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
let mut obligations = data.nested;
|
||||
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
|
||||
Ok(assoc_ty) => assoc_ty,
|
||||
Err(guar) => return Progress::error(tcx, guar),
|
||||
};
|
||||
// We don't support specialization for RPITITs anyways... yet.
|
||||
// Also don't try to project to an RPITIT that has no value
|
||||
if !leaf_def.is_final() || !leaf_def.item.defaultness(tcx).has_value() {
|
||||
return Progress { term: Ty::new_misc_error(tcx).into(), obligations };
|
||||
}
|
||||
|
||||
// Use the default `impl Trait` for the trait, e.g., for a default trait body
|
||||
if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
|
||||
return Progress {
|
||||
term: Ty::new_opaque(tcx, obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
obligations,
|
||||
};
|
||||
}
|
||||
|
||||
// Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque},
|
||||
// since `data.substs` are the impl substs.
|
||||
let impl_fn_substs =
|
||||
obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs);
|
||||
let impl_fn_substs = translate_substs(
|
||||
selcx.infcx,
|
||||
obligation.param_env,
|
||||
data.impl_def_id,
|
||||
impl_fn_substs,
|
||||
leaf_def.defining_node,
|
||||
);
|
||||
|
||||
if !check_substs_compatible(tcx, leaf_def.item, impl_fn_substs) {
|
||||
let err = Ty::new_error_with_message(
|
||||
tcx,
|
||||
obligation.cause.span,
|
||||
"impl method and trait method have different parameters",
|
||||
);
|
||||
return Progress { term: err.into(), obligations };
|
||||
}
|
||||
|
||||
let impl_fn_def_id = leaf_def.item.def_id;
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
super::ItemObligation(impl_fn_def_id),
|
||||
);
|
||||
let predicates = normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.extend(predicates.into_iter().map(|(pred, span)| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
if span.is_dummy() {
|
||||
super::ItemObligation(impl_fn_def_id)
|
||||
} else {
|
||||
super::BindingObligation(impl_fn_def_id, span)
|
||||
},
|
||||
),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
pred,
|
||||
)
|
||||
}));
|
||||
|
||||
let ty = normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
tcx.collect_return_position_impl_trait_in_trait_tys(impl_fn_def_id).map_or_else(
|
||||
|guar| Ty::new_error(tcx, guar),
|
||||
|tys| tys[&obligation.predicate.def_id].subst(tcx, impl_fn_substs),
|
||||
),
|
||||
&mut obligations,
|
||||
);
|
||||
|
||||
Progress { term: ty.into(), obligations }
|
||||
}
|
||||
|
||||
// Get obligations corresponding to the predicates from the where-clause of the
|
||||
// associated type itself.
|
||||
fn assoc_ty_own_obligations<'cx, 'tcx>(
|
||||
|
@ -24,70 +24,54 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
|
||||
let item = tcx.hir().expect_item(def_id);
|
||||
match item.kind {
|
||||
hir::ItemKind::Trait(.., ref trait_item_refs) => {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
// We collect RPITITs for each trait method's return type and create a
|
||||
// corresponding associated item using associated_types_for_impl_traits_in_associated_fn
|
||||
// query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
|
||||
.chain(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.filter(|trait_item_ref| {
|
||||
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|trait_item_ref| {
|
||||
let trait_fn_def_id =
|
||||
trait_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
trait_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
|
||||
)
|
||||
}
|
||||
// We collect RPITITs for each trait method's return type and create a
|
||||
// corresponding associated item using associated_types_for_impl_traits_in_associated_fn
|
||||
// query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
|
||||
.chain(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.filter(|trait_item_ref| {
|
||||
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|trait_item_ref| {
|
||||
let trait_fn_def_id = trait_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
trait_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id),
|
||||
),
|
||||
)
|
||||
}
|
||||
hir::ItemKind::Impl(ref impl_) => {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
// We collect RPITITs for each trait method's return type, on the impl side too and
|
||||
// create a corresponding associated item using
|
||||
// associated_types_for_impl_traits_in_associated_fn query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
|
||||
.chain(impl_.of_trait.iter().flat_map(|_| {
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.filter(|impl_item_ref| {
|
||||
matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|impl_item_ref| {
|
||||
let impl_fn_def_id =
|
||||
impl_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
impl_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id)
|
||||
})),
|
||||
)
|
||||
} else {
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
|
||||
)
|
||||
}
|
||||
// We collect RPITITs for each trait method's return type, on the impl side too and
|
||||
// create a corresponding associated item using
|
||||
// associated_types_for_impl_traits_in_associated_fn query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
|
||||
.chain(impl_.of_trait.iter().flat_map(|_| {
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.filter(|impl_item_ref| {
|
||||
matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|impl_item_ref| {
|
||||
let impl_fn_def_id = impl_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
impl_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id)
|
||||
})),
|
||||
)
|
||||
}
|
||||
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
@ -318,7 +318,6 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
|
||||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
@ -282,11 +282,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||
// If we're lowering to associated item, install the opaque type which is just
|
||||
// the `type_of` of the trait's associated item. If we're using the old lowering
|
||||
// strategy, then just reinterpret the associated type like an opaque :^)
|
||||
let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
self.tcx.type_of(shifted_alias_ty.def_id).subst(self.tcx, shifted_alias_ty.substs)
|
||||
} else {
|
||||
Ty::new_alias(self.tcx,ty::Opaque, shifted_alias_ty)
|
||||
};
|
||||
let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).subst(self.tcx, shifted_alias_ty.substs);
|
||||
|
||||
self.predicates.push(
|
||||
ty::Binder::bind_with_vars(
|
||||
@ -408,9 +404,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32
|
||||
};
|
||||
|
||||
// The last field of the structure has to exist and contain type/const parameters.
|
||||
let Some((tail_field, prefix_fields)) =
|
||||
def.non_enum_variant().fields.raw.split_last() else
|
||||
{
|
||||
let Some((tail_field, prefix_fields)) = def.non_enum_variant().fields.raw.split_last() else {
|
||||
return BitSet::new_empty(num_params);
|
||||
};
|
||||
|
||||
|
@ -136,7 +136,6 @@ impl From<DefKind> for ItemType {
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
@ -1860,8 +1860,8 @@ fn resolution_failure(
|
||||
}
|
||||
return;
|
||||
}
|
||||
Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder
|
||||
| TraitAlias | TyParam | Static(_) => "associated item",
|
||||
Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
|
||||
| Static(_) => "associated item",
|
||||
Impl { .. } | GlobalAsm => unreachable!("not a path"),
|
||||
}
|
||||
} else {
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_type_notation, async_fn_in_trait)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
|
@ -0,0 +1,48 @@
|
||||
error: return type notation uses `()` instead of `(..)` for elided arguments
|
||||
--> $DIR/bad-inputs-and-output.rs:18:24
|
||||
|
|
||||
LL | fn baz<T: Trait<method(..): Send>>() {}
|
||||
| ^^ help: remove the `..`
|
||||
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/bad-inputs-and-output.rs:10:17
|
||||
|
|
||||
LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/bad-inputs-and-output.rs:14:17
|
||||
|
|
||||
LL | fn bar<T: Trait<method() -> (): Send>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/bad-inputs-and-output.rs:3:12
|
||||
|
|
||||
LL | #![feature(return_type_notation, async_fn_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: argument types not allowed with return type notation
|
||||
--> $DIR/bad-inputs-and-output.rs:10:23
|
||||
|
|
||||
LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||
| ^^^^^ help: remove the input types: `()`
|
||||
|
||||
error: return type not allowed with return type notation
|
||||
--> $DIR/bad-inputs-and-output.rs:14:25
|
||||
|
|
||||
LL | fn bar<T: Trait<method() -> (): Send>>() {}
|
||||
| ^^^^^^ help: remove the return type
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,9 +1,6 @@
|
||||
// revisions: current_with current_without next_with next_without
|
||||
// [next_with] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// [next_without] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: with without
|
||||
// edition: 2021
|
||||
// [current_with] check-pass
|
||||
// [next_with] check-pass
|
||||
// [with] check-pass
|
||||
|
||||
#![feature(return_type_notation, async_fn_in_trait)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
@ -20,12 +17,11 @@ async fn foo<T: Foo>() -> Result<(), ()> {
|
||||
fn is_send(_: impl Send) {}
|
||||
|
||||
fn test<
|
||||
#[cfg(any(current_with, next_with))] T: Foo<method(): Send>,
|
||||
#[cfg(any(current_without, next_without))] T: Foo,
|
||||
#[cfg(with)] T: Foo<method(): Send>,
|
||||
#[cfg(without)] T: Foo,
|
||||
>() {
|
||||
is_send(foo::<T>());
|
||||
//[current_without]~^ ERROR future cannot be sent between threads safely
|
||||
//[next_without]~^^ ERROR future cannot be sent between threads safely
|
||||
//[without]~^ ERROR future cannot be sent between threads safely
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_type_notation, async_fn_in_trait)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
|
@ -0,0 +1,17 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/equality.rs:3:12
|
||||
|
|
||||
LL | #![feature(return_type_notation, async_fn_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: return type notation is not allowed to use type equality
|
||||
--> $DIR/equality.rs:12:18
|
||||
|
|
||||
LL | fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition:2015
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
|
||||
|
||||
|
98
tests/ui/async-await/edition-deny-async-fns-2015.stderr
Normal file
98
tests/ui/async-await/edition-deny-async-fns-2015.stderr
Normal file
@ -0,0 +1,98 @@
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:3:1
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:5:12
|
||||
|
|
||||
LL | fn baz() { async fn foo() {} }
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:7:1
|
||||
|
|
||||
LL | async fn async_baz() {
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:8:5
|
||||
|
|
||||
LL | async fn bar() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:14:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:18:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:36:9
|
||||
|
|
||||
LL | async fn bar() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:26:9
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0670]: `async fn` is not permitted in Rust 2015
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:31:13
|
||||
|
|
||||
LL | async fn bar() {}
|
||||
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
|
||||
|
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
error[E0706]: functions in traits cannot be declared `async`
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:18:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| -----^^^^^^^^^
|
||||
| |
|
||||
| `async` because of this
|
||||
|
|
||||
= note: `async` trait functions are not currently supported
|
||||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0670, E0706.
|
||||
For more information about an error, try `rustc --explain E0670`.
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(impl_trait_projections)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// run-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -0,0 +1,17 @@
|
||||
error[E0053]: method `foo` has an incompatible type for trait
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:15:28
|
||||
|
|
||||
LL | async fn foo(&self) -> i32 {
|
||||
| ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:11:22
|
||||
|
|
||||
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
|
||||
found signature `fn(&i32) -> impl Future<Output = i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error: method `foo` should be async because the method from the trait is async
|
||||
--> $DIR/async-example-desugared-boxed.rs:15:5
|
||||
|
|
||||
LL | async fn foo(&self) -> i32;
|
||||
| --------------------------- required because the trait method is async
|
||||
...
|
||||
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error: method `foo` should be async because the method from the trait is async
|
||||
--> $DIR/async-example-desugared-manual.rs:23:5
|
||||
|
|
||||
LL | async fn foo(&self) -> i32;
|
||||
| --------------------------- required because the trait method is async
|
||||
...
|
||||
LL | fn foo(&self) -> MyFuture {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-fail
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -0,0 +1,37 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:12:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:12:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0311`.
|
@ -1,8 +1,6 @@
|
||||
// check-fail
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
37
tests/ui/async-await/in-trait/async-generics.stderr
Normal file
37
tests/ui/async-await/in-trait/async-generics.stderr
Normal file
@ -0,0 +1,37 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:9:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:9:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0311`.
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
12
tests/ui/async-await/in-trait/async-recursive-generic.stderr
Normal file
12
tests/ui/async-await/in-trait/async-recursive-generic.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0733]: recursion in an `async fn` requires boxing
|
||||
--> $DIR/async-recursive-generic.rs:11:48
|
||||
|
|
||||
LL | async fn foo_recursive(&self, n: usize) -> T {
|
||||
| ^ recursive `async fn`
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0733`.
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
12
tests/ui/async-await/in-trait/async-recursive.stderr
Normal file
12
tests/ui/async-await/in-trait/async-recursive.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0733]: recursion in an `async fn` requires boxing
|
||||
--> $DIR/async-recursive.rs:11:48
|
||||
|
|
||||
LL | async fn foo_recursive(&self, n: usize) -> i32 {
|
||||
| ^^^ recursive `async fn`
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0733`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
17
tests/ui/async-await/in-trait/bad-signatures.stderr
Normal file
17
tests/ui/async-await/in-trait/bad-signatures.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error: expected identifier, found keyword `self`
|
||||
--> $DIR/bad-signatures.rs:6:23
|
||||
|
|
||||
LL | async fn bar(&abc self);
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found keyword `self`
|
||||
--> $DIR/bad-signatures.rs:6:23
|
||||
|
|
||||
LL | async fn bar(&abc self);
|
||||
| -----^^^^
|
||||
| | |
|
||||
| | expected one of `:`, `@`, or `|`
|
||||
| help: declare the type after the parameter binding: `<identifier>: <type>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
// known-bug: #108309
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(min_specialization)]
|
||||
|
@ -0,0 +1,25 @@
|
||||
error[E0053]: method `foo` has an incompatible type for trait
|
||||
--> $DIR/dont-project-to-specializable-projection.rs:14:35
|
||||
|
|
||||
LL | default async fn foo(_: T) -> &'static str {
|
||||
| ^^^^^^^^^^^^ expected associated type, found future
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/dont-project-to-specializable-projection.rs:10:27
|
||||
|
|
||||
LL | async fn foo(_: T) -> &'static str;
|
||||
| ^^^^^^^^^^^^
|
||||
= note: expected signature `fn(_) -> impl Future<Output = &'static str>`
|
||||
found signature `fn(_) -> impl Future<Output = &'static str>`
|
||||
|
||||
error: async associated function in trait cannot be specialized
|
||||
--> $DIR/dont-project-to-specializable-projection.rs:14:5
|
||||
|
|
||||
LL | default async fn foo(_: T) -> &'static str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
12
tests/ui/async-await/in-trait/fn-not-async-err2.stderr
Normal file
12
tests/ui/async-await/in-trait/fn-not-async-err2.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
|
||||
--> $DIR/fn-not-async-err2.rs:13:22
|
||||
|
|
||||
LL | fn foo(&self) -> impl Future<Output = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0562`.
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,8 +1,6 @@
|
||||
// compile-flags:--crate-type=lib
|
||||
// edition:2021
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition:2021
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
12
tests/ui/async-await/in-trait/lifetime-mismatch.stderr
Normal file
12
tests/ui/async-await/in-trait/lifetime-mismatch.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
|
||||
--> $DIR/lifetime-mismatch.rs:11:17
|
||||
|
|
||||
LL | async fn foo<'a>(&self);
|
||||
| ---- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | async fn foo(&self) {}
|
||||
| ^ lifetimes do not match method in trait
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0195`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2018
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(min_specialization)]
|
||||
|
30
tests/ui/async-await/in-trait/missing-feature-flag.stderr
Normal file
30
tests/ui/async-await/in-trait/missing-feature-flag.stderr
Normal file
@ -0,0 +1,30 @@
|
||||
error[E0046]: not all trait items implemented, missing: `foo`
|
||||
--> $DIR/missing-feature-flag.rs:12:1
|
||||
|
|
||||
LL | async fn foo(_: T) -> &'static str;
|
||||
| ----------------------------------- `foo` from trait
|
||||
...
|
||||
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
|
||||
|
||||
error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
|
||||
--> $DIR/missing-feature-flag.rs:16:5
|
||||
|
|
||||
LL | impl<T> MyTrait<T> for MyStruct {}
|
||||
| ------------------------------- parent `impl` is here
|
||||
...
|
||||
LL | async fn foo(_: i32) -> &'static str {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
|
||||
|
|
||||
= note: to specialize, `foo` in the parent `impl` must be marked `default`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-feature-flag.rs:16:42
|
||||
|
|
||||
LL | async fn foo(_: i32) -> &'static str {}
|
||||
| ^^ expected `&str`, found `()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0308, E0520.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
20
tests/ui/async-await/in-trait/missing-send-bound.stderr
Normal file
20
tests/ui/async-await/in-trait/missing-send-bound.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: future cannot be sent between threads safely
|
||||
--> $DIR/missing-send-bound.rs:14:20
|
||||
|
|
||||
LL | assert_is_send(test::<T>());
|
||||
| ^^^^^^^^^^^ future returned by `test` is not `Send`
|
||||
|
|
||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
|
||||
note: future is not `Send` as it awaits another future which is not `Send`
|
||||
--> $DIR/missing-send-bound.rs:10:5
|
||||
|
|
||||
LL | T::bar().await;
|
||||
| ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
|
||||
note: required by a bound in `assert_is_send`
|
||||
--> $DIR/missing-send-bound.rs:18:27
|
||||
|
|
||||
LL | fn assert_is_send(_: impl Send) {}
|
||||
| ^^^^ required by this bound in `assert_is_send`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
18
tests/ui/async-await/in-trait/object-safety.stderr
Normal file
18
tests/ui/async-await/in-trait/object-safety.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:10:12
|
||||
|
|
||||
LL | let x: &dyn Foo = todo!();
|
||||
| ^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:6:14
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | async fn foo(&self);
|
||||
| ^^^ ...because method `foo` is `async`
|
||||
= help: consider moving `foo` to another trait
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/return-not-existing-pair.rs:10:20
|
||||
|
|
||||
LL | impl<'a, 'b, T, U> MyTrait<T> for U {
|
||||
| ^^^^^^^^^^ expected lifetime parameters
|
||||
|
|
||||
help: indicate the anonymous lifetimes
|
||||
|
|
||||
LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
|
||||
| +++++++
|
||||
|
||||
error[E0412]: cannot find type `ConnImpl` in this scope
|
||||
--> $DIR/return-not-existing-pair.rs:6:48
|
||||
|
|
||||
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
|
||||
--> $DIR/return-not-existing-pair.rs:12:5
|
||||
|
|
||||
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
|
||||
| ------------------------------------------------------------ `&self` used in trait
|
||||
...
|
||||
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-not-existing-pair.rs:12:42
|
||||
|
|
||||
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
|
||||
| ^^ expected `(&U, &T)`, found `()`
|
||||
|
|
||||
= note: expected tuple `(&'a U, &'b T)`
|
||||
found unit type `()`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0186, E0308, E0412, E0726.
|
||||
For more information about an error, try `rustc --explain E0186`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
error[E0412]: cannot find type `Missing` in this scope
|
||||
--> $DIR/return-not-existing-type-wrapping-rpitit.rs:8:25
|
||||
|
|
||||
LL | fn bar() -> Wrapper<Missing<impl Sized>>;
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
||||
|
14
tests/ui/async-await/in-trait/return-type-suggestion.stderr
Normal file
14
tests/ui/async-await/in-trait/return-type-suggestion.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-type-suggestion.rs:7:9
|
||||
|
|
||||
LL | Ok(())
|
||||
| ^^^^^^- help: consider using a semicolon here: `;`
|
||||
| |
|
||||
| expected `()`, found `Result<(), _>`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<(), _>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
// known-bug: #110963
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_type_notation)]
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
@ -0,0 +1,37 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-110963-early.rs:4:12
|
||||
|
|
||||
LL | #![feature(return_type_notation)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: higher-ranked lifetime error
|
||||
--> $DIR/issue-110963-early.rs:15:5
|
||||
|
|
||||
LL | / spawn(async move {
|
||||
LL | | let mut hc = hc;
|
||||
LL | | if !hc.check().await {
|
||||
LL | | log_health_check_failure().await;
|
||||
LL | | }
|
||||
LL | | });
|
||||
| |______^
|
||||
|
|
||||
= note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
|
||||
|
||||
error: higher-ranked lifetime error
|
||||
--> $DIR/issue-110963-early.rs:15:5
|
||||
|
|
||||
LL | / spawn(async move {
|
||||
LL | | let mut hc = hc;
|
||||
LL | | if !hc.check().await {
|
||||
LL | | log_health_check_failure().await;
|
||||
LL | | }
|
||||
LL | | });
|
||||
| |______^
|
||||
|
|
||||
= note: could not prove `[async block@$DIR/issue-110963-early.rs:15:11: 20:6]: Send`
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_type_notation)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-110963-late.rs:4:12
|
||||
|
|
||||
LL | #![feature(return_type_notation)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition:2021
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait, return_type_notation)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/super-method-bound.rs:4:31
|
||||
|
|
||||
LL | #![feature(async_fn_in_trait, return_type_notation)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,6 +1,4 @@
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait, return_type_notation)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete and may not be safe to use
|
||||
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/supertrait-bound.rs:3:49
|
||||
|
|
||||
LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,6 +1,4 @@
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait, return_type_notation)]
|
||||
//~^ WARN the feature `return_type_notation` is incomplete
|
||||
|
@ -0,0 +1,29 @@
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/ty-or-ct-params.rs:3:31
|
||||
|
|
||||
LL | #![feature(async_fn_in_trait, return_type_notation)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: return type notation is not allowed for functions that have type parameters
|
||||
--> $DIR/ty-or-ct-params.rs:14:12
|
||||
|
|
||||
LL | async fn bar<T>() {}
|
||||
| - type parameter declared here
|
||||
...
|
||||
LL | T: Foo<bar(): Send, baz(): Send>,
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: return type notation is not allowed for functions that have const parameters
|
||||
--> $DIR/ty-or-ct-params.rs:14:25
|
||||
|
|
||||
LL | async fn baz<const N: usize>() {}
|
||||
| -------------- const parameter declared here
|
||||
...
|
||||
LL | T: Foo<bar(): Send, baz(): Send>,
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
@ -1,10 +1,7 @@
|
||||
// edition: 2021
|
||||
// revisions: cfg_current cfg_next no_current no_next
|
||||
// [cfg_next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// [no_next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: cfg no
|
||||
|
||||
// [no_current] check-pass
|
||||
// [no_next] check-pass
|
||||
// [no] check-pass
|
||||
// Since we're not adding new syntax, `cfg`'d out RTN must pass.
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
@ -13,17 +10,12 @@ trait Trait {
|
||||
async fn m();
|
||||
}
|
||||
|
||||
#[cfg(any(cfg_current, cfg_next))]
|
||||
#[cfg(cfg)]
|
||||
fn foo<T: Trait<m(): Send>>() {}
|
||||
//[cfg_current]~^ ERROR return type notation is experimental
|
||||
//[cfg_current]~| ERROR parenthesized generic arguments cannot be used in associated type constraints
|
||||
//[cfg_current]~| ERROR associated type `m` not found for `Trait`
|
||||
//[cfg_next]~^^^^ ERROR return type notation is experimental
|
||||
//[cfg_next]~| ERROR parenthesized generic arguments cannot be used in associated type constraints
|
||||
//[cfg_next]~| ERROR associated type `m` not found for `Trait`
|
||||
//[no_current]~^^^^^^^ WARN return type notation is experimental
|
||||
//[no_current]~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
||||
//[no_next]~^^^^^^^^^ WARN return type notation is experimental
|
||||
//[no_next]~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
||||
//[cfg]~^ ERROR return type notation is experimental
|
||||
//[cfg]~| ERROR parenthesized generic arguments cannot be used in associated type constraints
|
||||
//[cfg]~| ERROR associated type `m` not found for `Trait`
|
||||
//[no]~^^^^ WARN return type notation is experimental
|
||||
//[no]~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,3 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
use std::ops::Deref;
|
||||
@ -10,5 +8,7 @@ pub trait Foo {
|
||||
|
||||
pub struct Foreign;
|
||||
impl Foo for Foreign {
|
||||
fn bar(self) -> &'static () { &() }
|
||||
fn bar(self) -> &'static () {
|
||||
&()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,6 +1,3 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
15
tests/ui/impl-trait/in-trait/deep-match.stderr
Normal file
15
tests/ui/impl-trait/in-trait/deep-match.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0053]: method `bar` has an incompatible return type for trait
|
||||
--> $DIR/deep-match.rs:11:17
|
||||
|
|
||||
LL | fn bar() -> i32 {
|
||||
| ^^^
|
||||
| |
|
||||
| expected `Wrapper<_>`, found `i32`
|
||||
| return type in trait
|
||||
|
|
||||
= note: expected struct `Wrapper<_>`
|
||||
found type `i32`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -1,6 +1,4 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
11
tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr
Normal file
11
tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/default-body-type-err-2.rs:8:9
|
||||
|
|
||||
LL | 42
|
||||
| ^^- help: try using a conversion method: `.to_string()`
|
||||
| |
|
||||
| expected `String`, found integer
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,6 +1,3 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user