about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJack Huey <31162821+jackh726@users.noreply.github.com>2022-03-13 11:56:18 -0400
committerJack Huey <31162821+jackh726@users.noreply.github.com>2022-04-02 14:01:17 -0400
commit52b00db2351ca8a6902bcd99bac20408eb09a6c6 (patch)
tree0ef3056daf94f093886a5920ec4a8976b0a9b45e
parent0677edc86e342f333d4828b0ee1ef395a4e70fe5 (diff)
downloadrust-52b00db2351ca8a6902bcd99bac20408eb09a6c6.tar.gz
rust-52b00db2351ca8a6902bcd99bac20408eb09a6c6.zip
Make GATs object safe under generic_associated_types_extended feature
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs70
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr (renamed from src/test/ui/generic-associated-types/gat-in-trait-path.stderr)4
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.rs8
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.base.stderr (renamed from src/test/ui/generic-associated-types/issue-67510-pass.stderr)4
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.rs8
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.base.stderr (renamed from src/test/ui/generic-associated-types/issue-76535.stderr)12
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.extended.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.rs8
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.base.stderr (renamed from src/test/ui/generic-associated-types/issue-78671.stderr)8
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.extended.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.rs6
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.base.stderr (renamed from src/test/ui/generic-associated-types/issue-79422.stderr)12
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.extended.stderr35
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.rs9
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.base.stderr (renamed from src/test/ui/generic-associated-types/trait-objects.stderr)4
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.extended.nll.stderr17
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.extended.stderr12
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.rs7
19 files changed, 240 insertions, 44 deletions
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<Item = str>`.
             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
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<dyn for<'a> Foo<A<'a> = &'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 <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 {
    |       --- 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<T> Foo for Fooer<T> {
 }
 
 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() {
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
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<dyn X<Y<'a>=&'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 <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 {
    |       - 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<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() {}
diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/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<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:6:10
+  --> $DIR/issue-76535.rs:10:10
    |
 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
-  --> $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));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
-  --> $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<dyn SuperTrait<SubType = SubStruct>> = 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 <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 {
    |           ---------- 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<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`.
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<dyn SuperTrait<SubType = SubStruct>> = 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
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<Member=usize>
    |                                               ^^^^^^ 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<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
-  --> $DIR/issue-78671.rs:7:25
+  --> $DIR/issue-78671.rs:11:25
    |
 LL |     Box::new(Family) as &dyn CollectionFamily<Member=usize>
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
-  --> $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<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`.
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<T>;
@@ -6,7 +10,7 @@ trait CollectionFamily {
 fn floatify() {
     Box::new(Family) as &dyn CollectionFamily<Member=usize>
     //~^ 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
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<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: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 MapLike<u8, u8, VRefCont<'a> = 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<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>
-  --> $DIR/issue-79422.rs:20:10
+  --> $DIR/issue-79422.rs:24:10
    |
 LL | trait MapLike<K, V> {
    |       ------- 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::<u8, u8>::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 <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> {
    |       ------- 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<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`.
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<K, V: Default> MapLike<K, V> for Source {
 
 fn main() {
     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>>>;
       //~^ 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
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<Item<'a> = &'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 <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 {
    |       ----------------- 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<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`.
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<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`.
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<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
+    //[extended]~^ explicit lifetime required
 }
 
 fn main() {}