Skip to content

Commit aafb23b

Browse files
committed
nyaaa
1 parent 56229b3 commit aafb23b

File tree

5 files changed

+56
-88
lines changed

5 files changed

+56
-88
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,14 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
311311
b_arg: ty::GenericArgsRef<'tcx>,
312312
f: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
313313
) -> RelateResult<'tcx, Ty<'tcx>> {
314-
// FIXME: We could avoid fetching the variances if we're currently in an
315-
// invariant context.
316-
let variances = self.cx().variances_of(item_def_id);
314+
let tcx = self.cx();
315+
let variances = tcx.variances_of(item_def_id);
317316
let args = relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, true)?;
318-
Ok(f(args))
317+
let ty = f(args);
318+
if variances.iter().any(|&v| v == ty::Bivariant) {
319+
self.register_predicates([ty::ClauseKind::WellFormed(ty.into())]);
320+
}
321+
Ok(ty)
319322
}
320323

321324
#[instrument(skip(self, info), level = "trace", ret)]

compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 19 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,13 @@ impl<'tcx> InferCtxt<'tcx> {
7070
//
7171
// We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
7272
// `?1 <: ?3`.
73-
let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } = self
74-
.generalize(
75-
relation.span(),
76-
relation.structurally_relate_aliases(),
77-
target_vid,
78-
instantiation_variance,
79-
source_ty,
80-
)?;
73+
let Generalization { value_may_be_infer: generalized_ty } = self.generalize(
74+
relation.span(),
75+
relation.structurally_relate_aliases(),
76+
target_vid,
77+
instantiation_variance,
78+
source_ty,
79+
)?;
8180

8281
// Constrain `b_vid` to the generalized type `generalized_ty`.
8382
if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
@@ -86,11 +85,6 @@ impl<'tcx> InferCtxt<'tcx> {
8685
self.inner.borrow_mut().type_variables().instantiate(target_vid, generalized_ty);
8786
}
8887

89-
// See the comment on `Generalization::has_unconstrained_ty_var`.
90-
if has_unconstrained_ty_var {
91-
relation.register_predicates([ty::ClauseKind::WellFormed(generalized_ty.into())]);
92-
}
93-
9488
// Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
9589
//
9690
// FIXME(#16847): This code is non-ideal because all these subtype
@@ -210,19 +204,15 @@ impl<'tcx> InferCtxt<'tcx> {
210204
) -> RelateResult<'tcx, ()> {
211205
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
212206
// constants and generic expressions are not yet handled correctly.
213-
let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } = self
214-
.generalize(
215-
relation.span(),
216-
relation.structurally_relate_aliases(),
217-
target_vid,
218-
ty::Invariant,
219-
source_ct,
220-
)?;
207+
let Generalization { value_may_be_infer: generalized_ct } = self.generalize(
208+
relation.span(),
209+
relation.structurally_relate_aliases(),
210+
target_vid,
211+
ty::Invariant,
212+
source_ct,
213+
)?;
221214

222215
debug_assert!(!generalized_ct.is_ct_infer());
223-
if has_unconstrained_ty_var {
224-
bug!("unconstrained ty var when generalizing `{source_ct:?}`");
225-
}
226216

227217
self.inner
228218
.borrow_mut()
@@ -281,12 +271,10 @@ impl<'tcx> InferCtxt<'tcx> {
281271
ambient_variance,
282272
in_alias: false,
283273
cache: Default::default(),
284-
has_unconstrained_ty_var: false,
285274
};
286275

287276
let value_may_be_infer = generalizer.relate(source_term, source_term)?;
288-
let has_unconstrained_ty_var = generalizer.has_unconstrained_ty_var;
289-
Ok(Generalization { value_may_be_infer, has_unconstrained_ty_var })
277+
Ok(Generalization { value_may_be_infer })
290278
}
291279
}
292280

@@ -376,9 +364,6 @@ struct Generalizer<'me, 'tcx> {
376364
in_alias: bool,
377365

378366
cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>,
379-
380-
/// See the field `has_unconstrained_ty_var` in `Generalization`.
381-
has_unconstrained_ty_var: bool,
382367
}
383368

384369
impl<'tcx> Generalizer<'_, 'tcx> {
@@ -391,10 +376,8 @@ impl<'tcx> Generalizer<'_, 'tcx> {
391376
}
392377

393378
/// Create a new type variable in the universe of the target when
394-
/// generalizing an alias. This has to set `has_unconstrained_ty_var`
395-
/// if we're currently in a bivariant context.
379+
/// generalizing an alias.
396380
fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> {
397-
self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant;
398381
self.infcx.next_ty_var_in_universe(self.span, self.for_universe)
399382
}
400383

@@ -540,14 +523,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
540523
}
541524
}
542525

543-
// Bivariant: make a fresh var, but remember that
544-
// it is unconstrained. See the comment in
545-
// `Generalization`.
546-
ty::Bivariant => self.has_unconstrained_ty_var = true,
547-
548-
// Co/contravariant: this will be
549-
// sufficiently constrained later on.
550-
ty::Covariant | ty::Contravariant => (),
526+
// We do need a fresh type variable otherwise.
527+
ty::Bivariant | ty::Covariant | ty::Contravariant => (),
551528
}
552529

553530
let origin = inner.type_variables().var_origin(vid);
@@ -766,32 +743,8 @@ struct Generalization<T> {
766743
/// for `?0` generalization returns an inference
767744
/// variable.
768745
///
769-
/// This has to be handled wotj care as it can
746+
/// This has to be handled with care as it can
770747
/// otherwise very easily result in infinite
771748
/// recursion.
772749
pub value_may_be_infer: T,
773-
774-
/// In general, we do not check whether all types which occur during
775-
/// type checking are well-formed. We only check wf of user-provided types
776-
/// and when actually using a type, e.g. for method calls.
777-
///
778-
/// This means that when subtyping, we may end up with unconstrained
779-
/// inference variables if a generalized type has bivariant parameters.
780-
/// A parameter may only be bivariant if it is constrained by a projection
781-
/// bound in a where-clause. As an example, imagine a type:
782-
///
783-
/// struct Foo<A, B> where A: Iterator<Item = B> {
784-
/// data: A
785-
/// }
786-
///
787-
/// here, `A` will be covariant, but `B` is unconstrained.
788-
///
789-
/// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`.
790-
/// If we have an input `Foo<?A, ?B>`, then after generalization we will wind
791-
/// up with a type like `Foo<?C, ?D>`. When we enforce `Foo<?A, ?B> <: Foo<?C, ?D>`,
792-
/// we will wind up with the requirement that `?A <: ?C`, but no particular
793-
/// relationship between `?B` and `?D` (after all, these types may be completely
794-
/// different). If we do nothing else, this may mean that `?D` goes unconstrained
795-
/// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases.
796-
pub has_unconstrained_ty_var: bool,
797750
}

compiler/rustc_infer/src/infer/relate/lattice.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
8585
) -> RelateResult<'tcx, Ty<'tcx>> {
8686
let variances = self.cx().variances_of(item_def_id);
8787
let args = relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, false)?;
88-
Ok(f(args))
88+
let ty = f(args);
89+
if variances.iter().any(|&v| v == ty::Bivariant) {
90+
self.register_predicates([ty::ClauseKind::WellFormed(ty.into())]);
91+
}
92+
Ok(ty)
8993
}
9094

9195
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(

compiler/rustc_infer/src/infer/relate/type_relating.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,22 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
8686
b_arg: ty::GenericArgsRef<'tcx>,
8787
f: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
8888
) -> RelateResult<'tcx, Ty<'tcx>> {
89-
let args = if self.ambient_variance == ty::Invariant {
89+
if self.ambient_variance == ty::Invariant {
9090
// Avoid fetching the variance if we are in an invariant
9191
// context; no need, and it can induce dependency cycles
9292
// (e.g., #41849).
93-
relate_args_invariantly(self, a_arg, b_arg)
94-
} else {
95-
let tcx = self.cx();
96-
let variances = tcx.variances_of(item_def_id);
97-
relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, false)
98-
}?;
93+
let args = relate_args_invariantly(self, a_arg, b_arg)?;
94+
return Ok(f(args));
95+
}
9996

100-
Ok(f(args))
97+
let tcx = self.cx();
98+
let variances = tcx.variances_of(item_def_id);
99+
let args = relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, false)?;
100+
let ty = f(args);
101+
if variances.iter().any(|&v| v == ty::Bivariant) {
102+
self.register_predicates([ty::ClauseKind::WellFormed(ty.into())]);
103+
}
104+
Ok(ty)
101105
}
102106

103107
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(

compiler/rustc_type_ir/src/relate/solver_relating.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,22 @@ where
146146
b_arg: I::GenericArgs,
147147
f: impl FnOnce(I::GenericArgs) -> I::Ty,
148148
) -> RelateResult<I, I::Ty> {
149-
let args = if self.ambient_variance == ty::Invariant {
149+
if self.ambient_variance == ty::Invariant {
150150
// Avoid fetching the variance if we are in an invariant
151151
// context; no need, and it can induce dependency cycles
152152
// (e.g., #41849).
153-
relate_args_invariantly(self, a_arg, b_arg)
154-
} else {
155-
let tcx = self.cx();
156-
let variances = tcx.variances_of(item_def_id);
157-
relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, false)
158-
}?;
159-
160-
Ok(f(args))
153+
let args = relate_args_invariantly(self, a_arg, b_arg)?;
154+
return Ok(f(args));
155+
}
156+
157+
let tcx = self.cx();
158+
let variances = tcx.variances_of(item_def_id);
159+
let args = relate_args_with_variances(self, item_def_id, variances, a_arg, b_arg, false)?;
160+
let ty = f(args);
161+
if variances.iter().any(|v| v == ty::Bivariant) {
162+
self.goals.push(Goal::new(tcx, self.param_env, ty::ClauseKind::WellFormed(ty.into())));
163+
}
164+
Ok(ty)
161165
}
162166

163167
fn relate_with_variance<T: Relate<I>>(

0 commit comments

Comments
 (0)