Make GATs object safe under generic_associated_types_extended feature
This commit is contained in:
parent
0677edc86e
commit
52b00db235
19 changed files with 240 additions and 44 deletions
|
@ -131,16 +131,18 @@ fn object_safety_violations_for_trait(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
violations.extend(
|
if !tcx.features().generic_associated_types_extended {
|
||||||
tcx.associated_items(trait_def_id)
|
violations.extend(
|
||||||
.in_definition_order()
|
tcx.associated_items(trait_def_id)
|
||||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
.in_definition_order()
|
||||||
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
|
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||||
.map(|item| {
|
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
|
||||||
let ident = item.ident(tcx);
|
.map(|item| {
|
||||||
ObjectSafetyViolation::GAT(ident.name, ident.span)
|
let ident = item.ident(tcx);
|
||||||
}),
|
ObjectSafetyViolation::GAT(ident.name, ident.span)
|
||||||
);
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
|
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
|
||||||
|
|
|
@ -11,8 +11,8 @@ use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::bit_set::GrowableBitSet;
|
use rustc_index::bit_set::GrowableBitSet;
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
|
||||||
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
|
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
|
@ -487,18 +487,80 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for assoc_type in assoc_types {
|
for assoc_type in assoc_types {
|
||||||
if !tcx.generics_of(assoc_type).params.is_empty() {
|
let defs: &ty::Generics = tcx.generics_of(assoc_type);
|
||||||
|
|
||||||
|
if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended {
|
||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
"GATs in trait object shouldn't have been considered",
|
"GATs in trait object shouldn't have been considered",
|
||||||
);
|
);
|
||||||
return Err(SelectionError::Unimplemented);
|
return Err(SelectionError::Unimplemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This maybe belongs in wf, but that can't (doesn't) handle
|
// This maybe belongs in wf, but that can't (doesn't) handle
|
||||||
// higher-ranked things.
|
// higher-ranked things.
|
||||||
// Prevent, e.g., `dyn Iterator<Item = str>`.
|
// Prevent, e.g., `dyn Iterator<Item = str>`.
|
||||||
for bound in self.tcx().item_bounds(assoc_type) {
|
for bound in self.tcx().item_bounds(assoc_type) {
|
||||||
let subst_bound = bound.subst(tcx, trait_predicate.trait_ref.substs);
|
let subst_bound =
|
||||||
|
if defs.count() == 0 {
|
||||||
|
bound.subst(tcx, trait_predicate.trait_ref.substs)
|
||||||
|
} else {
|
||||||
|
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
|
||||||
|
substs.extend(trait_predicate.trait_ref.substs.iter());
|
||||||
|
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
|
||||||
|
smallvec::SmallVec::with_capacity(
|
||||||
|
bound.kind().bound_vars().len() + defs.count(),
|
||||||
|
);
|
||||||
|
bound_vars.extend(bound.kind().bound_vars().into_iter());
|
||||||
|
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
|
||||||
|
.kind
|
||||||
|
{
|
||||||
|
GenericParamDefKind::Type { .. } => {
|
||||||
|
let kind = ty::BoundTyKind::Param(param.name);
|
||||||
|
let bound_var = ty::BoundVariableKind::Ty(kind);
|
||||||
|
bound_vars.push(bound_var);
|
||||||
|
tcx.mk_ty(ty::Bound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundTy {
|
||||||
|
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||||
|
kind,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
GenericParamDefKind::Lifetime => {
|
||||||
|
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
|
||||||
|
let bound_var = ty::BoundVariableKind::Region(kind);
|
||||||
|
bound_vars.push(bound_var);
|
||||||
|
tcx.mk_region(ty::ReLateBound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundRegion {
|
||||||
|
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||||
|
kind,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
GenericParamDefKind::Const { .. } => {
|
||||||
|
let bound_var = ty::BoundVariableKind::Const;
|
||||||
|
bound_vars.push(bound_var);
|
||||||
|
tcx.mk_const(ty::ConstS {
|
||||||
|
ty: tcx.type_of(param.def_id),
|
||||||
|
val: ty::ConstKind::Bound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
|
||||||
|
let assoc_ty_substs = tcx.intern_substs(&substs);
|
||||||
|
|
||||||
|
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
|
||||||
|
let bound = bound.kind().skip_binder().subst(tcx, assoc_ty_substs);
|
||||||
|
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
|
||||||
|
};
|
||||||
let normalized_bound = normalize_with_depth_to(
|
let normalized_bound = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0038]: the trait `Foo` cannot be made into an object
|
error[E0038]: the trait `Foo` cannot be made into an object
|
||||||
--> $DIR/gat-in-trait-path.rs:21:17
|
--> $DIR/gat-in-trait-path.rs:27:17
|
||||||
|
|
|
|
||||||
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
|
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/gat-in-trait-path.rs:5:10
|
--> $DIR/gat-in-trait-path.rs:11:10
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --- this trait cannot be made into an object...
|
| --- this trait cannot be made into an object...
|
|
@ -1,5 +1,11 @@
|
||||||
|
// revisions: base extended
|
||||||
|
//[base] check-fail
|
||||||
|
//[extended] check-pass
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
type A<'a> where Self: 'a;
|
type A<'a> where Self: 'a;
|
||||||
|
@ -19,7 +25,7 @@ impl<T> Foo for Fooer<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
|
||||||
//~^ the trait `Foo` cannot be made into an object
|
//[base]~^ the trait `Foo` cannot be made into an object
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0038]: the trait `X` cannot be made into an object
|
error[E0038]: the trait `X` cannot be made into an object
|
||||||
--> $DIR/issue-67510-pass.rs:7:23
|
--> $DIR/issue-67510-pass.rs:13:23
|
||||||
|
|
|
|
||||||
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^ `X` 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>
|
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-67510-pass.rs:4:10
|
--> $DIR/issue-67510-pass.rs:10:10
|
||||||
|
|
|
|
||||||
LL | trait X {
|
LL | trait X {
|
||||||
| - this trait cannot be made into an object...
|
| - this trait cannot be made into an object...
|
|
@ -1,10 +1,16 @@
|
||||||
|
// revisions: base extended
|
||||||
|
//[base] check-fail
|
||||||
|
//[extended] check-pass
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
trait X {
|
trait X {
|
||||||
type Y<'a>;
|
type Y<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||||
//~^ ERROR the trait `X` cannot be made into an object
|
//[base]~^ ERROR the trait `X` cannot be made into an object
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0107]: missing generics for associated type `SuperTrait::SubType`
|
error[E0107]: missing generics for associated type `SuperTrait::SubType`
|
||||||
--> $DIR/issue-76535.rs:36:33
|
--> $DIR/issue-76535.rs:40:33
|
||||||
|
|
|
|
||||||
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
| ^^^^^^^ expected 1 lifetime argument
|
| ^^^^^^^ expected 1 lifetime argument
|
||||||
|
|
|
|
||||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||||
--> $DIR/issue-76535.rs:6:10
|
--> $DIR/issue-76535.rs:10:10
|
||||||
|
|
|
|
||||||
LL | type SubType<'a>: SubTrait where Self: 'a;
|
LL | type SubType<'a>: SubTrait where Self: 'a;
|
||||||
| ^^^^^^^ --
|
| ^^^^^^^ --
|
||||||
|
@ -15,13 +15,13 @@ LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperS
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
||||||
--> $DIR/issue-76535.rs:36:14
|
--> $DIR/issue-76535.rs:40:14
|
||||||
|
|
|
|
||||||
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` 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>
|
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:6:10
|
--> $DIR/issue-76535.rs:10:10
|
||||||
|
|
|
|
||||||
LL | pub trait SuperTrait {
|
LL | pub trait SuperTrait {
|
||||||
| ---------- this trait cannot be made into an object...
|
| ---------- this trait cannot be made into an object...
|
||||||
|
@ -30,13 +30,13 @@ LL | type SubType<'a>: SubTrait where Self: 'a;
|
||||||
= help: consider moving `SubType` to another trait
|
= help: consider moving `SubType` to another trait
|
||||||
|
|
||||||
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
error[E0038]: the trait `SuperTrait` cannot be made into an object
|
||||||
--> $DIR/issue-76535.rs:36:57
|
--> $DIR/issue-76535.rs:40:57
|
||||||
|
|
|
|
||||||
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` 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>
|
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:6:10
|
--> $DIR/issue-76535.rs:10:10
|
||||||
|
|
|
|
||||||
LL | pub trait SuperTrait {
|
LL | pub trait SuperTrait {
|
||||||
| ---------- this trait cannot be made into an object...
|
| ---------- this trait cannot be made into an object...
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0107]: missing generics for associated type `SuperTrait::SubType`
|
||||||
|
--> $DIR/issue-76535.rs:40:33
|
||||||
|
|
|
||||||
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
|
| ^^^^^^^ expected 1 lifetime argument
|
||||||
|
|
|
||||||
|
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||||
|
--> $DIR/issue-76535.rs:10:10
|
||||||
|
|
|
||||||
|
LL | type SubType<'a>: SubTrait where Self: 'a;
|
||||||
|
| ^^^^^^^ --
|
||||||
|
help: add missing lifetime argument
|
||||||
|
|
|
||||||
|
LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
|
| ~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0107`.
|
|
@ -1,4 +1,8 @@
|
||||||
|
// revisions: base extended
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
pub trait SubTrait {}
|
pub trait SubTrait {}
|
||||||
|
|
||||||
|
@ -35,6 +39,6 @@ impl SuperTrait for SuperStruct {
|
||||||
fn main() {
|
fn main() {
|
||||||
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
|
||||||
//~^ ERROR missing generics for associated type
|
//~^ ERROR missing generics for associated type
|
||||||
//~^^ ERROR the trait
|
//[base]~^^ ERROR the trait
|
||||||
//~| ERROR the trait
|
//[base]~| ERROR the trait
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0107]: missing generics for associated type `CollectionFamily::Member`
|
error[E0107]: missing generics for associated type `CollectionFamily::Member`
|
||||||
--> $DIR/issue-78671.rs:7:47
|
--> $DIR/issue-78671.rs:11:47
|
||||||
|
|
|
|
||||||
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
||||||
| ^^^^^^ expected 1 generic argument
|
| ^^^^^^ expected 1 generic argument
|
||||||
|
|
|
|
||||||
note: associated type defined here, with 1 generic parameter: `T`
|
note: associated type defined here, with 1 generic parameter: `T`
|
||||||
--> $DIR/issue-78671.rs:4:10
|
--> $DIR/issue-78671.rs:8:10
|
||||||
|
|
|
|
||||||
LL | type Member<T>;
|
LL | type Member<T>;
|
||||||
| ^^^^^^ -
|
| ^^^^^^ -
|
||||||
|
@ -15,13 +15,13 @@ LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
|
||||||
error[E0038]: the trait `CollectionFamily` cannot be made into an object
|
error[E0038]: the trait `CollectionFamily` cannot be made into an object
|
||||||
--> $DIR/issue-78671.rs:7:25
|
--> $DIR/issue-78671.rs:11:25
|
||||||
|
|
|
|
||||||
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` 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>
|
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-78671.rs:4:10
|
--> $DIR/issue-78671.rs:8:10
|
||||||
|
|
|
|
||||||
LL | trait CollectionFamily {
|
LL | trait CollectionFamily {
|
||||||
| ---------------- this trait cannot be made into an object...
|
| ---------------- this trait cannot be made into an object...
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0107]: missing generics for associated type `CollectionFamily::Member`
|
||||||
|
--> $DIR/issue-78671.rs:11:47
|
||||||
|
|
|
||||||
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
||||||
|
| ^^^^^^ expected 1 generic argument
|
||||||
|
|
|
||||||
|
note: associated type defined here, with 1 generic parameter: `T`
|
||||||
|
--> $DIR/issue-78671.rs:8:10
|
||||||
|
|
|
||||||
|
LL | type Member<T>;
|
||||||
|
| ^^^^^^ -
|
||||||
|
help: add missing generic argument
|
||||||
|
|
|
||||||
|
LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
|
||||||
|
| ~~~~~~~~~
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0107`.
|
|
@ -1,4 +1,8 @@
|
||||||
|
// revisions: base extended
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
trait CollectionFamily {
|
trait CollectionFamily {
|
||||||
type Member<T>;
|
type Member<T>;
|
||||||
|
@ -6,7 +10,7 @@ trait CollectionFamily {
|
||||||
fn floatify() {
|
fn floatify() {
|
||||||
Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
Box::new(Family) as &dyn CollectionFamily<Member=usize>
|
||||||
//~^ ERROR: missing generics for associated type
|
//~^ ERROR: missing generics for associated type
|
||||||
//~| ERROR: the trait `CollectionFamily` cannot be made into an object
|
//[base]~^^ ERROR: the trait `CollectionFamily` cannot be made into an object
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Family;
|
struct Family;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0107]: missing generics for associated type `MapLike::VRefCont`
|
error[E0107]: missing generics for associated type `MapLike::VRefCont`
|
||||||
--> $DIR/issue-79422.rs:42:36
|
--> $DIR/issue-79422.rs:48:36
|
||||||
|
|
|
|
||||||
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||||
| ^^^^^^^^ expected 1 lifetime argument
|
| ^^^^^^^^ expected 1 lifetime argument
|
||||||
|
|
|
|
||||||
note: associated type defined here, with 1 lifetime parameter: `'a`
|
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||||
--> $DIR/issue-79422.rs:20:10
|
--> $DIR/issue-79422.rs:24:10
|
||||||
|
|
|
|
||||||
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
||||||
| ^^^^^^^^ --
|
| ^^^^^^^^ --
|
||||||
|
@ -15,13 +15,13 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0038]: the trait `MapLike` cannot be made into an object
|
error[E0038]: the trait `MapLike` cannot be made into an object
|
||||||
--> $DIR/issue-79422.rs:42:12
|
--> $DIR/issue-79422.rs:48:12
|
||||||
|
|
|
|
||||||
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` 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>
|
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:20:10
|
--> $DIR/issue-79422.rs:24:10
|
||||||
|
|
|
|
||||||
LL | trait MapLike<K, V> {
|
LL | trait MapLike<K, V> {
|
||||||
| ------- this trait cannot be made into an object...
|
| ------- this trait cannot be made into an object...
|
||||||
|
@ -30,13 +30,13 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
||||||
= help: consider moving `VRefCont` to another trait
|
= help: consider moving `VRefCont` to another trait
|
||||||
|
|
||||||
error[E0038]: the trait `MapLike` cannot be made into an object
|
error[E0038]: the trait `MapLike` cannot be made into an object
|
||||||
--> $DIR/issue-79422.rs:41:13
|
--> $DIR/issue-79422.rs:45:13
|
||||||
|
|
|
|
||||||
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` 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>
|
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:20:10
|
--> $DIR/issue-79422.rs:24:10
|
||||||
|
|
|
|
||||||
LL | trait MapLike<K, V> {
|
LL | trait MapLike<K, V> {
|
||||||
| ------- this trait cannot be made into an object...
|
| ------- this trait cannot be made into an object...
|
|
@ -0,0 +1,35 @@
|
||||||
|
error[E0107]: missing generics for associated type `MapLike::VRefCont`
|
||||||
|
--> $DIR/issue-79422.rs:48:36
|
||||||
|
|
|
||||||
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||||
|
| ^^^^^^^^ expected 1 lifetime argument
|
||||||
|
|
|
||||||
|
note: associated type defined here, with 1 lifetime parameter: `'a`
|
||||||
|
--> $DIR/issue-79422.rs:24:10
|
||||||
|
|
|
||||||
|
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
||||||
|
| ^^^^^^^^ --
|
||||||
|
help: add missing lifetime argument
|
||||||
|
|
|
||||||
|
LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
|
||||||
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
|
||||||
|
--> $DIR/issue-79422.rs:45:13
|
||||||
|
|
|
||||||
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
|
||||||
|
|
|
||||||
|
note: expected this to be `(dyn RefCont<'_, u8> + 'static)`
|
||||||
|
--> $DIR/issue-79422.rs:29:25
|
||||||
|
|
|
||||||
|
LL | type VRefCont<'a> = &'a V where Self: 'a;
|
||||||
|
| ^^^^^
|
||||||
|
= note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
|
||||||
|
found reference `&u8`
|
||||||
|
= note: required for the cast to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0107, E0271.
|
||||||
|
For more information about an error, try `rustc --explain E0107`.
|
|
@ -1,4 +1,8 @@
|
||||||
|
// revisions: base extended
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
trait RefCont<'a, T> {
|
trait RefCont<'a, T> {
|
||||||
fn t(&'a self) -> &'a T;
|
fn t(&'a self) -> &'a T;
|
||||||
|
@ -39,8 +43,9 @@ impl<K, V: Default> MapLike<K, V> for Source {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
|
||||||
|
//[base]~^ ERROR the trait
|
||||||
|
//[extended]~^^ type mismatch
|
||||||
as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
|
||||||
//~^ ERROR missing generics for associated type
|
//~^ ERROR missing generics for associated type
|
||||||
//~^^ ERROR the trait
|
//[base]~^^ ERROR the trait
|
||||||
//~^^^^ ERROR the trait
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0038]: the trait `StreamingIterator` cannot be made into an object
|
error[E0038]: the trait `StreamingIterator` cannot be made into an object
|
||||||
--> $DIR/trait-objects.rs:10:21
|
--> $DIR/trait-objects.rs:14:21
|
||||||
|
|
|
|
||||||
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` 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>
|
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/trait-objects.rs:4:10
|
--> $DIR/trait-objects.rs:8:10
|
||||||
|
|
|
|
||||||
LL | trait StreamingIterator {
|
LL | trait StreamingIterator {
|
||||||
| ----------------- this trait cannot be made into an object...
|
| ----------------- this trait cannot be made into an object...
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0521]: borrowed data escapes outside of function
|
||||||
|
--> $DIR/trait-objects.rs:16:5
|
||||||
|
|
|
||||||
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
||||||
|
| - - let's call the lifetime of this reference `'1`
|
||||||
|
| |
|
||||||
|
| `x` is a reference that is only valid in the function body
|
||||||
|
LL |
|
||||||
|
LL | x.size_hint().0
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `x` escapes the function body here
|
||||||
|
| argument requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0521`.
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0621]: explicit lifetime required in the type of `x`
|
||||||
|
--> $DIR/trait-objects.rs:16:7
|
||||||
|
|
|
||||||
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
||||||
|
| ------------------------------------------------------ help: add explicit lifetime `'a` to the type of `x`: `&'a mut (dyn StreamingIterator<for<'a> Item = &'a i32> + 'a)`
|
||||||
|
LL |
|
||||||
|
LL | x.size_hint().0
|
||||||
|
| ^^^^^^^^^ lifetime `'a` required
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0621`.
|
|
@ -1,4 +1,8 @@
|
||||||
|
// revisions: base extended
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
|
#![cfg_attr(extended, feature(generic_associated_types_extended))]
|
||||||
|
#![cfg_attr(extended, allow(incomplete_features))]
|
||||||
|
|
||||||
trait StreamingIterator {
|
trait StreamingIterator {
|
||||||
type Item<'a> where Self: 'a;
|
type Item<'a> where Self: 'a;
|
||||||
|
@ -8,8 +12,9 @@ trait StreamingIterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
|
||||||
//~^ the trait `StreamingIterator` cannot be made into an object
|
//[base]~^ the trait `StreamingIterator` cannot be made into an object
|
||||||
x.size_hint().0
|
x.size_hint().0
|
||||||
|
//[extended]~^ explicit lifetime required
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue