Skip to content

Commit e8601fe

Browse files
committed
lift TypeFoldable over Result
1 parent eac0908 commit e8601fe

30 files changed

+721
-552
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/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
}

src/librustc/infer/fudge.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
9595
origin,
9696
};
9797

98-
Ok(value.fold_with(&mut fudger))
98+
value.fold_with(&mut fudger).map_err(|e| e)
9999
}
100100
}
101101

@@ -107,11 +107,13 @@ pub struct RegionFudger<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
107107
}
108108

109109
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
110+
type Error = !;
111+
110112
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
111113
self.infcx.tcx
112114
}
113115

114-
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
116+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
115117
match ty.sty {
116118
ty::Infer(ty::InferTy::TyVar(vid)) => {
117119
match self.type_variables.get(&vid) {
@@ -124,29 +126,29 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
124126
debug_assert!(self.infcx.type_variables.borrow_mut()
125127
.probe(vid)
126128
.is_unknown());
127-
ty
129+
Ok(ty)
128130
}
129131

130132
Some(&origin) => {
131133
// This variable was created during the
132134
// fudging. Recreate it with a fresh variable
133135
// here.
134-
self.infcx.next_ty_var(origin)
136+
Ok(self.infcx.next_ty_var(origin))
135137
}
136138
}
137139
}
138140
_ => ty.super_fold_with(self),
139141
}
140142
}
141143

142-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
143-
match *r {
144+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
145+
Ok(match *r {
144146
ty::ReVar(v) if self.region_vars.contains(&v) => {
145147
self.infcx.next_region_var(self.origin.clone())
146148
}
147149
_ => {
148150
r
149151
}
150-
}
152+
})
151153
}
152154
}

src/librustc/infer/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
604604
}
605605

606606
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
607-
t.fold_with(&mut self.freshener())
607+
t.fold_with(&mut self.freshener()).unwrap_or_else(|e: !| e)
608608
}
609609

610610
pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> bool {
@@ -1277,7 +1277,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12771277
return value.clone(); // avoid duplicated subst-folding
12781278
}
12791279
let mut r = resolve::OpportunisticTypeResolver::new(self);
1280-
value.fold_with(&mut r)
1280+
value.fold_with(&mut r).unwrap_or_else(|e: !| e)
12811281
}
12821282

12831283
/// Returns `true` if `T` contains unresolved type variables. In the
@@ -1290,7 +1290,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12901290
T: TypeFoldable<'tcx>,
12911291
{
12921292
let mut r = resolve::UnresolvedTypeFinder::new(self);
1293-
value.visit_with(&mut r)
1293+
value.visit_with(&mut r).is_err()
12941294
}
12951295

12961296
pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {

src/librustc/infer/nll_relate/mod.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ where
196196
}
197197
};
198198

199-
value.skip_binder().visit_with(&mut ScopeInstantiator {
199+
let Ok(_) = value.skip_binder().visit_with(&mut ScopeInstantiator {
200200
next_region: &mut next_region,
201201
target_index: ty::INNERMOST,
202202
bound_region_scope: &mut scope,
@@ -604,15 +604,17 @@ struct ScopeInstantiator<'me, 'tcx: 'me> {
604604
}
605605

606606
impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
607-
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
607+
type Error = !;
608+
609+
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> Result<(), !> {
608610
self.target_index.shift_in(1);
609-
t.super_visit_with(self);
611+
t.super_visit_with(self)?;
610612
self.target_index.shift_out(1);
611613

612-
false
614+
Ok(())
613615
}
614616

615-
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
617+
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Result<(), !> {
616618
let ScopeInstantiator {
617619
bound_region_scope,
618620
next_region,
@@ -630,7 +632,7 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
630632
_ => {}
631633
}
632634

633-
false
635+
Ok(())
634636
}
635637
}
636638

src/librustc/infer/opaque_types/mod.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
448448
// Convert the type from the function into a type valid outside
449449
// the function, by replacing invalid regions with 'static,
450450
// after producing an error for each of them.
451-
let definition_ty =
451+
let Ok(definition_ty) =
452452
instantiated_ty.fold_with(&mut ReverseMapper::new(
453453
self.tcx,
454454
self.is_tainted_by_errors(),
@@ -506,23 +506,25 @@ impl<'cx, 'gcx, 'tcx> ReverseMapper<'cx, 'gcx, 'tcx> {
506506
fn fold_kind_mapping_missing_regions_to_empty(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> {
507507
assert!(!self.map_missing_regions_to_empty);
508508
self.map_missing_regions_to_empty = true;
509-
let kind = kind.fold_with(self);
509+
let Ok(kind) = kind.fold_with(self);
510510
self.map_missing_regions_to_empty = false;
511511
kind
512512
}
513513

514514
fn fold_kind_normally(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> {
515515
assert!(!self.map_missing_regions_to_empty);
516-
kind.fold_with(self)
516+
kind.fold_with(self).unwrap_or_else(|e: !| e)
517517
}
518518
}
519519

520520
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> {
521+
type Error = !;
522+
521523
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> {
522524
self.tcx
523525
}
524526

525-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
527+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
526528
match r {
527529
// ignore bound regions that appear in the type (e.g., this
528530
// would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
@@ -533,13 +535,13 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
533535

534536
// ignore `ReScope`, as that can appear anywhere
535537
// See `src/test/run-pass/issue-49556.rs` for example.
536-
ty::ReScope(..) => return r,
538+
ty::ReScope(..) => return Ok(r),
537539

538540
_ => { }
539541
}
540542

541543
match self.map.get(&r.into()).map(|k| k.unpack()) {
542-
Some(UnpackedKind::Lifetime(r1)) => r1,
544+
Some(UnpackedKind::Lifetime(r1)) => Ok(r1),
543545
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
544546
None => {
545547
if !self.map_missing_regions_to_empty && !self.tainted_by_errors {
@@ -576,12 +578,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
576578
err.emit();
577579
}
578580
}
579-
self.tcx.types.re_empty
581+
Ok(self.tcx.types.re_empty)
580582
},
581583
}
582584
}
583585

584-
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
586+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
585587
match ty.sty {
586588
ty::Closure(def_id, substs) => {
587589
// I am a horrible monster and I pray for death. When
@@ -621,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
621623
},
622624
));
623625

624-
self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
626+
Ok(self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs }))
625627
}
626628

627629
_ => ty.super_fold_with(self),
@@ -733,7 +735,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
733735

734736
ty
735737
},
736-
})
738+
}).unwrap_or_else(|e: !| e)
737739
}
738740

739741
fn fold_opaque_ty(

0 commit comments

Comments
 (0)