From 52b00db2351ca8a6902bcd99bac20408eb09a6c6 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:56:18 -0400 Subject: [PATCH] Make GATs object safe under generic_associated_types_extended feature --- .../src/traits/object_safety.rs | 22 +++--- .../src/traits/select/confirmation.rs | 70 +++++++++++++++++-- ...h.stderr => gat-in-trait-path.base.stderr} | 4 +- .../gat-in-trait-path.rs | 8 ++- ...ss.stderr => issue-67510-pass.base.stderr} | 4 +- .../issue-67510-pass.rs | 8 ++- ...e-76535.stderr => issue-76535.base.stderr} | 12 ++-- .../issue-76535.extended.stderr | 19 +++++ .../generic-associated-types/issue-76535.rs | 8 ++- ...e-78671.stderr => issue-78671.base.stderr} | 8 +-- .../issue-78671.extended.stderr | 19 +++++ .../generic-associated-types/issue-78671.rs | 6 +- ...e-79422.stderr => issue-79422.base.stderr} | 12 ++-- .../issue-79422.extended.stderr | 35 ++++++++++ .../generic-associated-types/issue-79422.rs | 9 ++- ...jects.stderr => trait-objects.base.stderr} | 4 +- .../trait-objects.extended.nll.stderr | 17 +++++ .../trait-objects.extended.stderr | 12 ++++ .../generic-associated-types/trait-objects.rs | 7 +- 19 files changed, 240 insertions(+), 44 deletions(-) rename src/test/ui/generic-associated-types/{gat-in-trait-path.stderr => gat-in-trait-path.base.stderr} (91%) rename src/test/ui/generic-associated-types/{issue-67510-pass.stderr => issue-67510-pass.base.stderr} (90%) rename src/test/ui/generic-associated-types/{issue-76535.stderr => issue-76535.base.stderr} (93%) create mode 100644 src/test/ui/generic-associated-types/issue-76535.extended.stderr rename src/test/ui/generic-associated-types/{issue-78671.stderr => issue-78671.base.stderr} (91%) create mode 100644 src/test/ui/generic-associated-types/issue-78671.extended.stderr rename src/test/ui/generic-associated-types/{issue-79422.stderr => issue-79422.base.stderr} (93%) create mode 100644 src/test/ui/generic-associated-types/issue-79422.extended.stderr rename src/test/ui/generic-associated-types/{trait-objects.stderr => trait-objects.base.stderr} (93%) create mode 100644 src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr create mode 100644 src/test/ui/generic-associated-types/trait-objects.extended.stderr diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 6cceec86213..54f7c68060f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -131,16 +131,18 @@ fn object_safety_violations_for_trait( }), ); - violations.extend( - tcx.associated_items(trait_def_id) - .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Type) - .filter(|item| !tcx.generics_of(item.def_id).params.is_empty()) - .map(|item| { - let ident = item.ident(tcx); - ObjectSafetyViolation::GAT(ident.name, ident.span) - }), - ); + if !tcx.features().generic_associated_types_extended { + violations.extend( + tcx.associated_items(trait_def_id) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| !tcx.generics_of(item.def_id).params.is_empty()) + .map(|item| { + let ident = item.ident(tcx); + ObjectSafetyViolation::GAT(ident.name, ident.span) + }), + ); + } debug!( "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9c871eea1cd..18a37759543 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -11,8 +11,8 @@ use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty}; use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; use rustc_span::def_id::DefId; @@ -487,18 +487,80 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .collect(); 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( obligation.cause.span, "GATs in trait object shouldn't have been considered", ); return Err(SelectionError::Unimplemented); } + // This maybe belongs in wf, but that can't (doesn't) handle // higher-ranked things. // Prevent, e.g., `dyn Iterator`. 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( self, obligation.param_env, diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr similarity index 91% rename from src/test/ui/generic-associated-types/gat-in-trait-path.stderr rename to src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr index a55642490f9..c2054f64e2d 100644 --- a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr @@ -1,11 +1,11 @@ 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 Foo = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/gat-in-trait-path.rs:5:10 + --> $DIR/gat-in-trait-path.rs:11:10 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.rs b/src/test/ui/generic-associated-types/gat-in-trait-path.rs index 7bbcf950ae1..c82450ccff1 100644 --- a/src/test/ui/generic-associated-types/gat-in-trait-path.rs +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.rs @@ -1,5 +1,11 @@ +// revisions: base extended +//[base] check-fail +//[extended] check-pass + #![feature(generic_associated_types)] #![feature(associated_type_defaults)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] trait Foo { type A<'a> where Self: 'a; @@ -19,7 +25,7 @@ impl Foo for Fooer { } fn f(_arg : Box Foo = &'a ()>>) {} -//~^ the trait `Foo` cannot be made into an object +//[base]~^ the trait `Foo` cannot be made into an object fn main() { diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr similarity index 90% rename from src/test/ui/generic-associated-types/issue-67510-pass.stderr rename to src/test/ui/generic-associated-types/issue-67510-pass.base.stderr index 7dd1bdf891e..74a616aaabe 100644 --- a/src/test/ui/generic-associated-types/issue-67510-pass.stderr +++ b/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr @@ -1,11 +1,11 @@ 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=&'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-67510-pass.rs:4:10 + --> $DIR/issue-67510-pass.rs:10:10 | LL | trait X { | - this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.rs b/src/test/ui/generic-associated-types/issue-67510-pass.rs index 99f0e84fa6d..c5b02ff9a64 100644 --- a/src/test/ui/generic-associated-types/issue-67510-pass.rs +++ b/src/test/ui/generic-associated-types/issue-67510-pass.rs @@ -1,10 +1,16 @@ +// revisions: base extended +//[base] check-fail +//[extended] check-pass + #![feature(generic_associated_types)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] trait X { type Y<'a>; } fn _func1<'a>(_x: Box=&'a ()>>) {} -//~^ ERROR the trait `X` cannot be made into an object +//[base]~^ ERROR the trait `X` cannot be made into an object fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.base.stderr similarity index 93% rename from src/test/ui/generic-associated-types/issue-76535.stderr rename to src/test/ui/generic-associated-types/issue-76535.base.stderr index 64eeec1b2fc..5decd58bbcd 100644 --- a/src/test/ui/generic-associated-types/issue-76535.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.base.stderr @@ -1,11 +1,11 @@ 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> = Box::new(SuperStruct::new(0)); | ^^^^^^^ expected 1 lifetime argument | 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; | ^^^^^^^ -- @@ -15,13 +15,13 @@ LL | let sub: Box = SubStruct>> = Box::new(SuperS | ~~~~~~~~~~~ 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> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-76535.rs:6:10 + --> $DIR/issue-76535.rs:10:10 | LL | pub trait SuperTrait { | ---------- 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 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> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-76535.rs:6:10 + --> $DIR/issue-76535.rs:10:10 | LL | pub trait SuperTrait { | ---------- this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/issue-76535.extended.stderr b/src/test/ui/generic-associated-types/issue-76535.extended.stderr new file mode 100644 index 00000000000..067d0489b48 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-76535.extended.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for associated type `SuperTrait::SubType` + --> $DIR/issue-76535.rs:40:33 + | +LL | let sub: Box> = 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 = SubStruct>> = Box::new(SuperStruct::new(0)); + | ~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs index 20c6924afa6..46f217ba06b 100644 --- a/src/test/ui/generic-associated-types/issue-76535.rs +++ b/src/test/ui/generic-associated-types/issue-76535.rs @@ -1,4 +1,8 @@ +// revisions: base extended + #![feature(generic_associated_types)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] pub trait SubTrait {} @@ -35,6 +39,6 @@ impl SuperTrait for SuperStruct { fn main() { let sub: Box> = Box::new(SuperStruct::new(0)); //~^ ERROR missing generics for associated type - //~^^ ERROR the trait - //~| ERROR the trait + //[base]~^^ ERROR the trait + //[base]~| ERROR the trait } diff --git a/src/test/ui/generic-associated-types/issue-78671.stderr b/src/test/ui/generic-associated-types/issue-78671.base.stderr similarity index 91% rename from src/test/ui/generic-associated-types/issue-78671.stderr rename to src/test/ui/generic-associated-types/issue-78671.base.stderr index 17dd0ff4a0c..6bcd004b1a9 100644 --- a/src/test/ui/generic-associated-types/issue-78671.stderr +++ b/src/test/ui/generic-associated-types/issue-78671.base.stderr @@ -1,11 +1,11 @@ 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 | ^^^^^^ expected 1 generic argument | 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; | ^^^^^^ - @@ -15,13 +15,13 @@ LL | Box::new(Family) as &dyn CollectionFamily=usize> | ~~~~~~~~~ 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 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-78671.rs:4:10 + --> $DIR/issue-78671.rs:8:10 | LL | trait CollectionFamily { | ---------------- this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/issue-78671.extended.stderr b/src/test/ui/generic-associated-types/issue-78671.extended.stderr new file mode 100644 index 00000000000..f1b48933516 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-78671.extended.stderr @@ -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 + | ^^^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-78671.rs:8:10 + | +LL | type Member; + | ^^^^^^ - +help: add missing generic argument + | +LL | Box::new(Family) as &dyn CollectionFamily=usize> + | ~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-78671.rs b/src/test/ui/generic-associated-types/issue-78671.rs index 7ccf376e5cb..c09dac28bda 100644 --- a/src/test/ui/generic-associated-types/issue-78671.rs +++ b/src/test/ui/generic-associated-types/issue-78671.rs @@ -1,4 +1,8 @@ +// revisions: base extended + #![feature(generic_associated_types)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] trait CollectionFamily { type Member; @@ -6,7 +10,7 @@ trait CollectionFamily { fn floatify() { Box::new(Family) as &dyn CollectionFamily //~^ 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; diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.base.stderr similarity index 93% rename from src/test/ui/generic-associated-types/issue-79422.stderr rename to src/test/ui/generic-associated-types/issue-79422.base.stderr index 8b6f9b866e5..404c975d64a 100644 --- a/src/test/ui/generic-associated-types/issue-79422.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.base.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for associated type `MapLike::VRefCont` - --> $DIR/issue-79422.rs:42:36 + --> $DIR/issue-79422.rs:48:36 | LL | as Box>>; | ^^^^^^^^ expected 1 lifetime argument | 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; | ^^^^^^^^ -- @@ -15,13 +15,13 @@ LL | as Box = dyn RefCont<'_, u8>>>; | ~~~~~~~~~~~~ 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>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-79422.rs:20:10 + --> $DIR/issue-79422.rs:24:10 | LL | trait MapLike { | ------- 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 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::::new()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/issue-79422.rs:20:10 + --> $DIR/issue-79422.rs:24:10 | LL | trait MapLike { | ------- this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/issue-79422.extended.stderr b/src/test/ui/generic-associated-types/issue-79422.extended.stderr new file mode 100644 index 00000000000..9478fc89792 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-79422.extended.stderr @@ -0,0 +1,35 @@ +error[E0107]: missing generics for associated type `MapLike::VRefCont` + --> $DIR/issue-79422.rs:48:36 + | +LL | as Box>>; + | ^^^^^^^^ 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 RefCont<'_, u8>>>; + | ~~~~~~~~~~~~ + +error[E0271]: type mismatch resolving ` as MapLike>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)` + --> $DIR/issue-79422.rs:45:13 + | +LL | let m = Box::new(std::collections::BTreeMap::::new()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as MapLike>::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 + '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`. diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs index b9a3c583f7c..7749975e687 100644 --- a/src/test/ui/generic-associated-types/issue-79422.rs +++ b/src/test/ui/generic-associated-types/issue-79422.rs @@ -1,4 +1,8 @@ +// revisions: base extended + #![feature(generic_associated_types)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] trait RefCont<'a, T> { fn t(&'a self) -> &'a T; @@ -39,8 +43,9 @@ impl MapLike for Source { fn main() { let m = Box::new(std::collections::BTreeMap::::new()) + //[base]~^ ERROR the trait + //[extended]~^^ type mismatch as Box>>; //~^ ERROR missing generics for associated type - //~^^ ERROR the trait - //~^^^^ ERROR the trait + //[base]~^^ ERROR the trait } diff --git a/src/test/ui/generic-associated-types/trait-objects.stderr b/src/test/ui/generic-associated-types/trait-objects.base.stderr similarity index 93% rename from src/test/ui/generic-associated-types/trait-objects.stderr rename to src/test/ui/generic-associated-types/trait-objects.base.stderr index 5ab37910207..1df76a21bf9 100644 --- a/src/test/ui/generic-associated-types/trait-objects.stderr +++ b/src/test/ui/generic-associated-types/trait-objects.base.stderr @@ -1,11 +1,11 @@ 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 = &'a i32>) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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 - --> $DIR/trait-objects.rs:4:10 + --> $DIR/trait-objects.rs:8:10 | LL | trait StreamingIterator { | ----------------- this trait cannot be made into an object... diff --git a/src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr b/src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr new file mode 100644 index 00000000000..52d48d57859 --- /dev/null +++ b/src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr @@ -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 = &'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`. diff --git a/src/test/ui/generic-associated-types/trait-objects.extended.stderr b/src/test/ui/generic-associated-types/trait-objects.extended.stderr new file mode 100644 index 00000000000..7cc3dad9921 --- /dev/null +++ b/src/test/ui/generic-associated-types/trait-objects.extended.stderr @@ -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 = &'a i32>) -> usize { + | ------------------------------------------------------ help: add explicit lifetime `'a` to the type of `x`: `&'a mut (dyn StreamingIterator 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`. diff --git a/src/test/ui/generic-associated-types/trait-objects.rs b/src/test/ui/generic-associated-types/trait-objects.rs index 559e6758a32..644e56ce21f 100644 --- a/src/test/ui/generic-associated-types/trait-objects.rs +++ b/src/test/ui/generic-associated-types/trait-objects.rs @@ -1,4 +1,8 @@ +// revisions: base extended + #![feature(generic_associated_types)] +#![cfg_attr(extended, feature(generic_associated_types_extended))] +#![cfg_attr(extended, allow(incomplete_features))] trait StreamingIterator { type Item<'a> where Self: 'a; @@ -8,8 +12,9 @@ trait StreamingIterator { } fn min_size(x: &mut dyn for<'a> StreamingIterator = &'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 + //[extended]~^ explicit lifetime required } fn main() {}