mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-13 23:42:56 +00:00
Extract out mts
into combine
using tys_with_variance
This commit is contained in:
parent
bfac337daa
commit
1b0f0ad280
@ -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)))
|
||||
|
@ -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>>;
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user