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:
bors 2023-07-10 19:01:30 +00:00
commit 8ca44ef9ca
146 changed files with 1106 additions and 586 deletions

View File

@ -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

View File

@ -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",

View File

@ -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()

View File

@ -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);

View File

@ -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(..), .. }) => &[],

View File

@ -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();

View File

@ -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),
}
}

View File

@ -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)
{

View File

@ -142,7 +142,6 @@ fixed_size_enum! {
( AnonConst )
( InlineConst )
( OpaqueTy )
( ImplTraitPlaceholder )
( Field )
( LifetimeParam )
( GlobalAsm )

View File

@ -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,

View File

@ -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.

View File

@ -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();
}
}

View File

@ -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))),

View File

@ -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))

View File

@ -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

View File

@ -694,7 +694,6 @@ impl CheckAttrVisitor<'_> {
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
| Target::ImplTraitPlaceholder
| Target::Enum
| Target::Variant
| Target::Struct

View File

@ -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

View File

@ -949,7 +949,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
| DefKind::TraitAlias
| DefKind::AssocTy,
_,

View File

@ -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],

View File

@ -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>(

View File

@ -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"),
}

View File

@ -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

View File

@ -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

View File

@ -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);
};

View File

@ -136,7 +136,6 @@ impl From<DefKind> for ItemType {
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::ImplTraitPlaceholder
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm

View File

@ -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 {

View File

@ -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

View File

@ -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`.

View File

@ -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() {}

View File

@ -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

View File

@ -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

View File

@ -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

View 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`.

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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`.

View File

@ -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)]

View File

@ -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

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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

View File

@ -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)]

View File

@ -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)]

View File

@ -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`.

View File

@ -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)]

View 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`.

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View 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`.

View File

@ -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)]

View 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`.

View File

@ -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)]

View 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

View File

@ -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)]

View File

@ -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`.

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View 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`.

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View 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`.

View File

@ -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)]

View 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`.

View File

@ -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)]

View 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

View File

@ -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)]

View 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`.

View File

@ -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)]

View File

@ -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`.

View File

@ -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)]

View File

@ -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`.

View File

@ -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)]

View 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`.

View File

@ -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)]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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() {}

View File

@ -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 () {
&()
}
}

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View 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`.

View File

@ -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)]

View 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`.

View File

@ -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