From 1b0f0ad28070c072f68ea0ab10bbae61b52706a8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 17 Mar 2015 10:23:13 -0400 Subject: [PATCH] Extract out `mts` into `combine` using `tys_with_variance` --- src/librustc/middle/infer/bivariate.rs | 10 --------- src/librustc/middle/infer/combine.rs | 19 +++++++++++++++- src/librustc/middle/infer/equate.rs | 9 -------- src/librustc/middle/infer/glb.rs | 30 -------------------------- src/librustc/middle/infer/lub.rs | 26 ---------------------- src/librustc/middle/infer/sub.rs | 24 --------------------- 6 files changed, 18 insertions(+), 100 deletions(-) diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs index 93c80fb754f71..1916d39b49828 100644 --- a/src/librustc/middle/infer/bivariate.rs +++ b/src/librustc/middle/infer/bivariate.rs @@ -74,16 +74,6 @@ impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> { Ok(a) } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { - debug!("mts({} <: {})", - a.repr(self.fields.infcx.tcx), - b.repr(self.fields.infcx.tcx)); - - if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } - let t = try!(self.tys(a.ty, b.ty)); - Ok(ty::mt { mutbl: a.mutbl, ty: t }) - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { if a != b { Err(ty::terr_unsafety_mismatch(expected_found(self, a, b))) diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 438b61f918a1e..9fdfdaccf4eaf 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -74,7 +74,24 @@ pub trait Combine<'tcx> : Sized { fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) } fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>; + fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { + debug!("{}.mts({}, {})", + self.tag(), + a.repr(self.tcx()), + b.repr(self.tcx())); + + if a.mutbl != b.mutbl { + Err(ty::terr_mutability) + } else { + let mutbl = a.mutbl; + let variance = match mutbl { + ast::MutImmutable => ty::Covariant, + ast::MutMutable => ty::Invariant, + }; + let ty = try!(self.tys_with_variance(variance, a.ty, b.ty)); + Ok(ty::mt {ty: ty, mutbl: mutbl}) + } + } fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>; diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs index 2f9f8532b6c52..e9ffe368f4220 100644 --- a/src/librustc/middle/infer/equate.rs +++ b/src/librustc/middle/infer/equate.rs @@ -54,15 +54,6 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> { Ok(a) } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { - debug!("mts({} <: {})", - a.repr(self.fields.infcx.tcx), - b.repr(self.fields.infcx.tcx)); - - if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } - let t = try!(self.tys(a.ty, b.ty)); - Ok(ty::mt { mutbl: a.mutbl, ty: t }) - } fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { if a != b { diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs index ba073999ed127..43d64643fe2ee 100644 --- a/src/librustc/middle/infer/glb.rs +++ b/src/librustc/middle/infer/glb.rs @@ -55,36 +55,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { } } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { - let tcx = self.fields.infcx.tcx; - - debug!("{}.mts({}, {})", - self.tag(), - mt_to_string(tcx, a), - mt_to_string(tcx, b)); - - match (a.mutbl, b.mutbl) { - // If one side or both is mut, then the GLB must use - // the precise type from the mut side. - (MutMutable, MutMutable) => { - let t = try!(self.equate().tys(a.ty, b.ty)); - Ok(ty::mt {ty: t, mutbl: MutMutable}) - } - - // If one side or both is immutable, we can use the GLB of - // both sides but mutbl must be `MutImmutable`. - (MutImmutable, MutImmutable) => { - let t = try!(self.tys(a.ty, b.ty)); - Ok(ty::mt {ty: t, mutbl: MutImmutable}) - } - - // There is no mutual subtype of these combinations. - (MutMutable, MutImmutable) | - (MutImmutable, MutMutable) => { - Err(ty::terr_mutability) - } - } - } fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs index 37eace0b15b6d..95d661b1add8c 100644 --- a/src/librustc/middle/infer/lub.rs +++ b/src/librustc/middle/infer/lub.rs @@ -55,32 +55,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { } } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { - let tcx = self.tcx(); - - debug!("{}.mts({}, {})", - self.tag(), - mt_to_string(tcx, a), - mt_to_string(tcx, b)); - - if a.mutbl != b.mutbl { - return Err(ty::terr_mutability) - } - - let m = a.mutbl; - match m { - MutImmutable => { - let t = try!(self.tys(a.ty, b.ty)); - Ok(ty::mt {ty: t, mutbl: m}) - } - - MutMutable => { - let t = try!(self.equate().tys(a.ty, b.ty)); - Ok(ty::mt {ty: t, mutbl: m}) - } - } - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe), diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs index 8ab063686d4bc..067973fb80f68 100644 --- a/src/librustc/middle/infer/sub.rs +++ b/src/librustc/middle/infer/sub.rs @@ -66,30 +66,6 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> { Ok(a) } - fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { - debug!("mts({} <: {})", - a.repr(self.tcx()), - b.repr(self.tcx())); - - if a.mutbl != b.mutbl { - return Err(ty::terr_mutability); - } - - match b.mutbl { - MutMutable => { - // If supertype is mut, subtype must match exactly - // (i.e., invariant if mut): - try!(self.equate().tys(a.ty, b.ty)); - } - MutImmutable => { - // Otherwise we can be covariant: - try!(self.tys(a.ty, b.ty)); - } - } - - Ok(*a) // return is meaningless in sub, just return *a - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { self.lub().unsafeties(a, b).compare(b, || { ty::terr_unsafety_mismatch(expected_found(self, a, b))