Rollup merge of #79554 - b-naber:generic-associated-types-in-trait-paths, r=jackh726
Generic associated types in trait paths This is the second part of https://github.com/rust-lang/rust/pull/78978 This should fix: Fixes #67510 Fixes #68648 Fixes #68649 Fixes #68650 Fixes #68652 Fixes #74684 Fixes #76535 Fixes #79422 Fixes #80433 and implement the remaining functionality needed for https://github.com/rust-lang/rust/issues/44265 r? ``@matthewjasper``
This commit is contained in:
commit
deec6a96d4
@ -1076,16 +1076,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_assoc_ty_constraint(
|
||||
&mut self,
|
||||
constraint: &AssocTyConstraint,
|
||||
itctx: ImplTraitContext<'_, 'hir>,
|
||||
mut itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> hir::TypeBinding<'hir> {
|
||||
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
|
||||
|
||||
if let Some(ref gen_args) = constraint.gen_args {
|
||||
self.sess.span_fatal(
|
||||
gen_args.span(),
|
||||
"generic associated types in trait paths are currently not implemented",
|
||||
);
|
||||
// lower generic arguments of identifier in constraint
|
||||
let gen_args = if let Some(ref gen_args) = constraint.gen_args {
|
||||
let gen_args_ctor = match gen_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
self.lower_angle_bracketed_parameter_data(
|
||||
data,
|
||||
ParamMode::Explicit,
|
||||
itctx.reborrow(),
|
||||
)
|
||||
.0
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => {
|
||||
let mut err = self.sess.struct_span_err(
|
||||
gen_args.span(),
|
||||
"parenthesized generic arguments cannot be used in associated type constraints"
|
||||
);
|
||||
// FIXME: try to write a suggestion here
|
||||
err.emit();
|
||||
self.lower_angle_bracketed_parameter_data(
|
||||
&data.as_angle_bracketed_args(),
|
||||
ParamMode::Explicit,
|
||||
itctx.reborrow(),
|
||||
)
|
||||
.0
|
||||
}
|
||||
};
|
||||
self.arena.alloc(gen_args_ctor.into_generic_args(&self.arena))
|
||||
} else {
|
||||
self.arena.alloc(hir::GenericArgs::none())
|
||||
};
|
||||
|
||||
let kind = match constraint.kind {
|
||||
AssocTyConstraintKind::Equality { ref ty } => {
|
||||
@ -1182,6 +1206,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
hir::TypeBinding {
|
||||
hir_id: self.lower_node_id(constraint.id),
|
||||
ident: constraint.ident,
|
||||
gen_args,
|
||||
kind,
|
||||
span: constraint.span,
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_angle_bracketed_parameter_data(
|
||||
pub(crate) fn lower_angle_bracketed_parameter_data(
|
||||
&mut self,
|
||||
data: &AngleBracketedArgs,
|
||||
param_mode: ParamMode,
|
||||
@ -426,6 +426,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
) -> hir::TypeBinding<'hir> {
|
||||
let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME);
|
||||
let kind = hir::TypeBindingKind::Equality { ty };
|
||||
hir::TypeBinding { hir_id: self.next_id(), span, ident, kind }
|
||||
let args = arena_vec![self;];
|
||||
let bindings = arena_vec![self;];
|
||||
let gen_args = self.arena.alloc(hir::GenericArgs { args, bindings, parenthesized: false });
|
||||
hir::TypeBinding { hir_id: self.next_id(), gen_args, span, ident, kind }
|
||||
}
|
||||
}
|
||||
|
@ -2015,6 +2015,7 @@ pub struct TypeBinding<'hir> {
|
||||
pub hir_id: HirId,
|
||||
#[stable_hasher(project(name))]
|
||||
pub ident: Ident,
|
||||
pub gen_args: &'hir GenericArgs<'hir>,
|
||||
pub kind: TypeBindingKind<'hir>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -781,6 +781,7 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
|
||||
) {
|
||||
visitor.visit_id(type_binding.hir_id);
|
||||
visitor.visit_ident(type_binding.ident);
|
||||
visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
|
||||
match type_binding.kind {
|
||||
TypeBindingKind::Equality { ref ty } => {
|
||||
visitor.visit_ty(ty);
|
||||
|
@ -1840,6 +1840,7 @@ impl<'a> State<'a> {
|
||||
for binding in generic_args.bindings.iter() {
|
||||
start_or_comma(self);
|
||||
self.print_ident(binding.ident);
|
||||
self.print_generic_args(binding.gen_args, false, false);
|
||||
self.s.space();
|
||||
match generic_args.bindings[0].kind {
|
||||
hir::TypeBindingKind::Equality { ref ty } => {
|
||||
|
@ -1132,8 +1132,16 @@ impl<'tcx> ProjectionTy<'tcx> {
|
||||
/// For example, if this is a projection of `<T as Iterator>::Item`,
|
||||
/// then this function would return a `T: Iterator` trait reference.
|
||||
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
|
||||
// FIXME: This method probably shouldn't exist at all, since it's not
|
||||
// clear what this method really intends to do. Be careful when
|
||||
// using this method since the resulting TraitRef additionally
|
||||
// contains the substs for the assoc_item, which strictly speaking
|
||||
// is not correct
|
||||
let def_id = tcx.associated_item(self.item_def_id).container.id();
|
||||
ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) }
|
||||
// Include substitutions for generic arguments of associated types
|
||||
let assoc_item = tcx.associated_item(self.item_def_id);
|
||||
let substs_assoc_item = self.substs.truncate_to(tcx, tcx.generics_of(assoc_item.def_id));
|
||||
ty::TraitRef { def_id, substs: substs_assoc_item }
|
||||
}
|
||||
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
|
@ -257,13 +257,11 @@ fn predicates_reference_self(
|
||||
}
|
||||
|
||||
fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> {
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
|
||||
tcx.associated_items(trait_def_id)
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
.flat_map(|item| tcx.explicit_item_bounds(item.def_id))
|
||||
.map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp))
|
||||
.filter_map(|predicate| predicate_references_self(tcx, predicate))
|
||||
.filter_map(|pred_span| predicate_references_self(tcx, *pred_span))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -112,12 +112,15 @@ pub enum SizedByDefault {
|
||||
No,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ConvertedBinding<'a, 'tcx> {
|
||||
item_name: Ident,
|
||||
kind: ConvertedBindingKind<'a, 'tcx>,
|
||||
gen_args: &'a GenericArgs<'a>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ConvertedBindingKind<'a, 'tcx> {
|
||||
Equality(Ty<'tcx>),
|
||||
Constraint(&'a [hir::GenericBound<'a>]),
|
||||
@ -323,6 +326,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let tcx = self.tcx();
|
||||
let generics = tcx.generics_of(def_id);
|
||||
debug!("generics: {:?}", generics);
|
||||
|
||||
if generics.has_self {
|
||||
if generics.parent.is_some() {
|
||||
@ -557,7 +561,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
ConvertedBindingKind::Constraint(bounds)
|
||||
}
|
||||
};
|
||||
ConvertedBinding { item_name: binding.ident, kind, span: binding.span }
|
||||
ConvertedBinding {
|
||||
item_name: binding.ident,
|
||||
kind,
|
||||
gen_args: binding.gen_args,
|
||||
span: binding.span,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
@ -918,9 +927,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
dup_bindings: &mut FxHashMap<DefId, Span>,
|
||||
path_span: Span,
|
||||
) -> Result<(), ErrorReported> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
if !speculative {
|
||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
||||
// subtle in the event that `T` is defined in a supertrait of
|
||||
@ -937,41 +943,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||
|
||||
// Find any late-bound regions declared in `ty` that are not
|
||||
// declared in the trait-ref. These are not well-formed.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||
if let ConvertedBindingKind::Equality(ty) = binding.kind {
|
||||
let late_bound_in_trait_ref =
|
||||
tcx.collect_constrained_late_bound_regions(&trait_ref);
|
||||
let late_bound_in_ty =
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
|
||||
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
|
||||
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
|
||||
|
||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
// ---- ---- ^^^^^^^
|
||||
self.validate_late_bound_regions(
|
||||
late_bound_in_trait_ref,
|
||||
late_bound_in_ty,
|
||||
|br_name| {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
binding.span,
|
||||
E0582,
|
||||
"binding for associated type `{}` references {}, \
|
||||
which does not appear in the trait input types",
|
||||
binding.item_name,
|
||||
br_name
|
||||
)
|
||||
},
|
||||
debug!(
|
||||
"add_predicates_for_ast_type_binding(hir_ref_id {:?}, trait_ref {:?}, binding {:?}, bounds {:?}",
|
||||
hir_ref_id, trait_ref, binding, bounds
|
||||
);
|
||||
}
|
||||
}
|
||||
let tcx = self.tcx();
|
||||
|
||||
let candidate =
|
||||
if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
|
||||
@ -1030,6 +1006,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.or_insert(binding.span);
|
||||
}
|
||||
|
||||
// Include substitutions for generic parameters of associated types
|
||||
let projection_ty = candidate.map_bound(|trait_ref| {
|
||||
let item_segment = hir::PathSegment {
|
||||
ident: assoc_ty.ident,
|
||||
hir_id: None,
|
||||
res: None,
|
||||
args: Some(binding.gen_args),
|
||||
infer_args: false,
|
||||
};
|
||||
|
||||
let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item(
|
||||
tcx,
|
||||
path_span,
|
||||
assoc_ty.def_id,
|
||||
&item_segment,
|
||||
trait_ref.substs,
|
||||
);
|
||||
|
||||
debug!(
|
||||
"add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}",
|
||||
substs_trait_ref_and_assoc_item
|
||||
);
|
||||
|
||||
ty::ProjectionTy {
|
||||
item_def_id: assoc_ty.def_id,
|
||||
substs: substs_trait_ref_and_assoc_item,
|
||||
}
|
||||
});
|
||||
|
||||
if !speculative {
|
||||
// Find any late-bound regions declared in `ty` that are not
|
||||
// declared in the trait-ref or assoc_ty. These are not well-formed.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||
if let ConvertedBindingKind::Equality(ty) = binding.kind {
|
||||
let late_bound_in_trait_ref =
|
||||
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
||||
let late_bound_in_ty =
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
|
||||
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
|
||||
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
|
||||
|
||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
// ---- ---- ^^^^^^^
|
||||
self.validate_late_bound_regions(
|
||||
late_bound_in_trait_ref,
|
||||
late_bound_in_ty,
|
||||
|br_name| {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
binding.span,
|
||||
E0582,
|
||||
"binding for associated type `{}` references {}, \
|
||||
which does not appear in the trait input types",
|
||||
binding.item_name,
|
||||
br_name
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
match binding.kind {
|
||||
ConvertedBindingKind::Equality(ref ty) => {
|
||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
||||
@ -1037,13 +1079,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// `<T as Iterator>::Item = u32`
|
||||
bounds.projection_bounds.push((
|
||||
candidate.map_bound(|trait_ref| ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
trait_ref,
|
||||
binding.item_name,
|
||||
),
|
||||
ty,
|
||||
projection_ty.map_bound(|projection_ty| {
|
||||
debug!(
|
||||
"add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}",
|
||||
projection_ty, projection_ty.substs
|
||||
);
|
||||
ty::ProjectionPredicate { projection_ty, ty }
|
||||
}),
|
||||
binding.span,
|
||||
));
|
||||
@ -1055,7 +1096,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
|
||||
let param_ty =
|
||||
tcx.mk_projection(assoc_ty.def_id, projection_ty.skip_binder().substs);
|
||||
self.add_bounds(param_ty, ast_bounds, bounds);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'x>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
//~^ ERROR: use of undeclared lifetime name `'x`
|
||||
//~| ERROR: binding for associated type `Y` references lifetime
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'x`
|
||||
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:35
|
||||
|
|
||||
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'x` here: `<'x>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
|
||||
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:33
|
||||
|
|
||||
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0261, E0582.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
30
src/test/ui/generic-associated-types/gat-in-trait-path.rs
Normal file
30
src/test/ui/generic-associated-types/gat-in-trait-path.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
trait Foo {
|
||||
type A<'a> where Self: 'a;
|
||||
}
|
||||
|
||||
struct Fooy;
|
||||
|
||||
impl Foo for Fooy {
|
||||
type A<'a> = &'a ();
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Fooer<T>(T);
|
||||
|
||||
impl<T> Foo for Fooer<T> {
|
||||
type A<'x> where T: 'x = &'x ();
|
||||
}
|
||||
|
||||
fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
||||
|
||||
|
||||
fn main() {
|
||||
let foo = Fooer(5);
|
||||
f(Box::new(foo));
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/gat-in-trait-path.rs:3:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -0,0 +1,16 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait Foo {
|
||||
type F<'a>;
|
||||
|
||||
fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T, T1> Foo for T {
|
||||
type F<T1> = &[u8];
|
||||
//~^ ERROR: the name `T1` is already used for
|
||||
//~| ERROR: missing lifetime specifier
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,32 @@
|
||||
error[E0403]: the name `T1` is already used for a generic parameter in this item's generic parameters
|
||||
--> $DIR/gat-trait-path-generic-type-arg.rs:11:12
|
||||
|
|
||||
LL | impl <T, T1> Foo for T {
|
||||
| -- first use of `T1`
|
||||
LL | type F<T1> = &[u8];
|
||||
| ^^ already used
|
||||
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/gat-trait-path-generic-type-arg.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/gat-trait-path-generic-type-arg.rs:11:18
|
||||
|
|
||||
LL | type F<T1> = &[u8];
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type F<'a, T1> = &'a [u8];
|
||||
| ^^^ ^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0106, E0403.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
@ -0,0 +1,18 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
//~^ ERROR missing generics for
|
||||
//~| ERROR missing generics for
|
||||
|
||||
fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
|
||||
}
|
||||
|
||||
impl<T> X for T {
|
||||
fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,44 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0107]: missing generics for associated type `X::Y`
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ --
|
||||
help: use angle brackets to add missing lifetime argument
|
||||
|
|
||||
LL | type Y<'a><'a>;
|
||||
| ^^^^
|
||||
|
||||
error[E0107]: missing generics for associated type `X::Y`
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ --
|
||||
help: use angle brackets to add missing lifetime argument
|
||||
|
|
||||
LL | type Y<'a><'a>;
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
@ -0,0 +1,15 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
//~^ ERROR this associated type
|
||||
//~| ERROR this associated type
|
||||
}
|
||||
|
||||
fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
//~^ ERROR: lifetime in trait object type must be followed by `+`
|
||||
//~| ERROR: parenthesized generic arguments cannot be used
|
||||
//~| WARNING: trait objects without an explicit `dyn` are deprecated
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,68 @@
|
||||
error: lifetime in trait object type must be followed by `+`
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:10:29
|
||||
|
|
||||
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
| ^^
|
||||
|
||||
error: parenthesized generic arguments cannot be used in associated type constraints
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:10:27
|
||||
|
|
||||
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
| ^^^^^
|
||||
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:10:29
|
||||
|
|
||||
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
| ^^ help: use `dyn`: `dyn 'a`
|
||||
|
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
|
||||
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ --
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | fn foo<'a>(arg: Box<dyn X<Y('a'a) = &'a ()>>) {}
|
||||
| ^^
|
||||
|
||||
error[E0107]: this associated type takes 0 type arguments but 1 type argument was supplied
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ________^-
|
||||
| | |
|
||||
| | expected 0 type arguments
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | }
|
||||
LL | |
|
||||
LL | | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
| |_________________________________________- help: remove these generics
|
||||
|
|
||||
note: associated type defined here, with 0 type parameters
|
||||
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^
|
||||
|
||||
error: aborting due to 4 previous errors; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
12
src/test/ui/generic-associated-types/issue-67510-pass.rs
Normal file
12
src/test/ui/generic-associated-types/issue-67510-pass.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
}
|
||||
|
||||
fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
|
||||
fn main() {}
|
11
src/test/ui/generic-associated-types/issue-67510-pass.stderr
Normal file
11
src/test/ui/generic-associated-types/issue-67510-pass.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-67510-pass.rs:3:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
13
src/test/ui/generic-associated-types/issue-67510.rs
Normal file
13
src/test/ui/generic-associated-types/issue-67510.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
}
|
||||
|
||||
fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
//~^ ERROR: use of undeclared lifetime name `'a`
|
||||
//~| ERROR: use of undeclared lifetime name `'a`
|
||||
|
||||
|
||||
fn main() {}
|
32
src/test/ui/generic-associated-types/issue-67510.stderr
Normal file
32
src/test/ui/generic-associated-types/issue-67510.stderr
Normal file
@ -0,0 +1,32 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-67510.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/issue-67510.rs:8:21
|
||||
|
|
||||
LL | fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/issue-67510.rs:8:26
|
||||
|
|
||||
LL | fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
26
src/test/ui/generic-associated-types/issue-68648-1.rs
Normal file
26
src/test/ui/generic-associated-types/issue-68648-1.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
|
||||
trait Fun {
|
||||
type F<'a>;
|
||||
|
||||
fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T> Fun for T {
|
||||
type F<'a> = Self;
|
||||
}
|
||||
|
||||
fn bug<'a, T: for<'b> Fun<F<'b> = T>>(t: T) -> T::F<'a> {
|
||||
T::identity(t)
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = 10;
|
||||
|
||||
bug(x);
|
||||
}
|
11
src/test/ui/generic-associated-types/issue-68648-1.stderr
Normal file
11
src/test/ui/generic-associated-types/issue-68648-1.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-68648-1.rs:3:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
24
src/test/ui/generic-associated-types/issue-68648-2.rs
Normal file
24
src/test/ui/generic-associated-types/issue-68648-2.rs
Normal file
@ -0,0 +1,24 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait Fun {
|
||||
type F<'a>;
|
||||
|
||||
fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T> Fun for T {
|
||||
type F<'a> = Self;
|
||||
}
|
||||
|
||||
fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
|
||||
T::identity(())
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = 10;
|
||||
|
||||
bug(x);
|
||||
}
|
23
src/test/ui/generic-associated-types/issue-68648-2.stderr
Normal file
23
src/test/ui/generic-associated-types/issue-68648-2.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-68648-2.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-68648-2.rs:15:17
|
||||
|
|
||||
LL | fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
|
||||
| - this type parameter
|
||||
LL | T::identity(())
|
||||
| ^^ expected type parameter `T`, found `()`
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found unit type `()`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
25
src/test/ui/generic-associated-types/issue-68649-pass.rs
Normal file
25
src/test/ui/generic-associated-types/issue-68649-pass.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait Fun {
|
||||
type F<'a>;
|
||||
|
||||
fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T> Fun for T {
|
||||
type F<'a> = Self;
|
||||
}
|
||||
|
||||
fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
|
||||
T::identity(t)
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = 10;
|
||||
|
||||
bug(x);
|
||||
}
|
11
src/test/ui/generic-associated-types/issue-68649-pass.stderr
Normal file
11
src/test/ui/generic-associated-types/issue-68649-pass.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-68649-pass.rs:3:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
26
src/test/ui/generic-associated-types/issue-74684-1.rs
Normal file
26
src/test/ui/generic-associated-types/issue-74684-1.rs
Normal file
@ -0,0 +1,26 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait Fun {
|
||||
type F<'a>: ?Sized;
|
||||
|
||||
fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T> Fun for T {
|
||||
type F<'a> = [u8];
|
||||
}
|
||||
|
||||
fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
|
||||
let a = [0; 1];
|
||||
let _x = T::identity(&a);
|
||||
//~^ ERROR: `a` does not live long enough
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = 10;
|
||||
|
||||
bug(Box::new(x));
|
||||
}
|
27
src/test/ui/generic-associated-types/issue-74684-1.stderr
Normal file
27
src/test/ui/generic-associated-types/issue-74684-1.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-74684-1.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0597]: `a` does not live long enough
|
||||
--> $DIR/issue-74684-1.rs:16:26
|
||||
|
|
||||
LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let a = [0; 1];
|
||||
LL | let _x = T::identity(&a);
|
||||
| ------------^^-
|
||||
| | |
|
||||
| | borrowed value does not live long enough
|
||||
| argument requires that `a` is borrowed for `'a`
|
||||
...
|
||||
LL | }
|
||||
| - `a` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
26
src/test/ui/generic-associated-types/issue-74684-2.rs
Normal file
26
src/test/ui/generic-associated-types/issue-74684-2.rs
Normal file
@ -0,0 +1,26 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING: the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait Fun {
|
||||
type F<'a>: ?Sized;
|
||||
|
||||
fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
|
||||
}
|
||||
|
||||
impl <T> Fun for T {
|
||||
type F<'a> = i32;
|
||||
}
|
||||
|
||||
fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
|
||||
let a = [0; 1];
|
||||
let x = T::identity(&a);
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = 10;
|
||||
|
||||
bug(Box::new(x));
|
||||
//~^ ERROR: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
|
||||
}
|
21
src/test/ui/generic-associated-types/issue-74684-2.stderr
Normal file
21
src/test/ui/generic-associated-types/issue-74684-2.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-74684-2.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
|
||||
--> $DIR/issue-74684-2.rs:24:5
|
||||
|
|
||||
LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
|
||||
| ------------ required by this bound in `bug`
|
||||
...
|
||||
LL | bug(Box::new(x));
|
||||
| ^^^ expected slice `[u8]`, found `i32`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
41
src/test/ui/generic-associated-types/issue-76535.rs
Normal file
41
src/test/ui/generic-associated-types/issue-76535.rs
Normal file
@ -0,0 +1,41 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ WARNING the feature
|
||||
|
||||
pub trait SubTrait {}
|
||||
|
||||
pub trait SuperTrait {
|
||||
type SubType<'a>: SubTrait;
|
||||
//~^ ERROR missing generics for associated
|
||||
|
||||
fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
|
||||
}
|
||||
|
||||
pub struct SubStruct<'a> {
|
||||
sup: &'a mut SuperStruct,
|
||||
}
|
||||
|
||||
impl<'a> SubTrait for SubStruct<'a> {}
|
||||
|
||||
pub struct SuperStruct {
|
||||
value: u8,
|
||||
}
|
||||
|
||||
impl SuperStruct {
|
||||
pub fn new(value: u8) -> SuperStruct {
|
||||
SuperStruct { value }
|
||||
}
|
||||
}
|
||||
|
||||
impl SuperTrait for SuperStruct {
|
||||
type SubType<'a> = SubStruct<'a>;
|
||||
|
||||
fn get_sub<'a>(&'a mut self) -> Self::SubType<'a> {
|
||||
SubStruct { sup: self }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||
//~^ ERROR the trait
|
||||
//~| ERROR the trait
|
||||
}
|
63
src/test/ui/generic-associated-types/issue-76535.stderr
Normal file
63
src/test/ui/generic-associated-types/issue-76535.stderr
Normal file
@ -0,0 +1,63 @@
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-76535.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error[E0107]: missing generics for associated type `SuperTrait::SubType`
|
||||
--> $DIR/issue-76535.rs:7:10
|
||||
|
|
||||
LL | type SubType<'a>: SubTrait;
|
||||
| ^^^^^^^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/issue-76535.rs:7:10
|
||||
|
|
||||
LL | type SubType<'a>: SubTrait;
|
||||
| ^^^^^^^ --
|
||||
help: use angle brackets to add missing lifetime argument
|
||||
|
|
||||
LL | type SubType<'a><'a>: SubTrait;
|
||||
| ^^^^
|
||||
|
||||
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
||||
--> $DIR/issue-76535.rs:38:14
|
||||
|
|
||||
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `get_sub` to another trait
|
||||
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/issue-76535.rs:10:37
|
||||
|
|
||||
LL | pub trait SuperTrait {
|
||||
| ---------- this trait cannot be made into an object...
|
||||
...
|
||||
LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
|
||||
| ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type
|
||||
|
||||
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
||||
--> $DIR/issue-76535.rs:38:57
|
||||
|
|
||||
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `get_sub` to another trait
|
||||
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/issue-76535.rs:10:37
|
||||
|
|
||||
LL | pub trait SuperTrait {
|
||||
| ---------- this trait cannot be made into an object...
|
||||
...
|
||||
LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
|
||||
| ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type
|
||||
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
|
||||
= note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0038, E0107.
|
||||
For more information about an error, try `rustc --explain E0038`.
|
47
src/test/ui/generic-associated-types/issue-79422.rs
Normal file
47
src/test/ui/generic-associated-types/issue-79422.rs
Normal file
@ -0,0 +1,47 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
trait RefCont<'a, T> {
|
||||
fn t(&'a self) -> &'a T;
|
||||
}
|
||||
|
||||
impl<'a, T> RefCont<'a, T> for &'a T {
|
||||
fn t(&'a self) -> &'a T {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> RefCont<'a, T> for Box<T> {
|
||||
fn t(&'a self) -> &'a T {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
trait MapLike<K, V> {
|
||||
type VRefCont<'a>: RefCont<'a, V>;
|
||||
//~^ ERROR missing generics
|
||||
fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
|
||||
}
|
||||
|
||||
impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
|
||||
type VRefCont<'a> = &'a V;
|
||||
fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
|
||||
std::collections::BTreeMap::get(self, key)
|
||||
}
|
||||
}
|
||||
|
||||
struct Source;
|
||||
|
||||
impl<K, V: Default> MapLike<K, V> for Source {
|
||||
type VRefCont<'a> = Box<V>;
|
||||
fn get<'a>(&self, _: &K) -> Option<Box<V>> {
|
||||
Some(Box::new(V::default()))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
||||
as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||
//~^ ERROR the trait
|
||||
//~^^^ ERROR the trait
|
||||
}
|
54
src/test/ui/generic-associated-types/issue-79422.stderr
Normal file
54
src/test/ui/generic-associated-types/issue-79422.stderr
Normal file
@ -0,0 +1,54 @@
|
||||
error[E0107]: missing generics for associated type `MapLike::VRefCont`
|
||||
--> $DIR/issue-79422.rs:21:10
|
||||
|
|
||||
LL | type VRefCont<'a>: RefCont<'a, V>;
|
||||
| ^^^^^^^^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/issue-79422.rs:21:10
|
||||
|
|
||||
LL | type VRefCont<'a>: RefCont<'a, V>;
|
||||
| ^^^^^^^^ --
|
||||
help: use angle brackets to add missing lifetime argument
|
||||
|
|
||||
LL | type VRefCont<'a><'a>: RefCont<'a, V>;
|
||||
| ^^^^
|
||||
|
||||
error[E0038]: the trait `MapLike` cannot be made into an object
|
||||
--> $DIR/issue-79422.rs:44:12
|
||||
|
|
||||
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `get` to another trait
|
||||
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/issue-79422.rs:23:38
|
||||
|
|
||||
LL | trait MapLike<K, V> {
|
||||
| ------- this trait cannot be made into an object...
|
||||
...
|
||||
LL | fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type
|
||||
|
||||
error[E0038]: the trait `MapLike` cannot be made into an object
|
||||
--> $DIR/issue-79422.rs:43:13
|
||||
|
|
||||
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `get` to another trait
|
||||
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/issue-79422.rs:23:38
|
||||
|
|
||||
LL | trait MapLike<K, V> {
|
||||
| ------- this trait cannot be made into an object...
|
||||
...
|
||||
LL | fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type
|
||||
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
|
||||
= note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0038, E0107.
|
||||
For more information about an error, try `rustc --explain E0038`.
|
24
src/test/ui/generic-associated-types/issue-80433-reduced.rs
Normal file
24
src/test/ui/generic-associated-types/issue-80433-reduced.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// check-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
struct E {}
|
||||
|
||||
trait TestMut {
|
||||
type Output<'a>;
|
||||
fn test_mut(&mut self) -> Self::Output<'static>;
|
||||
}
|
||||
|
||||
impl TestMut for E {
|
||||
type Output<'a> = usize;
|
||||
fn test_mut(&mut self) -> Self::Output<'static> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn test_simpler<'a>(_: impl TestMut<Output<'a> = usize>) {}
|
||||
|
||||
fn main() {
|
||||
test_simpler(E {});
|
||||
}
|
35
src/test/ui/generic-associated-types/issue-80433.rs
Normal file
35
src/test/ui/generic-associated-types/issue-80433.rs
Normal file
@ -0,0 +1,35 @@
|
||||
#![feature(generic_associated_types)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct E<T> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
trait TestMut {
|
||||
type Output<'a>;
|
||||
//~^ ERROR missing generics
|
||||
fn test_mut<'a>(&'a mut self) -> Self::Output<'a>;
|
||||
}
|
||||
|
||||
impl<T> TestMut for E<T>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
type Output<'a> = &'a mut T;
|
||||
fn test_mut<'a>(&'a mut self) -> Self::Output<'a> {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
||||
|
||||
fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
|
||||
{
|
||||
for n in 0i16..100 {
|
||||
*dst.test_mut() = n.into();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut t1: E<f32> = Default::default();
|
||||
test_simpler(&mut t1);
|
||||
}
|
19
src/test/ui/generic-associated-types/issue-80433.stderr
Normal file
19
src/test/ui/generic-associated-types/issue-80433.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0107]: missing generics for associated type `TestMut::Output`
|
||||
--> $DIR/issue-80433.rs:10:10
|
||||
|
|
||||
LL | type Output<'a>;
|
||||
| ^^^^^^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/issue-80433.rs:10:10
|
||||
|
|
||||
LL | type Output<'a>;
|
||||
| ^^^^^^ --
|
||||
help: use angle brackets to add missing lifetime argument
|
||||
|
|
||||
LL | type Output<'a><'a>;
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
@ -1,10 +1,14 @@
|
||||
#![feature(generic_associated_types)]
|
||||
//~^ the feature `generic_associated_types` is incomplete
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
//~^ ERROR this associated type
|
||||
//~| ERROR this associated type
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
|
||||
//~^ ERROR: generic associated types in trait paths are currently not implemented
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,49 @@
|
||||
error: generic associated types in trait paths are currently not implemented
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:8:30
|
||||
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:1:12
|
||||
|
|
||||
LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
|
||||
| ^^^
|
||||
LL | #![feature(generic_associated_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^ --
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | fn f2<'a>(arg : Box<dyn X<Y<'a1> = &'a ()>>) {}
|
||||
| ^^
|
||||
|
||||
error[E0107]: this associated type takes 0 const arguments but 1 const argument was supplied
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| __________^-
|
||||
| | |
|
||||
| | expected 0 const arguments
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | }
|
||||
LL | |
|
||||
LL | | const _: () = {
|
||||
LL | | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
|
||||
| |________________________________- help: remove these generics
|
||||
|
|
||||
note: associated type defined here, with 0 const parameters
|
||||
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
|
||||
|
|
||||
LL | type Y<'a>;
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
||||
|
@ -1,17 +0,0 @@
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
trait X {
|
||||
type Y<'a>;
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
fn f1<'a>(arg : Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
//~^ ERROR: generic associated types in trait paths are currently not implemented
|
||||
};
|
||||
|
||||
const _: () = {
|
||||
fn f1<'a>(arg : Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
//~^ ERROR: lifetime in trait object type must be followed by `+`
|
||||
};
|
||||
|
||||
fn main() {}
|
@ -1,14 +0,0 @@
|
||||
error: lifetime in trait object type must be followed by `+`
|
||||
--> $DIR/trait-path-unimplemented.rs:13:31
|
||||
|
|
||||
LL | fn f1<'a>(arg : Box<dyn X<Y('a) = &'a ()>>) {}
|
||||
| ^^
|
||||
|
||||
error: generic associated types in trait paths are currently not implemented
|
||||
--> $DIR/trait-path-unimplemented.rs:8:30
|
||||
|
|
||||
LL | fn f1<'a>(arg : Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user