Skip to content

Commit c5e0b61

Browse files
committed
Auto merge of #58333 - arielb1:fold-result, r=<try>
Lift TypeFoldable over Result and remove the Relate hack in combine/nll No functional changes intended - just a cleanup. r? @nikomatsakis
2 parents eac0908 + 090f21e commit c5e0b61

33 files changed

+1021
-693
lines changed

src/librustc/infer/canonical/canonicalizer.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,13 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
275275
}
276276

277277
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
278+
type Error = !;
279+
278280
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
279281
self.tcx
280282
}
281283

282-
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
284+
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> Result<ty::Binder<T>, !>
283285
where T: TypeFoldable<'tcx>
284286
{
285287
self.binder_index.shift_in(1);
@@ -288,8 +290,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
288290
t
289291
}
290292

291-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
292-
match *r {
293+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
294+
Ok(match *r {
293295
ty::ReLateBound(index, ..) => {
294296
if index >= self.binder_index {
295297
bug!("escaping late bound region during canonicalization")
@@ -324,10 +326,10 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
324326
ty::ReClosureBound(..) => {
325327
bug!("closure bound region encountered during canonicalization")
326328
}
327-
}
329+
})
328330
}
329331

330-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
332+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
331333
match t.sty {
332334
ty::Infer(ty::TyVar(vid)) => {
333335
debug!("canonical: type var found with vid {:?}", vid);
@@ -345,48 +347,48 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
345347
// FIXME: perf problem described in #55921.
346348
ui = ty::UniverseIndex::ROOT;
347349
}
348-
self.canonicalize_ty_var(
350+
Ok(self.canonicalize_ty_var(
349351
CanonicalVarInfo {
350352
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
351353
},
352354
t
353-
)
355+
))
354356
}
355357
}
356358
}
357359

358-
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
360+
ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var(
359361
CanonicalVarInfo {
360362
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
361363
},
362364
t
363-
),
365+
)),
364366

365-
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
367+
ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var(
366368
CanonicalVarInfo {
367369
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
368370
},
369371
t
370-
),
372+
)),
371373

372374
ty::Infer(ty::FreshTy(_))
373375
| ty::Infer(ty::FreshIntTy(_))
374376
| ty::Infer(ty::FreshFloatTy(_)) => {
375377
bug!("encountered a fresh type during canonicalization")
376378
}
377379

378-
ty::Placeholder(placeholder) => self.canonicalize_ty_var(
380+
ty::Placeholder(placeholder) => Ok(self.canonicalize_ty_var(
379381
CanonicalVarInfo {
380382
kind: CanonicalVarKind::PlaceholderTy(placeholder)
381383
},
382384
t
383-
),
385+
)),
384386

385387
ty::Bound(debruijn, _) => {
386388
if debruijn >= self.binder_index {
387389
bug!("escaping bound type during canonicalization")
388390
} else {
389-
t
391+
Ok(t)
390392
}
391393
}
392394

@@ -418,7 +420,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
418420
if t.flags.intersects(self.needs_canonical_flags) {
419421
t.super_fold_with(self)
420422
} else {
421-
t
423+
Ok(t)
422424
}
423425
}
424426
}
@@ -476,7 +478,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
476478
indices: FxHashMap::default(),
477479
binder_index: ty::INNERMOST,
478480
};
479-
let out_value = value.fold_with(&mut canonicalizer);
481+
let Ok(out_value) = value.fold_with(&mut canonicalizer);
480482

481483
// Once we have canonicalized `out_value`, it should not
482484
// contain anything that ties it to this inference context
@@ -618,7 +620,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
618620
let infcx = self.infcx.expect("encountered ty-var without infcx");
619621
let bound_to = infcx.shallow_resolve(ty_var);
620622
if bound_to != ty_var {
621-
self.fold_ty(bound_to)
623+
self.fold_ty(bound_to).unwrap_or_else(|e: !| e)
622624
} else {
623625
let var = self.canonical_var(info, ty_var.into());
624626
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))

src/librustc/infer/combine.rs

+41-48
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ use super::lub::Lub;
2929
use super::sub::Sub;
3030
use super::type_variable::TypeVariableValue;
3131

32-
use crate::hir::def_id::DefId;
3332
use crate::ty::{IntType, UintType};
3433
use crate::ty::{self, Ty, TyCtxt};
34+
use crate::ty::fold::{TypeFoldable, TypeFolder};
3535
use crate::ty::error::TypeError;
36-
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
37-
use crate::ty::subst::Substs;
36+
use crate::ty::relate::{RelateResult, TypeRelation};
3837
use crate::traits::{Obligation, PredicateObligations};
38+
use crate::util::common::ErrorReported;
3939

4040
use syntax::ast;
4141
use syntax_pos::Span;
@@ -264,7 +264,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
264264
root_ty: ty,
265265
};
266266

267-
let ty = match generalize.relate(&ty, &ty) {
267+
let ty = match ty.fold_with(&mut generalize) {
268268
Ok(ty) => ty,
269269
Err(e) => {
270270
debug!("generalize: failure {:?}", e);
@@ -332,60 +332,41 @@ struct Generalization<'tcx> {
332332
needs_wf: bool,
333333
}
334334

335-
impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
336-
fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
337-
self.infcx.tcx
338-
}
339-
340-
fn tag(&self) -> &'static str {
341-
"Generalizer"
342-
}
335+
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
336+
type Error = TypeError<'tcx>;
343337

344-
fn a_is_expected(&self) -> bool {
345-
true
346-
}
347-
348-
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
349-
-> RelateResult<'tcx, ty::Binder<T>>
350-
where T: Relate<'tcx>
351-
{
352-
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
338+
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> {
339+
self.infcx.tcx
353340
}
354341

355-
fn relate_item_substs(&mut self,
356-
item_def_id: DefId,
357-
a_subst: &'tcx Substs<'tcx>,
358-
b_subst: &'tcx Substs<'tcx>)
359-
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
360-
{
342+
fn use_variances(&self) -> bool {
361343
if self.ambient_variance == ty::Variance::Invariant {
362344
// Avoid fetching the variance if we are in an invariant
363345
// context; no need, and it can induce dependency cycles
364346
// (e.g., #41849).
365-
relate::relate_substs(self, None, a_subst, b_subst)
347+
false
366348
} else {
367-
let opt_variances = self.tcx().variances_of(item_def_id);
368-
relate::relate_substs(self, Some(&opt_variances), a_subst, b_subst)
349+
true
369350
}
370351
}
371352

372-
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
373-
variance: ty::Variance,
374-
a: &T,
375-
b: &T)
376-
-> RelateResult<'tcx, T>
353+
fn fold_with_variance<T: TypeFoldable<'tcx>>(&mut self,
354+
variance: ty::Variance,
355+
a: &T)
356+
-> RelateResult<'tcx, T>
377357
{
378358
let old_ambient_variance = self.ambient_variance;
359+
debug!("Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})",
360+
variance, a, old_ambient_variance);
379361
self.ambient_variance = self.ambient_variance.xform(variance);
380362

381-
let result = self.relate(a, b);
363+
let result = a.fold_with(self);
382364
self.ambient_variance = old_ambient_variance;
383365
result
384366
}
385367

386-
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
387-
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
388-
368+
fn fold_ty(&mut self, t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
369+
debug!("Generalize: fold_ty({:?}, variance={:?})", t, self.ambient_variance);
389370
// Check to see whether the type we are genealizing references
390371
// any other type variable related to `vid` via
391372
// subtyping. This is basically our "occurs check", preventing
@@ -403,7 +384,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
403384
match variables.probe(vid) {
404385
TypeVariableValue::Known { value: u } => {
405386
drop(variables);
406-
self.relate(&u, &u)
387+
u.fold_with(self)
407388
}
408389
TypeVariableValue::Unknown { universe } => {
409390
match self.ambient_variance {
@@ -423,7 +404,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
423404

424405
let origin = *variables.var_origin(vid);
425406
let new_var_id = variables.new_var(universe, false, origin);
426-
let u = self.tcx().mk_var(new_var_id);
407+
let u = self.infcx.tcx.mk_var(new_var_id);
427408
debug!("generalize: replacing original vid={:?} with new={:?}",
428409
vid, u);
429410
return Ok(u);
@@ -433,21 +414,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
433414
}
434415
ty::Infer(ty::IntVar(_)) |
435416
ty::Infer(ty::FloatVar(_)) => {
436-
// No matter what mode we are in,
437-
// integer/floating-point types must be equal to be
438-
// relatable.
439417
Ok(t)
440418
}
419+
ty::Array(_, sz) => {
420+
// HACK, not sure how desirable this is: propagate errors from
421+
// array lengths to the array type itself. This makes error
422+
// messages a bit nicer, and used to be the case before because
423+
// we used `ty::relate` instead of `TypeFoldable`, so I'll keep
424+
// it here.
425+
//
426+
// This does not serve any functional purpose, but it does
427+
// avoid some "duplicate" errors.
428+
match self.infcx.tcx.force_eval_array_length(*sz) {
429+
Ok(_) => t.super_fold_with(self),
430+
Err(ErrorReported) => {
431+
Ok(self.infcx.tcx.types.err)
432+
}
433+
}
434+
}
441435
_ => {
442-
relate::super_relate_tys(self, t, t)
436+
t.super_fold_with(self)
443437
}
444438
}
445439
}
446440

447-
fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>)
441+
fn fold_region(&mut self, r: ty::Region<'tcx>)
448442
-> RelateResult<'tcx, ty::Region<'tcx>> {
449-
assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
450-
443+
debug!("Generalize: fold_region({:?}, variance={:?})", r, self.ambient_variance);
451444
match *r {
452445
// Never make variables for regions bound within the type itself,
453446
// nor for erased regions.

src/librustc/infer/freshen.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
6464
F: FnOnce(u32) -> ty::InferTy,
6565
{
6666
if let Some(ty) = opt_ty {
67-
return ty.fold_with(self);
67+
return ty.fold_with(self).unwrap_or_else(|e: !| e);
6868
}
6969

7070
match self.freshen_map.entry(key) {
@@ -81,12 +81,14 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
8181
}
8282

8383
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
84+
type Error = !;
85+
8486
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
8587
self.infcx.tcx
8688
}
8789

88-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
89-
match *r {
90+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
91+
Ok(match *r {
9092
ty::ReLateBound(..) => {
9193
// leave bound regions alone
9294
r
@@ -110,18 +112,18 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
110112
r,
111113
);
112114
}
113-
}
115+
})
114116
}
115117

116-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
118+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
117119
if !t.needs_infer() && !t.has_erasable_regions() &&
118120
!(t.has_closure_types() && self.infcx.in_progress_tables.is_some()) {
119-
return t;
121+
return Ok(t);
120122
}
121123

122124
let tcx = self.infcx.tcx;
123125

124-
match t.sty {
126+
Ok(match t.sty {
125127
ty::Infer(ty::TyVar(v)) => {
126128
let opt_ty = self.infcx.type_variables.borrow_mut().probe(v).known();
127129
self.freshen(
@@ -185,11 +187,11 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
185187
ty::Closure(..) |
186188
ty::GeneratorWitness(..) |
187189
ty::Opaque(..) => {
188-
t.super_fold_with(self)
190+
t.super_fold_with(self)?
189191
}
190192

191193
ty::Placeholder(..) |
192194
ty::Bound(..) => bug!("unexpected type {:?}", t),
193-
}
195+
})
194196
}
195197
}

0 commit comments

Comments
 (0)