Move bounds on associated types to the type

Given `trait X { type U; }` the bound `<Self as X>::U` now lives
on the type, rather than the trait. This is feature gated on
`feature(generic_associated_types)` for now until more testing can
be done.

The also enabled type-generic associated types since we no longer
need "implies bounds".
This commit is contained in:
Matthew Jasper 2020-06-11 16:50:34 +01:00
parent 9818bc08d3
commit db4826dd6c
47 changed files with 347 additions and 500 deletions

View File

@ -1,9 +1,8 @@
use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::{GenericKind, VerifyBound};
use crate::traits;
use rustc_data_structures::captures::Captures;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::{self, Ty, TyCtxt};
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
@ -311,18 +310,14 @@ fn declared_projection_bounds_from_trait(
fn region_bounds_declared_on_associated_item(
&self,
assoc_item_def_id: DefId,
) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
) -> impl Iterator<Item = ty::Region<'tcx>> {
let tcx = self.tcx;
let assoc_item = tcx.associated_item(assoc_item_def_id);
let trait_def_id = assoc_item.container.assert_trait();
let trait_predicates = tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p);
let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id);
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
self.collect_outlives_from_predicate_list(
move |ty| ty == identity_proj,
traits::elaborate_predicates(tcx, trait_predicates).map(|o| o.predicate),
)
.map(|b| b.1)
let predicates = tcx.projection_predicates(assoc_item_def_id);
predicates
.into_iter()
.filter_map(|p| p.to_opt_type_outlives())
.filter_map(|p| p.no_bound_vars())
.map(|b| b.1)
}
/// Searches through a predicate list for a predicate `T: 'a`.

View File

@ -25,8 +25,6 @@
Normalized, NormalizedTy, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey,
ProjectionCacheStorage, Reveal,
};
crate use self::util::elaborate_predicates;
pub use rustc_middle::traits::*;
/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for

View File

@ -136,6 +136,16 @@ fn describe_as_module(def_id: DefId, tcx: TyCtxt<'_>) -> String {
/// Returns the list of predicates that can be used for
/// `SelectionCandidate::ProjectionCandidate` and
/// `ProjectionTyCandidate::TraitDef`.
/// Specifically this is the bounds (equivalent to) those
/// written on the trait's type definition, or those
/// after the `impl` keyword
///
/// type X: Bound + 'lt
/// ^^^^^^^^^^^
/// impl Debug + Display
/// ^^^^^^^^^^^^^^^
///
/// `key` is the `DefId` of the associated type or opaque type.
query projection_predicates(key: DefId) -> &'tcx ty::List<ty::Predicate<'tcx>> {
desc { |tcx| "finding projection predicates for `{}`", tcx.def_path_str(key) }
}

View File

@ -371,34 +371,45 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
/// (`type X: Trait`) to be used as candidates. We also allow the same bounds
/// when desugared as bounds on the trait `where Self::X: Trait`.
///
/// Note that this filtering is done with the trait's identity substs to
/// Note that this filtering is done with the items identity substs to
/// simplify checking that these bounds are met in impls. This means that
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
/// `hr-associated-type-bound-1.rs`.
fn associated_type_projection_predicates(
tcx: TyCtxt<'_>,
def_id: DefId,
assoc_item_def_id: DefId,
) -> &'_ ty::List<ty::Predicate<'_>> {
let trait_id = tcx.associated_item(def_id).container.id();
let trait_substs = InternalSubsts::identity_for_item(tcx, trait_id);
let generic_trait_bounds = tcx.predicates_of(assoc_item_def_id);
// We include predicates from the trait as well to handle
// `where Self::X: Trait`.
let item_bounds = generic_trait_bounds.instantiate_identity(tcx);
let item_predicates = util::elaborate_predicates(tcx, item_bounds.predicates.into_iter());
let generic_trait_bounds = tcx.predicates_of(trait_id);
let trait_bounds = generic_trait_bounds.instantiate_identity(tcx);
let trait_predicates = util::elaborate_predicates(tcx, trait_bounds.predicates.into_iter());
let assoc_item_ty = ty::ProjectionTy {
item_def_id: assoc_item_def_id,
substs: InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
};
let predicates = trait_predicates.filter_map(|obligation| {
let predicates = item_predicates.filter_map(|obligation| {
let pred = obligation.predicate;
match pred.kind() {
ty::PredicateKind::Trait(tr, _) => {
if let ty::Projection(p) = tr.skip_binder().self_ty().kind {
if p.item_def_id == def_id && p.substs.starts_with(trait_substs) {
if p == assoc_item_ty {
return Some(pred);
}
}
}
ty::PredicateKind::Projection(proj) => {
if let ty::Projection(p) = proj.skip_binder().projection_ty.self_ty().kind {
if p.item_def_id == def_id && p.substs.starts_with(trait_substs) {
if p == assoc_item_ty {
return Some(pred);
}
}
}
ty::PredicateKind::TypeOutlives(outlives) => {
if let ty::Projection(p) = outlives.skip_binder().0.kind {
if p == assoc_item_ty {
return Some(pred);
}
}
@ -409,7 +420,11 @@ fn associated_type_projection_predicates(
});
let result = tcx.mk_predicates(predicates);
debug!("associated_type_projection_predicates({}) = {:?}", tcx.def_path_str(def_id), result);
debug!(
"associated_type_projection_predicates({}) = {:?}",
tcx.def_path_str(assoc_item_def_id),
result
);
result
}
@ -422,9 +437,9 @@ fn opaque_type_projection_predicates(
) -> &'_ ty::List<ty::Predicate<'_>> {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let generics_bounds = tcx.predicates_of(def_id);
let bounds = generics_bounds.instantiate_identity(tcx);
let predicates = util::elaborate_predicates(tcx, bounds.predicates.into_iter());
let bounds = tcx.predicates_of(def_id);
let predicates =
util::elaborate_predicates(tcx, bounds.predicates.into_iter().map(|&(pred, _)| pred));
let filtered_predicates = predicates.filter_map(|obligation| {
let pred = obligation.predicate;
@ -445,6 +460,18 @@ fn opaque_type_projection_predicates(
}
}
}
ty::PredicateKind::TypeOutlives(outlives) => {
if let ty::Opaque(opaque_def_id, opaque_substs) = outlives.skip_binder().0.kind {
if opaque_def_id == def_id && opaque_substs == substs {
return Some(pred);
}
} else {
// These can come from elaborating other predicates
return None;
}
}
// These can come from elaborating other predicates
ty::PredicateKind::RegionOutlives(_) => return None,
_ => {}
}
tcx.sess.delay_span_bug(

View File

@ -1189,8 +1189,8 @@ fn compare_projection_bounds<'tcx>(
impl_ty_span: Span,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorReported> {
let is_gat = !tcx.generics_of(impl_ty.def_id).params.is_empty();
if impl_ty.defaultness.is_final() && !is_gat {
let have_gats = tcx.features().generic_associated_types;
if impl_ty.defaultness.is_final() && !have_gats {
// For "final", non-generic associate type implementations, we
// don't need this as described above.
return Ok(());
@ -1198,7 +1198,9 @@ fn compare_projection_bounds<'tcx>(
let param_env = tcx.param_env(impl_ty.def_id);
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.container.id());
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let rebased_substs =
impl_ty_substs.rebase_onto(tcx, impl_ty.container.id(), impl_trait_ref.substs);
let impl_ty_value = tcx.type_of(impl_ty.def_id);
// Map the predicate from the trait to the corresponding one for the impl.
@ -1211,32 +1213,9 @@ fn compare_projection_bounds<'tcx>(
// function would translate and partially normalize
// `[<Self as X<A>>::Y<'a>, A]` to `[&'a u32, &'x u32]`.
let translate_predicate_substs = move |predicate_substs: SubstsRef<'tcx>| {
let normalized_self = if !is_gat {
// projection_predicates only includes projections where the
// substs of the trait ref are exactly the trait's identity
// substs, so we can simply return the value from the impl.
impl_ty_value
} else {
let predicate_self_ty = predicate_substs.type_at(0);
let impl_ty_substs = if let ty::Projection(p) = predicate_self_ty.kind {
assert!(
p.item_def_id == trait_ty.def_id,
"projection_predicates returned predicate for the wrong type: {}",
predicate_self_ty,
);
p.substs.rebase_onto(tcx, impl_trait_ref.def_id, impl_substs)
} else {
bug!(
"projection_predicates returned predicate for the wrong type `{}`",
predicate_self_ty,
);
};
impl_ty_value.subst(tcx, impl_ty_substs)
};
tcx.mk_substs(
iter::once(normalized_self.into())
.chain(predicate_substs[1..].iter().map(|s| s.subst(tcx, impl_trait_ref.substs))),
iter::once(impl_ty_value.into())
.chain(predicate_substs[1..].iter().map(|s| s.subst(tcx, rebased_substs))),
)
};
@ -1275,10 +1254,15 @@ fn compare_projection_bounds<'tcx>(
substs: projection_substs,
item_def_id: projection.projection_ty.item_def_id,
},
ty: projection.ty.subst(tcx, impl_trait_ref.substs),
ty: projection.ty.subst(tcx, rebased_substs),
}
})
.to_predicate(tcx),
ty::PredicateKind::TypeOutlives(poly_outlives) => poly_outlives
.map_bound(|outlives| {
ty::OutlivesPredicate(impl_ty_value, outlives.1.subst(tcx, rebased_substs))
})
.to_predicate(tcx),
_ => bug!("unexepected projection predicate kind: `{:?}`", predicate),
};

View File

@ -35,7 +35,7 @@
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::Discr;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
@ -1692,6 +1692,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
let mut is_trait = None;
let mut is_default_impl_trait = None;
let mut is_trait_associated_type = None;
let icx = ItemCtxt::new(tcx, def_id);
let constness = icx.default_constness_for_trait_bounds();
@ -1701,7 +1702,12 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
let mut predicates = UniquePredicates::new();
let ast_generics = match node {
Node::TraitItem(item) => &item.generics,
Node::TraitItem(item) => {
if let hir::TraitItemKind::Type(bounds, _) = item.kind {
is_trait_associated_type = Some((bounds, item.span));
}
&item.generics
}
Node::ImplItem(item) => &item.generics,
@ -1925,10 +1931,21 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
}
}
// Add predicates from associated type bounds.
if let Some((self_trait_ref, trait_items)) = is_trait {
// Add predicates from associated type bounds (`type X: Bound`)
if tcx.features().generic_associated_types {
// New behavior: bounds declared on associate type are predicates of that
// associated type. Not the default because it needs more testing.
if let Some((bounds, span)) = is_trait_associated_type {
let projection_ty =
tcx.mk_projection(def_id, InternalSubsts::identity_for_item(tcx, def_id));
predicates.extend(associated_item_bounds(tcx, def_id, bounds, projection_ty, span))
}
} else if let Some((self_trait_ref, trait_items)) = is_trait {
// Current behavior: bounds declared on associate type are predicates
// of its parent trait.
predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
associated_item_predicates(tcx, def_id, self_trait_ref, trait_item_ref)
trait_associated_item_predicates(tcx, def_id, self_trait_ref, trait_item_ref)
}))
}
@ -1958,7 +1975,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
result
}
fn associated_item_predicates(
fn trait_associated_item_predicates(
tcx: TyCtxt<'tcx>,
def_id: DefId,
self_trait_ref: ty::TraitRef<'tcx>,
@ -1971,92 +1988,40 @@ fn associated_item_predicates(
_ => return Vec::new(),
};
let is_gat = !tcx.generics_of(item_def_id).params.is_empty();
if !tcx.generics_of(item_def_id).params.is_empty() {
// For GATs the substs provided to the mk_projection call below are
// wrong. We should emit a feature gate error if we get here so skip
// this type.
tcx.sess.delay_span_bug(trait_item.span, "gats used without feature gate");
return Vec::new();
}
let mut had_error = false;
let mut unimplemented_error = |arg_kind: &str| {
if !had_error {
tcx.sess
.struct_span_err(
trait_item.span,
&format!("{}-generic associated types are not yet implemented", arg_kind),
)
.note(
"for more information, see issue #44265 \
<https://github.com/rust-lang/rust/issues/44265> for more information",
)
.emit();
had_error = true;
}
};
let mk_bound_param = |param: &ty::GenericParamDef, _: &_| {
match param.kind {
ty::GenericParamDefKind::Lifetime => tcx
.mk_region(ty::RegionKind::ReLateBound(
ty::INNERMOST,
ty::BoundRegion::BrNamed(param.def_id, param.name),
))
.into(),
// FIXME(generic_associated_types): Use bound types and constants
// once they are handled by the trait system.
ty::GenericParamDefKind::Type { .. } => {
unimplemented_error("type");
tcx.ty_error().into()
}
ty::GenericParamDefKind::Const => {
unimplemented_error("const");
tcx.const_error(tcx.type_of(param.def_id)).into()
}
}
};
let bound_substs = if is_gat {
// Given:
//
// trait X<'a, B, const C: usize> {
// type T<'d, E, const F: usize>: Default;
// }
//
// We need to create predicates on the trait:
//
// for<'d, E, const F: usize>
// <Self as X<'a, B, const C: usize>>::T<'d, E, const F: usize>: Sized + Default
//
// We substitute escaping bound parameters for the generic
// arguments to the associated type which are then bound by
// the `Binder` around the the predicate.
//
// FIXME(generic_associated_types): Currently only lifetimes are handled.
self_trait_ref.substs.extend_to(tcx, item_def_id.to_def_id(), mk_bound_param)
} else {
self_trait_ref.substs
};
let assoc_ty =
tcx.mk_projection(tcx.hir().local_def_id(trait_item.hir_id).to_def_id(), bound_substs);
let bounds = AstConv::compute_bounds(
&ItemCtxt::new(tcx, def_id),
assoc_ty,
bounds,
SizedByDefault::Yes,
trait_item.span,
let assoc_ty = tcx.mk_projection(
tcx.hir().local_def_id(trait_item.hir_id).to_def_id(),
self_trait_ref.substs,
);
let predicates = bounds.predicates(tcx, assoc_ty);
associated_item_bounds(tcx, def_id, bounds, assoc_ty, trait_item.span)
}
if is_gat {
// We use shifts to get the regions that we're substituting to
// be bound by the binders in the `Predicate`s rather that
// escaping.
let shifted_in = ty::fold::shift_vars(tcx, &predicates, 1);
let substituted = shifted_in.subst(tcx, bound_substs);
ty::fold::shift_out_vars(tcx, &substituted, 1)
} else {
predicates
}
fn associated_item_bounds(
tcx: TyCtxt<'tcx>,
def_id: DefId,
bounds: &'tcx [hir::GenericBound<'tcx>],
projection_ty: Ty<'tcx>,
span: Span,
) -> Vec<(ty::Predicate<'tcx>, Span)> {
let bounds = AstConv::compute_bounds(
&ItemCtxt::new(tcx, def_id),
projection_ty,
bounds,
SizedByDefault::Yes,
span,
);
let predicates = bounds.predicates(tcx, projection_ty);
predicates
}
/// Converts a specific `GenericBound` from the AST into a set of

View File

@ -3,11 +3,9 @@
trait PointerFamily<U> {
type Pointer<T>: Deref<Target = T>;
//~^ ERROR generic associated types are unstable
//~| ERROR type-generic associated types are not yet implemented
type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
//~^ ERROR generic associated types are unstable
//~| ERROR where clauses on associated types are unstable
//~| ERROR type-generic associated types are not yet implemented
}
struct Foo;

View File

@ -8,7 +8,7 @@ LL | type Pointer<T>: Deref<Target = T>;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: generic associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:7:5
--> $DIR/feature-gate-generic_associated_types.rs:6:5
|
LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: where clauses on associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:7:5
--> $DIR/feature-gate-generic_associated_types.rs:6:5
|
LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: generic associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:16:5
--> $DIR/feature-gate-generic_associated_types.rs:14:5
|
LL | type Pointer<Usize> = Box<Usize>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -35,7 +35,7 @@ LL | type Pointer<Usize> = Box<Usize>;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: generic associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:18:5
--> $DIR/feature-gate-generic_associated_types.rs:16:5
|
LL | type Pointer2<U32> = Box<U32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -44,7 +44,7 @@ LL | type Pointer2<U32> = Box<U32>;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: where clauses on associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:23:5
--> $DIR/feature-gate-generic_associated_types.rs:21:5
|
LL | type Assoc where Self: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -53,7 +53,7 @@ LL | type Assoc where Self: Sized;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: where clauses on associated types are unstable
--> $DIR/feature-gate-generic_associated_types.rs:28:5
--> $DIR/feature-gate-generic_associated_types.rs:26:5
|
LL | type Assoc where Self: Sized = Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -61,22 +61,6 @@ LL | type Assoc where Self: Sized = Foo;
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error: type-generic associated types are not yet implemented
--> $DIR/feature-gate-generic_associated_types.rs:4:5
|
LL | type Pointer<T>: Deref<Target = T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/feature-gate-generic_associated_types.rs:7:5
|
LL | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 9 previous errors
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,72 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
#![feature(associated_type_defaults)]
// A Collection trait and collection families. Based on
// http://smallcultfollowing.com/babysteps/blog/2016/11/03/
// associated-type-constructors-part-2-family-traits/
// check that we don't normalize with trait defaults.
trait Collection<T> {
type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter;
type Family: CollectionFamily;
// Test associated type defaults with parameters
type Sibling<U>: Collection<U> =
<<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
fn empty() -> Self;
fn add(&mut self, value: T);
fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
}
trait CollectionFamily {
type Member<T>: Collection<T, Family = Self>;
}
struct VecFamily;
impl CollectionFamily for VecFamily {
type Member<T> = Vec<T>;
}
impl<T> Collection<T> for Vec<T> {
type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>;
type Family = VecFamily;
fn empty() -> Self {
Vec::new()
}
fn add(&mut self, value: T) {
self.push(value)
}
fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
self.iter()
}
}
fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
where
C: Collection<i32>,
{
let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
for &v in ints.iterate() {
res.add(v as f32);
}
res
//~^ ERROR mismatched types
}
fn use_floatify() {
let a = vec![1i32, 2, 3];
let c = floatify_sibling(&a);
assert_eq!(Some(&1.0), c.iterate().next());
}
fn main() {
use_floatify();
}

View File

@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/collections-project-default.rs:60:5
|
LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
| ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
...
LL | res
| ^^^ expected Collection::Sibling, found CollectionFamily::Member
|
= note: expected associated type `<C as Collection<i32>>::Sibling<f32>`
found associated type `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -6,13 +6,14 @@
// http://smallcultfollowing.com/babysteps/blog/2016/11/03/
// associated-type-constructors-part-2-family-traits/
// run-pass
trait Collection<T> {
type Iter<'iter>: Iterator<Item=&'iter T>;
type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter;
type Family: CollectionFamily;
// Test associated type defaults with parameters
type Sibling<U>: Collection<U> =
<<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
//~^^ ERROR type-generic associated types are not yet implemented
fn empty() -> Self;
@ -23,7 +24,6 @@ trait Collection<T> {
trait CollectionFamily {
type Member<T>: Collection<T, Family = Self>;
//~^ ERROR type-generic associated types are not yet implemented
}
struct VecFamily;
@ -33,7 +33,7 @@ impl CollectionFamily for VecFamily {
}
impl<T> Collection<T> for Vec<T> {
type Iter<'iter> = std::slice::Iter<'iter, T>;
type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>;
type Family = VecFamily;
fn empty() -> Self {
@ -53,18 +53,7 @@ fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>
where
C: Collection<i32>,
{
let mut res = C::Family::Member::<f32>::empty();
for &v in ints.iterate() {
res.add(v as f32);
}
res
}
fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
where
C: Collection<i32>,
{
let mut res = C::Family::Member::<f32>::empty();
let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
for &v in ints.iterate() {
res.add(v as f32);
}
@ -72,11 +61,11 @@ fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
}
fn use_floatify() {
let a = vec![1i32, 2, 3];
let b = floatify(a);
println!("{}", b.iterate().next());
let c = floatify_sibling(a);
println!("{}", c.iterate().next());
let a = vec![1, 2, 3];
let b = floatify(&a);
assert_eq!(Some(&1.0), b.iterate().next());
}
fn main() {}
fn main() {
use_floatify();
}

View File

@ -1,19 +0,0 @@
error: type-generic associated types are not yet implemented
--> $DIR/collections.rs:13:5
|
LL | / type Sibling<U>: Collection<U> =
LL | | <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
| |_________________________________________________________________________^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/collections.rs:25:5
|
LL | type Member<T>: Collection<T, Family = Self>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 2 previous errors

View File

@ -1,7 +1,7 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
// FIXME(#30472) normalize enough to handle this.
// check-pass
use std::ops::Deref;
@ -17,7 +17,6 @@ trait Baz {
}
impl<T> Baz for T where T: Foo {
//~^ ERROR type mismatch resolving
type Quux<'a> where T: 'a = T;
type Baa<'a> where T: 'a = &'a <T as Foo>::Bar<'a, 'static>;

View File

@ -1,18 +0,0 @@
error[E0271]: type mismatch resolving `for<'a> <<T as Baz>::Baa<'a> as std::ops::Deref>::Target == <<T as Baz>::Quux<'a> as Foo>::Bar<'a, 'static>`
--> $DIR/construct_with_other_type.rs:19:9
|
LL | impl<T> Baz for T where T: Foo {
| - ^^^ expected type parameter `T`, found associated type
| |
| this type parameter
|
= note: expected associated type `<T as Foo>::Bar<'_, 'static>`
found associated type `<<T as Baz>::Quux<'_> as Foo>::Bar<'_, 'static>`
help: consider further restricting this bound
|
LL | impl<T> Baz for T where T: Foo + Baz<Quux = T> {
| ^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.

View File

@ -6,7 +6,6 @@
trait MyTrait {
type Item<T>;
//~^ ERROR generic associated types are unstable [E0658]
//~| ERROR type-generic associated types are not yet implemented
}
impl MyTrait for Foo {

View File

@ -8,7 +8,7 @@ LL | type Item<T>;
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error[E0658]: generic associated types are unstable
--> $DIR/gat-dont-ice-on-absent-feature-2.rs:13:5
--> $DIR/gat-dont-ice-on-absent-feature-2.rs:12:5
|
LL | type Item<T> = T;
| ^^^^^^^^^^^^^^^^^
@ -16,14 +16,6 @@ LL | type Item<T> = T;
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error: type-generic associated types are not yet implemented
--> $DIR/gat-dont-ice-on-absent-feature-2.rs:7:5
|
LL | type Item<T>;
| ^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -9,11 +9,8 @@
trait Foo {
type Assoc where Self: Sized;
type Assoc2<T> where T: Display;
//~^ ERROR type-generic associated types are not yet implemented
type Assoc3<T>;
//~^ ERROR type-generic associated types are not yet implemented
type WithDefault<'a, T: Debug + 'a> = dyn Iterator<Item=T>;
//~^ ERROR type-generic associated types are not yet implemented
type WithDefault<'a, T: Debug + 'a>: ?Sized = dyn Iterator<Item=T>;
type NoGenerics;
}
@ -23,6 +20,7 @@ impl Foo for Bar {
type Assoc = usize;
type Assoc2<T> = Vec<T>;
type Assoc3<T> where T: Iterator = Vec<T>;
//~^ impl has stricter requirements than trait
type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item=T>;
type NoGenerics = ::std::cell::Cell<i32>;
}

View File

@ -1,26 +1,12 @@
error: type-generic associated types are not yet implemented
--> $DIR/generic-associated-types-where.rs:11:5
|
LL | type Assoc2<T> where T: Display;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/generic-associated-types-where.rs:13:5
error[E0276]: impl has stricter requirements than trait
--> $DIR/generic-associated-types-where.rs:22:5
|
LL | type Assoc3<T>;
| ^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
| --------------- definition of `Assoc3` from trait
...
LL | type Assoc3<T> where T: Iterator = Vec<T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: std::iter::Iterator`
error: type-generic associated types are not yet implemented
--> $DIR/generic-associated-types-where.rs:15:5
|
LL | type WithDefault<'a, T: Debug + 'a> = dyn Iterator<Item=T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 3 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0276`.

View File

@ -5,13 +5,13 @@
trait Foo {
type Assoc3<T>;
//~^ type-generic associated types are not yet implemented
}
struct Bar;
impl Foo for Bar {
type Assoc3<T> where T: Iterator = Vec<T>;
//~^ ERROR impl has stricter requirements than trait
}
fn main() {}

View File

@ -1,10 +1,12 @@
error: type-generic associated types are not yet implemented
--> $DIR/issue-47206-where-clause.rs:7:5
error[E0276]: impl has stricter requirements than trait
--> $DIR/issue-47206-where-clause.rs:13:5
|
LL | type Assoc3<T>;
| ^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
| --------------- definition of `Assoc3` from trait
...
LL | type Assoc3<T> where T: Iterator = Vec<T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: std::iter::Iterator`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0276`.

View File

@ -1,11 +1,14 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
// FIXME(generic-associated-types) Investigate why this doesn't compile.
// check-pass
trait Iterator {
type Item<'a>: 'a;
//~^ ERROR the requirement `for<'a> <Self as Iterator>::Item<'a>: 'a` is not satisfied
}
impl Iterator for () {
type Item<'a> = &'a ();
}
fn main() {}

View File

@ -1,10 +0,0 @@
error[E0280]: the requirement `for<'a> <Self as Iterator>::Item<'a>: 'a` is not satisfied
--> $DIR/issue-62326-parameter-out-of-range.rs:7:20
|
LL | trait Iterator {
| -------- required by a bound in this
LL | type Item<'a>: 'a;
| ^^ required by this bound in `Iterator`
error: aborting due to previous error

View File

@ -7,7 +7,6 @@ trait Trait1 {
trait Trait2 {
type Type1<B>: Trait1<A=B>;
//~^ ERROR: generic associated types are unstable
//~| ERROR: type-generic associated types are not yet implemented
}
fn main() {}

View File

@ -7,14 +7,6 @@ LL | type Type1<B>: Trait1<A=B>;
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
= help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
error: type-generic associated types are not yet implemented
--> $DIR/issue-67424.rs:8:5
|
LL | type Type1<B>: Trait1<A=B>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> $DIR/issue-68641-check-gat-bounds.rs:15:5
|
LL | trait UnsafeCopy {
| ---------------- required by `UnsafeCopy`
LL | type Item<'a>: Copy;
| -------------------- required by `UnsafeCopy::Item`
...
LL | type Item<'a> = T;
| ^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0277]: expected a `std::ops::Fn<()>` closure, found `T`
--> $DIR/issue-68642-broken-llvm-ir.rs:15:5
|
LL | trait Fun {
| --------- required by `Fun`
LL | type F<'a>: Fn() -> u32;
| ------------------------ required by `Fun::F`
...
LL | type F<'a> = Self;
| ^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `T`

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0277]: expected a `std::ops::Fn<()>` closure, found `T`
--> $DIR/issue-68643-broken-mir.rs:15:5
|
LL | trait Fun {
| --------- required by `Fun`
LL | type F<'a>: Fn() -> u32;
| ------------------------ required by `Fun::F`
...
LL | type F<'a> = Self;
| ^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `T`

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0277]: expected a `std::ops::Fn<()>` closure, found `T`
--> $DIR/issue-68644-codegen-selection.rs:15:5
|
LL | trait Fun {
| --------- required by `Fun`
LL | type F<'a>: Fn() -> u32;
| ------------------------ required by `Fun::F`
...
LL | type F<'a> = Self;
| ^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `T`

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0277]: expected a `std::ops::Fn<()>` closure, found `T`
--> $DIR/issue-68645-codegen-fulfillment.rs:15:5
|
LL | trait Fun {
| --------- required by `Fun`
LL | type F<'a>: Fn() -> u32;
| ------------------------ required by `Fun::F`
...
LL | type F<'a> = Self;
| ^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `T`

View File

@ -10,8 +10,8 @@ LL | #![feature(generic_associated_types)]
error[E0271]: type mismatch resolving `<T as std::ops::Deref>::Target == T`
--> $DIR/issue-68656-unsized-values.rs:16:5
|
LL | trait UnsafeCopy<T: Copy> {
| ------------------------- required by `UnsafeCopy`
LL | type Item<'a>: std::ops::Deref<Target = T>;
| ------------------------------------------- required by `UnsafeCopy::Item`
...
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<T> for T {
| - this type parameter

View File

@ -1,7 +1,7 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
// FIXME(#30472) normalize enough to handle this.
// run-pass
trait Iterable {
type Item<'a> where Self: 'a;
@ -13,39 +13,35 @@ trait Iterable {
// Impl for struct type
impl<T> Iterable for Vec<T> {
type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
//~^ ERROR type mismatch resolving
type Iter<'a> where T: 'a = std::slice::Iter<'a, T>;
fn iter<'a>(&'a self) -> Self::Iter<'a> {
//~^ ERROR type mismatch resolving
self.iter()
self[..].iter()
}
}
// Impl for a primitive type
impl<T> Iterable for [T] {
type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
//~^ ERROR type mismatch resolving
type Iter<'a> where T: 'a = std::slice::Iter<'a, T>;
fn iter<'a>(&'a self) -> Self::Iter<'a> {
//~^ ERROR type mismatch resolving
self.iter()
}
}
fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> {
fn make_iter<'a, I: Iterable + ?Sized>(it: &'a I) -> I::Iter<'a> {
it.iter()
}
fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> {
fn get_first<'a, I: Iterable + ?Sized>(it: &'a I) -> Option<I::Item<'a>> {
it.iter().next()
}
fn main() {
let v = vec![1, 2, 3];
assert_eq!(v, make_iter(&v).copied().collect());
assert_eq!(v, make_iter(&*v).copied().collect());
assert_eq!(1, get_first(&v));
assert_eq!(1, get_first(&*v));
assert_eq!(v, make_iter(&v).copied().collect::<Vec<_>>());
assert_eq!(v, make_iter(&*v).copied().collect::<Vec<_>>());
assert_eq!(Some(&1), get_first(&v));
assert_eq!(Some(&1), get_first(&*v));
}

View File

@ -1,59 +0,0 @@
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
--> $DIR/iterable.rs:15:33
|
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
= note: expected reference `&T`
found associated type `<std::vec::Vec<T> as Iterable>::Item<'_>`
= help: consider constraining the associated type `<std::vec::Vec<T> as Iterable>::Item<'_>` to `&_`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
--> $DIR/iterable.rs:27:33
|
LL | type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
|
= note: expected reference `&T`
found associated type `<[T] as Iterable>::Item<'_>`
= help: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
--> $DIR/iterable.rs:19:30
|
LL | trait Iterable {
| -------- required by a bound in this
LL | type Item<'a> where Self: 'a;
LL | type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
| --------------------- required by this bound in `Iterable`
...
LL | fn iter<'a>(&'a self) -> Self::Iter<'a> {
| ^^^^^^^^^^^^^^ expected associated type, found reference
|
= note: expected associated type `<std::vec::Vec<T> as Iterable>::Item<'_>`
found reference `&T`
= help: consider constraining the associated type `<std::vec::Vec<T> as Iterable>::Item<'_>` to `&_` or calling a method that returns `<std::vec::Vec<T> as Iterable>::Item<'_>`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
--> $DIR/iterable.rs:31:30
|
LL | trait Iterable {
| -------- required by a bound in this
LL | type Item<'a> where Self: 'a;
LL | type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
| --------------------- required by this bound in `Iterable`
...
LL | fn iter<'a>(&'a self) -> Self::Iter<'a> {
| ^^^^^^^^^^^^^^ expected associated type, found reference
|
= note: expected associated type `<[T] as Iterable>::Item<'_>`
found reference `&T`
= help: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_` or calling a method that returns `<[T] as Iterable>::Item<'_>`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0271`.

View File

@ -34,12 +34,11 @@ impl<B: std::ops::Add<Output = B>> Add for D<B> {
struct E<B>(B);
impl<B: Add> Add for E<B> where B: Add<Output = B>, B: std::ops::Add<Output = B> {
//~^ ERROR equality constraints are not yet supported in `where` clauses
impl<B: Add> Add for E<B> where B: Add<Output = B> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self(self.0 + rhs.0) //~ ERROR mismatched types
Self(self.0 + rhs.0)
}
}

View File

@ -34,12 +34,11 @@ fn add(self, rhs: Self) -> Self {
struct E<B>(B);
impl<B: Add> Add for E<B> where <B as Add>::Output = B {
//~^ ERROR equality constraints are not yet supported in `where` clauses
impl<B: Add> Add for E<B> where B: Add<Output = B> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self(self.0 + rhs.0) //~ ERROR mismatched types
Self(self.0 + rhs.0)
}
}

View File

@ -1,15 +1,3 @@
error: equality constraints are not yet supported in `where` clauses
--> $DIR/missing-bounds.rs:37:33
|
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
help: if `Output` is an associated type you're trying to set, use the associated type binding syntax
|
LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
| ^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/missing-bounds.rs:11:11
|
@ -55,23 +43,7 @@ help: consider restricting type parameter `B`
LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/missing-bounds.rs:42:14
|
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
| - this type parameter
...
LL | Self(self.0 + rhs.0)
| ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<B as std::ops::Add>::Output`
help: consider further restricting type parameter `B`
|
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: std::ops::Add<Output = B> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0369.
For more information about an error, try `rustc --explain E0308`.

View File

@ -7,18 +7,14 @@ trait Foo {
type B<'a, 'b>;
type C;
type D<T>;
//~^ ERROR type-generic associated types are not yet implemented
type E<'a, T>;
//~^ ERROR type-generic associated types are not yet implemented
// Test parameters in default values
type FOk<T> = Self::E<'static, T>;
//~^ ERROR type-generic associated types are not yet implemented
type FErr1 = Self::E<'static, 'static>;
//~^ ERROR wrong number of lifetime arguments: expected 1, found 2
//~| ERROR wrong number of type arguments: expected 1, found 0
type FErr2<T> = Self::E<'static, T, u32>;
//~^ ERROR type-generic associated types are not yet implemented
//~| ERROR wrong number of type arguments: expected 1, found 2
//~^ ERROR wrong number of type arguments: expected 1, found 2
}
fn main() {}

View File

@ -1,53 +1,21 @@
error: type-generic associated types are not yet implemented
--> $DIR/parameter_number_and_kind.rs:9:5
|
LL | type D<T>;
| ^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/parameter_number_and_kind.rs:11:5
|
LL | type E<'a, T>;
| ^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/parameter_number_and_kind.rs:14:5
|
LL | type FOk<T> = Self::E<'static, T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/parameter_number_and_kind.rs:19:5
|
LL | type FErr2<T> = Self::E<'static, T, u32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0107]: wrong number of lifetime arguments: expected 1, found 2
--> $DIR/parameter_number_and_kind.rs:16:35
--> $DIR/parameter_number_and_kind.rs:13:35
|
LL | type FErr1 = Self::E<'static, 'static>;
| ^^^^^^^ unexpected lifetime argument
error[E0107]: wrong number of type arguments: expected 1, found 0
--> $DIR/parameter_number_and_kind.rs:16:18
--> $DIR/parameter_number_and_kind.rs:13:18
|
LL | type FErr1 = Self::E<'static, 'static>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 type argument
error[E0107]: wrong number of type arguments: expected 1, found 2
--> $DIR/parameter_number_and_kind.rs:19:41
--> $DIR/parameter_number_and_kind.rs:16:41
|
LL | type FErr2<T> = Self::E<'static, T, u32>;
| ^^^ unexpected type argument
error: aborting due to 7 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0107`.

View File

@ -1,7 +1,7 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
// FIXME(#44265): allow type-generic associated types.
// check-pass
use std::rc::Rc;
use std::sync::Arc;
@ -9,7 +9,6 @@
trait PointerFamily {
type Pointer<T>: Deref<Target = T>;
//~^ ERROR type-generic associated types are not yet implemented
fn new<T>(value: T) -> Self::Pointer<T>;
}

View File

@ -1,10 +0,0 @@
error: type-generic associated types are not yet implemented
--> $DIR/pointer_family.rs:11:5
|
LL | type Pointer<T>: Deref<Target = T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to previous error

View File

@ -18,12 +18,10 @@ impl<'a> NoShadow<'a> for &'a u32 {
trait ShadowT<T> {
type Bar<T>;
//~^ ERROR the name `T` is already used
//~| ERROR type-generic associated types are not yet implemented
}
trait NoShadowT<T> {
type Bar<U>; // OK
//~^ ERROR type-generic associated types are not yet implemented
}
impl<T> NoShadowT<T> for Option<T> {

View File

@ -7,7 +7,7 @@ LL | type Bar<T>;
| ^ already used
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowing.rs:30:14
--> $DIR/shadowing.rs:28:14
|
LL | impl<T> NoShadowT<T> for Option<T> {
| - first use of `T`
@ -30,23 +30,7 @@ LL | impl<'a> NoShadow<'a> for &'a u32 {
LL | type Bar<'a> = i32;
| ^^ lifetime 'a already in scope
error: type-generic associated types are not yet implemented
--> $DIR/shadowing.rs:19:5
|
LL | type Bar<T>;
| ^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: type-generic associated types are not yet implemented
--> $DIR/shadowing.rs:25:5
|
LL | type Bar<U>; // OK
| ^^^^^^^^^^^^
|
= note: for more information, see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error: aborting due to 6 previous errors
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0403, E0496.
For more information about an error, try `rustc --explain E0403`.

View File

@ -0,0 +1,22 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
trait ATy {
type Item<'a>: 'a;
}
impl<'b> ATy for &'b () {
type Item<'a> = &'b ();
//~^ ERROR does not fulfill the required lifetime
}
trait StaticTy {
type Item<'a>: 'static;
}
impl StaticTy for () {
type Item<'a> = &'a ();
//~^ ERROR does not fulfill the required lifetime
}
fn main() {}

View File

@ -0,0 +1,23 @@
error[E0477]: the type `&'b ()` does not fulfill the required lifetime
--> $DIR/unsatisfied-outlives-bound.rs:9:5
|
LL | type Item<'a> = &'b ();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must outlive the lifetime `'a` as defined on the associated item at 9:15
--> $DIR/unsatisfied-outlives-bound.rs:9:15
|
LL | type Item<'a> = &'b ();
| ^^
error[E0477]: the type `&'a ()` does not fulfill the required lifetime
--> $DIR/unsatisfied-outlives-bound.rs:18:5
|
LL | type Item<'a> = &'a ();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: type must satisfy the static lifetime
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0477`.

View File

@ -1,5 +1,5 @@
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-38091.rs:2:12
--> $DIR/issue-38091.rs:1:12
|
LL | #![feature(specialization)]
| ^^^^^^^^^^^^^^
@ -8,14 +8,14 @@ LL | #![feature(specialization)]
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
error[E0277]: the trait bound `(): Valid` is not satisfied
--> $DIR/issue-38091.rs:8:5
--> $DIR/issue-38091.rs:9:5
|
LL | trait Iterate<'a> {
| ----------------- required by `Iterate`
LL | type Ty: Valid;
| --------------- required by `Iterate::Ty`
...
LL | default type Ty = ();
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Valid` is not implemented for `()`
error: aborting due to previous error
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0277`.

View File

@ -10,8 +10,8 @@ LL | #![feature(specialization)]
error[E0277]: the trait bound `str: std::clone::Clone` is not satisfied
--> $DIR/deafult-associated-type-bound-1.rs:18:5
|
LL | trait X {
| ------- required by `X`
LL | type U: Clone;
| -------------- required by `X::U`
...
LL | default type U = str;
| ^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `str`

View File

@ -10,8 +10,8 @@ LL | #![feature(specialization)]
error[E0277]: can't compare `&'static B` with `B`
--> $DIR/deafult-associated-type-bound-2.rs:16:5
|
LL | trait X<T> {
| ---------- required by `X`
LL | type U: PartialEq<T>;
| --------------------- required by `X::U`
...
LL | default type U = &'static B;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `&'static B == B`

View File

@ -18,14 +18,14 @@ LL | #![feature(generic_associated_types)]
error[E0277]: can't compare `T` with `T`
--> $DIR/deafult-generic-associated-type-bound.rs:19:5
|
LL | trait X {
| ------- required by `X`
LL | type U<'a>: PartialEq<&'a Self>;
| -------------------------------- required by `X::U`
...
LL | default type U<'a> = &'a T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `T == T`
|
= help: the trait `std::cmp::PartialEq` is not implemented for `T`
= note: required because of the requirements on the impl of `for<'a> std::cmp::PartialEq` for `&'a T`
= note: required because of the requirements on the impl of `std::cmp::PartialEq` for `&'a T`
help: consider further restricting this bound
|
LL | impl<T: 'static + std::cmp::PartialEq> X for T {