Skip to content

Commit 7e0ae7d

Browse files
nikomatsakisMark-Simulacrum
authored andcommitted
introduce a Diverging enum instead of a bool
1 parent c1b4824 commit 7e0ae7d

File tree

5 files changed

+78
-61
lines changed

5 files changed

+78
-61
lines changed

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222
// is also useful to track which value is the "expected" value in
2323
// terms of error reporting.
2424

25-
use super::equate::Equate;
2625
use super::glb::Glb;
2726
use super::lub::Lub;
2827
use super::sub::Sub;
2928
use super::type_variable::TypeVariableValue;
3029
use super::unify_key::replace_if_possible;
3130
use super::unify_key::{ConstVarValue, ConstVariableValue};
3231
use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
32+
use super::{equate::Equate, type_variable::Diverging};
3333
use super::{InferCtxt, MiscVariable, TypeTrace};
3434

3535
use crate::traits::{Obligation, PredicateObligations};
@@ -643,7 +643,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
643643
.inner
644644
.borrow_mut()
645645
.type_variables()
646-
.new_var(self.for_universe, false, origin);
646+
.new_var(self.for_universe, Diverging::NotDiverging, origin);
647647
let u = self.tcx().mk_ty_var(new_var_id);
648648
debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
649649
Ok(u)
@@ -881,7 +881,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
881881
*self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
882882
let new_var_id = self.infcx.inner.borrow_mut().type_variables().new_var(
883883
self.for_universe,
884-
false,
884+
Diverging::NotDiverging,
885885
origin,
886886
);
887887
let u = self.tcx().mk_ty_var(new_var_id);

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, Veri
4646
use self::region_constraints::{
4747
RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
4848
};
49-
use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
49+
use self::type_variable::{Diverging, TypeVariableOrigin, TypeVariableOriginKind};
5050

5151
pub mod at;
5252
pub mod canonical;
@@ -679,10 +679,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
679679
t.fold_with(&mut self.freshener())
680680
}
681681

682-
pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> bool {
682+
pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> Diverging {
683683
match *ty.kind() {
684684
ty::Infer(ty::TyVar(vid)) => self.inner.borrow_mut().type_variables().var_diverges(vid),
685-
_ => false,
685+
_ => Diverging::NotDiverging,
686686
}
687687
}
688688

@@ -1020,25 +1020,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10201020
})
10211021
}
10221022

1023-
pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
1023+
pub fn next_ty_var_id(&self, diverging: Diverging, origin: TypeVariableOrigin) -> TyVid {
10241024
self.inner.borrow_mut().type_variables().new_var(self.universe(), diverging, origin)
10251025
}
10261026

10271027
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
1028-
self.tcx.mk_ty_var(self.next_ty_var_id(false, origin))
1028+
self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::NotDiverging, origin))
10291029
}
10301030

10311031
pub fn next_ty_var_in_universe(
10321032
&self,
10331033
origin: TypeVariableOrigin,
10341034
universe: ty::UniverseIndex,
10351035
) -> Ty<'tcx> {
1036-
let vid = self.inner.borrow_mut().type_variables().new_var(universe, false, origin);
1036+
let vid = self.inner.borrow_mut().type_variables().new_var(
1037+
universe,
1038+
Diverging::NotDiverging,
1039+
origin,
1040+
);
10371041
self.tcx.mk_ty_var(vid)
10381042
}
10391043

10401044
pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
1041-
self.tcx.mk_ty_var(self.next_ty_var_id(true, origin))
1045+
self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::Diverges, origin))
10421046
}
10431047

10441048
pub fn next_const_var(
@@ -1152,7 +1156,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11521156
// as the substitutions for the default, `(T, U)`.
11531157
let ty_var_id = self.inner.borrow_mut().type_variables().new_var(
11541158
self.universe(),
1155-
false,
1159+
Diverging::NotDiverging,
11561160
TypeVariableOrigin {
11571161
kind: TypeVariableOriginKind::TypeParameterDefinition(
11581162
param.name,

compiler/rustc_infer/src/infer/nll_relate/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//! constituents)
2323
2424
use crate::infer::combine::ConstEquateRelation;
25+
use crate::infer::type_variable::Diverging;
2526
use crate::infer::InferCtxt;
2627
use crate::infer::{ConstVarValue, ConstVariableValue};
2728
use rustc_data_structures::fx::FxHashMap;
@@ -920,7 +921,8 @@ where
920921
// Replacing with a new variable in the universe `self.universe`,
921922
// it will be unified later with the original type variable in
922923
// the universe `_universe`.
923-
let new_var_id = variables.new_var(self.universe, false, origin);
924+
let new_var_id =
925+
variables.new_var(self.universe, Diverging::NotDiverging, origin);
924926

925927
let u = self.tcx().mk_ty_var(new_var_id);
926928
debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);

compiler/rustc_infer/src/infer/type_variable.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,13 @@ pub enum TypeVariableOriginKind {
119119

120120
pub(crate) struct TypeVariableData {
121121
origin: TypeVariableOrigin,
122-
diverging: bool,
122+
diverging: Diverging,
123+
}
124+
125+
#[derive(Copy, Clone, Debug)]
126+
pub enum Diverging {
127+
NotDiverging,
128+
Diverges,
123129
}
124130

125131
#[derive(Copy, Clone, Debug)]
@@ -173,7 +179,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
173179
///
174180
/// Note that this function does not return care whether
175181
/// `vid` has been unified with something else or not.
176-
pub fn var_diverges(&self, vid: ty::TyVid) -> bool {
182+
pub fn var_diverges(&self, vid: ty::TyVid) -> Diverging {
177183
self.storage.values.get(vid.index as usize).diverging
178184
}
179185

@@ -238,7 +244,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
238244
pub fn new_var(
239245
&mut self,
240246
universe: ty::UniverseIndex,
241-
diverging: bool,
247+
diverging: Diverging,
242248
origin: TypeVariableOrigin,
243249
) -> ty::TyVid {
244250
let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe });

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_hir::lang_items::LangItem;
1717
use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
1818
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1919
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
20+
use rustc_infer::infer::type_variable::Diverging;
2021
use rustc_infer::infer::{InferOk, InferResult};
2122
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
2223
use rustc_middle::ty::fold::TypeFoldable;
@@ -656,56 +657,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
656657
_ if self.is_tainted_by_errors() => self.tcx().ty_error(),
657658
UnconstrainedInt => self.tcx.types.i32,
658659
UnconstrainedFloat => self.tcx.types.f64,
659-
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
660-
Neither => {
661-
// This type variable was created from the instantiation of an opaque
662-
// type. The fact that we're attempting to perform fallback for it
663-
// means that the function neither constrained it to a concrete
664-
// type, nor to the opaque type itself.
665-
//
666-
// For example, in this code:
667-
//
668-
//```
669-
// type MyType = impl Copy;
670-
// fn defining_use() -> MyType { true }
671-
// fn other_use() -> MyType { defining_use() }
672-
// ```
673-
//
674-
// `defining_use` will constrain the instantiated inference
675-
// variable to `bool`, while `other_use` will constrain
676-
// the instantiated inference variable to `MyType`.
677-
//
678-
// When we process opaque types during writeback, we
679-
// will handle cases like `other_use`, and not count
680-
// them as defining usages
681-
//
682-
// However, we also need to handle cases like this:
683-
//
684-
// ```rust
685-
// pub type Foo = impl Copy;
686-
// fn produce() -> Option<Foo> {
687-
// None
688-
// }
689-
// ```
690-
//
691-
// In the above snippet, the inference variable created by
692-
// instantiating `Option<Foo>` will be completely unconstrained.
693-
// We treat this as a non-defining use by making the inference
694-
// variable fall back to the opaque type itself.
695-
if let FallbackMode::All = mode {
696-
if let Some(opaque_ty) = self.infcx.inner.borrow().opaque_types_vars.get(ty) {
697-
debug!(
698-
"fallback_if_possible: falling back opaque type var {:?} to {:?}",
699-
ty, opaque_ty
700-
);
701-
*opaque_ty
660+
Neither => match self.type_var_diverges(ty) {
661+
Diverging::Diverges => self.tcx.mk_diverging_default(),
662+
663+
Diverging::NotDiverging => {
664+
// This type variable was created from the instantiation of an opaque
665+
// type. The fact that we're attempting to perform fallback for it
666+
// means that the function neither constrained it to a concrete
667+
// type, nor to the opaque type itself.
668+
//
669+
// For example, in this code:
670+
//
671+
//```
672+
// type MyType = impl Copy;
673+
// fn defining_use() -> MyType { true }
674+
// fn other_use() -> MyType { defining_use() }
675+
// ```
676+
//
677+
// `defining_use` will constrain the instantiated inference
678+
// variable to `bool`, while `other_use` will constrain
679+
// the instantiated inference variable to `MyType`.
680+
//
681+
// When we process opaque types during writeback, we
682+
// will handle cases like `other_use`, and not count
683+
// them as defining usages
684+
//
685+
// However, we also need to handle cases like this:
686+
//
687+
// ```rust
688+
// pub type Foo = impl Copy;
689+
// fn produce() -> Option<Foo> {
690+
// None
691+
// }
692+
// ```
693+
//
694+
// In the above snippet, the inference variable created by
695+
// instantiating `Option<Foo>` will be completely unconstrained.
696+
// We treat this as a non-defining use by making the inference
697+
// variable fall back to the opaque type itself.
698+
if let FallbackMode::All = mode {
699+
if let Some(opaque_ty) = self.infcx.inner.borrow().opaque_types_vars.get(ty)
700+
{
701+
debug!(
702+
"fallback_if_possible: falling back opaque type var {:?} to {:?}",
703+
ty, opaque_ty
704+
);
705+
*opaque_ty
706+
} else {
707+
return false;
708+
}
702709
} else {
703710
return false;
704711
}
705-
} else {
706-
return false;
707712
}
708-
}
713+
},
709714
};
710715
debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
711716
self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);

0 commit comments

Comments
 (0)