Skip to content

Commit 413f247

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 c0086b9 + ab85743 commit 413f247

32 files changed

+1050
-696
lines changed

src/librustc/infer/canonical/canonicalizer.rs

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

286286
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
287+
type Error = !;
288+
287289
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
288290
self.tcx
289291
}
290292

291-
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
293+
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> Result<ty::Binder<T>, !>
292294
where T: TypeFoldable<'tcx>
293295
{
294296
self.binder_index.shift_in(1);
@@ -297,8 +299,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
297299
t
298300
}
299301

300-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
301-
match *r {
302+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
303+
Ok(match *r {
302304
ty::ReLateBound(index, ..) => {
303305
if index >= self.binder_index {
304306
bug!("escaping late bound region during canonicalization")
@@ -333,10 +335,10 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
333335
ty::ReClosureBound(..) => {
334336
bug!("closure bound region encountered during canonicalization")
335337
}
336-
}
338+
})
337339
}
338340

339-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
341+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
340342
match t.sty {
341343
ty::Infer(ty::TyVar(vid)) => {
342344
debug!("canonical: type var found with vid {:?}", vid);
@@ -354,48 +356,48 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
354356
// FIXME: perf problem described in #55921.
355357
ui = ty::UniverseIndex::ROOT;
356358
}
357-
self.canonicalize_ty_var(
359+
Ok(self.canonicalize_ty_var(
358360
CanonicalVarInfo {
359361
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
360362
},
361363
t
362-
)
364+
))
363365
}
364366
}
365367
}
366368

367-
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
369+
ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var(
368370
CanonicalVarInfo {
369371
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
370372
},
371373
t
372-
),
374+
)),
373375

374-
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
376+
ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var(
375377
CanonicalVarInfo {
376378
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
377379
},
378380
t
379-
),
381+
)),
380382

381383
ty::Infer(ty::FreshTy(_))
382384
| ty::Infer(ty::FreshIntTy(_))
383385
| ty::Infer(ty::FreshFloatTy(_)) => {
384386
bug!("encountered a fresh type during canonicalization")
385387
}
386388

387-
ty::Placeholder(placeholder) => self.canonicalize_ty_var(
389+
ty::Placeholder(placeholder) => Ok(self.canonicalize_ty_var(
388390
CanonicalVarInfo {
389391
kind: CanonicalVarKind::PlaceholderTy(placeholder)
390392
},
391393
t
392-
),
394+
)),
393395

394396
ty::Bound(debruijn, _) => {
395397
if debruijn >= self.binder_index {
396398
bug!("escaping bound type during canonicalization")
397399
} else {
398-
t
400+
Ok(t)
399401
}
400402
}
401403

@@ -427,7 +429,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
427429
if t.flags.intersects(self.needs_canonical_flags) {
428430
t.super_fold_with(self)
429431
} else {
430-
t
432+
Ok(t)
431433
}
432434
}
433435
}
@@ -485,7 +487,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
485487
indices: FxHashMap::default(),
486488
binder_index: ty::INNERMOST,
487489
};
488-
let out_value = value.fold_with(&mut canonicalizer);
490+
let Ok(out_value) = value.fold_with(&mut canonicalizer);
489491

490492
// Once we have canonicalized `out_value`, it should not
491493
// contain anything that ties it to this inference context
@@ -627,7 +629,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
627629
let infcx = self.infcx.expect("encountered ty-var without infcx");
628630
let bound_to = infcx.shallow_resolve(ty_var);
629631
if bound_to != ty_var {
630-
self.fold_ty(bound_to)
632+
self.fold_ty(bound_to).unwrap_or_else(|e: !| e)
631633
} else {
632634
let var = self.canonical_var(info, ty_var.into());
633635
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::SubstsRef;
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;
@@ -278,7 +278,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
278278
root_ty: ty,
279279
};
280280

281-
let ty = match generalize.relate(&ty, &ty) {
281+
let ty = match ty.fold_with(&mut generalize) {
282282
Ok(ty) => ty,
283283
Err(e) => {
284284
debug!("generalize: failure {:?}", e);
@@ -351,60 +351,41 @@ struct Generalization<'tcx> {
351351
needs_wf: bool,
352352
}
353353

354-
impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
355-
fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
356-
self.infcx.tcx
357-
}
358-
359-
fn tag(&self) -> &'static str {
360-
"Generalizer"
361-
}
354+
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
355+
type Error = TypeError<'tcx>;
362356

363-
fn a_is_expected(&self) -> bool {
364-
true
365-
}
366-
367-
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
368-
-> RelateResult<'tcx, ty::Binder<T>>
369-
where T: Relate<'tcx>
370-
{
371-
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
357+
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> {
358+
self.infcx.tcx
372359
}
373360

374-
fn relate_item_substs(&mut self,
375-
item_def_id: DefId,
376-
a_subst: SubstsRef<'tcx>,
377-
b_subst: SubstsRef<'tcx>)
378-
-> RelateResult<'tcx, SubstsRef<'tcx>>
379-
{
361+
fn use_variances(&self) -> bool {
380362
if self.ambient_variance == ty::Variance::Invariant {
381363
// Avoid fetching the variance if we are in an invariant
382364
// context; no need, and it can induce dependency cycles
383365
// (e.g., #41849).
384-
relate::relate_substs(self, None, a_subst, b_subst)
366+
false
385367
} else {
386-
let opt_variances = self.tcx().variances_of(item_def_id);
387-
relate::relate_substs(self, Some(&opt_variances), a_subst, b_subst)
368+
true
388369
}
389370
}
390371

391-
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
392-
variance: ty::Variance,
393-
a: &T,
394-
b: &T)
395-
-> RelateResult<'tcx, T>
372+
fn fold_with_variance<T: TypeFoldable<'tcx>>(&mut self,
373+
variance: ty::Variance,
374+
a: &T)
375+
-> RelateResult<'tcx, T>
396376
{
397377
let old_ambient_variance = self.ambient_variance;
378+
debug!("Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})",
379+
variance, a, old_ambient_variance);
398380
self.ambient_variance = self.ambient_variance.xform(variance);
399381

400-
let result = self.relate(a, b);
382+
let result = a.fold_with(self);
401383
self.ambient_variance = old_ambient_variance;
402384
result
403385
}
404386

405-
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
406-
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
407-
387+
fn fold_ty(&mut self, t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
388+
debug!("Generalize: fold_ty({:?}, variance={:?})", t, self.ambient_variance);
408389
debug!("generalize: t={:?}", t);
409390

410391
// Check to see whether the type we are genealizing references
@@ -425,7 +406,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
425406
TypeVariableValue::Known { value: u } => {
426407
drop(variables);
427408
debug!("generalize: known value {:?}", u);
428-
self.relate(&u, &u)
409+
u.fold_with(self)
429410
}
430411
TypeVariableValue::Unknown { universe } => {
431412
match self.ambient_variance {
@@ -449,7 +430,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
449430

450431
let origin = *variables.var_origin(vid);
451432
let new_var_id = variables.new_var(self.for_universe, false, origin);
452-
let u = self.tcx().mk_var(new_var_id);
433+
let u = self.infcx.tcx.mk_var(new_var_id);
453434
debug!("generalize: replacing original vid={:?} with new={:?}",
454435
vid, u);
455436
return Ok(u);
@@ -459,21 +440,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
459440
}
460441
ty::Infer(ty::IntVar(_)) |
461442
ty::Infer(ty::FloatVar(_)) => {
462-
// No matter what mode we are in,
463-
// integer/floating-point types must be equal to be
464-
// relatable.
465443
Ok(t)
466444
}
445+
ty::Array(_, sz) => {
446+
// HACK, not sure how desirable this is: propagate errors from
447+
// array lengths to the array type itself. This makes error
448+
// messages a bit nicer, and used to be the case before because
449+
// we used `ty::relate` instead of `TypeFoldable`, so I'll keep
450+
// it here.
451+
//
452+
// This does not serve any functional purpose, but it does
453+
// avoid some "duplicate" errors.
454+
match self.infcx.tcx.force_eval_array_length(*sz) {
455+
Ok(_) => t.super_fold_with(self),
456+
Err(ErrorReported) => {
457+
Ok(self.infcx.tcx.types.err)
458+
}
459+
}
460+
}
467461
_ => {
468-
relate::super_relate_tys(self, t, t)
462+
t.super_fold_with(self)
469463
}
470464
}
471465
}
472466

473-
fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>)
467+
fn fold_region(&mut self, r: ty::Region<'tcx>)
474468
-> RelateResult<'tcx, ty::Region<'tcx>> {
475-
assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
476-
469+
debug!("Generalize: fold_region({:?}, variance={:?})", r, self.ambient_variance);
477470
debug!("generalize: regions r={:?}", r);
478471

479472
match *r {

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)