Extract out mts into combine using tys_with_variance

This commit is contained in:
Niko Matsakis 2015-03-17 10:23:13 -04:00
parent bfac337daa
commit 1b0f0ad280
6 changed files with 18 additions and 100 deletions

View File

@ -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)))

View File

@ -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>>;

View File

@ -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 {

View File

@ -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) {

View File

@ -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),

View File

@ -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))