diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index d4c7d752c953f..aaea3b4820b35 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -329,6 +329,14 @@ impl<'tcx> Generalizer<'_, 'tcx> {
         }
     }
 
+    /// Create a new type variable in the universe of the target when
+    /// generalizing an alias. This has to set `has_unconstrained_ty_var`
+    /// if we're currently in a bivariant context.
+    fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> {
+        self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant;
+        self.infcx.next_ty_var_in_universe(self.span, self.for_universe)
+    }
+
     /// An occurs check failure inside of an alias does not mean
     /// that the types definitely don't unify. We may be able
     /// to normalize the alias after all.
@@ -358,7 +366,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
         //
         // cc trait-system-refactor-initiative#110
         if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
-            return Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe));
+            return Ok(self.next_ty_var_for_alias());
         }
 
         let is_nested_alias = mem::replace(&mut self.in_alias, true);
@@ -378,7 +386,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
                     }
 
                     debug!("generalization failure in alias");
-                    Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe))
+                    Ok(self.next_ty_var_for_alias())
                 }
             }
         };
diff --git a/tests/ui/traits/next-solver/generalize/bivariant-alias.rs b/tests/ui/traits/next-solver/generalize/bivariant-alias.rs
new file mode 100644
index 0000000000000..b03d547838a01
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/bivariant-alias.rs
@@ -0,0 +1,20 @@
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// When generalizing an alias in a bivariant context, we have to set
+// `has_unconstrained_ty_var` as we may otherwise never check for
+// well-formedness of the generalized type, causing us to error due
+// to ambiguity.
+trait Trait {
+    type Assoc;
+}
+
+struct BivariantArg<I, T: Trait<Assoc = I>>(T);
+
+fn generalize<T: Trait>(input: BivariantArg<T::Assoc, T>) {
+    let _generalized = input;
+}
+
+pub fn main() {}