2014-05-28 14:36:05 -05:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-11-06 02:05:53 -06:00
|
|
|
pub use self::VarValue::*;
|
|
|
|
|
2015-01-06 16:33:42 -06:00
|
|
|
use std::marker;
|
2013-05-17 17:28:44 -05:00
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
use middle::ty::{expected_found, IntVarValue};
|
2015-01-03 21:42:21 -06:00
|
|
|
use middle::ty::{self, Ty};
|
2014-11-25 15:59:02 -06:00
|
|
|
use middle::infer::{uok, ures};
|
|
|
|
use middle::infer::InferCtxt;
|
2013-12-19 22:35:14 -06:00
|
|
|
use std::cell::RefCell;
|
2014-06-20 05:35:06 -05:00
|
|
|
use std::fmt::Show;
|
2013-01-22 09:02:40 -06:00
|
|
|
use syntax::ast;
|
2014-06-20 05:35:06 -05:00
|
|
|
use util::ppaux::Repr;
|
2014-07-22 06:40:51 -05:00
|
|
|
use util::snapshot_vec as sv;
|
2014-06-20 05:35:06 -05:00
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// This trait is implemented by any type that can serve as a type
|
|
|
|
/// variable. We call such variables *unification keys*. For example,
|
|
|
|
/// this trait is implemented by `IntVid`, which represents integral
|
|
|
|
/// variables.
|
|
|
|
///
|
|
|
|
/// Each key type has an associated value type `V`. For example, for
|
|
|
|
/// `IntVid`, this is `Option<IntVarValue>`, representing some
|
|
|
|
/// (possibly not yet known) sort of integer.
|
|
|
|
///
|
|
|
|
/// Implementations of this trait are at the end of this file.
|
2014-09-29 14:11:30 -05:00
|
|
|
pub trait UnifyKey<'tcx, V> : Clone + Show + PartialEq + Repr<'tcx> {
|
2014-06-20 05:35:06 -05:00
|
|
|
fn index(&self) -> uint;
|
|
|
|
|
|
|
|
fn from_index(u: uint) -> Self;
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
// Given an inference context, returns the unification table
|
|
|
|
// appropriate to this key type.
|
2014-06-20 05:35:06 -05:00
|
|
|
fn unification_table<'v>(infcx: &'v InferCtxt)
|
|
|
|
-> &'v RefCell<UnificationTable<Self,V>>;
|
|
|
|
|
|
|
|
fn tag(k: Option<Self>) -> &'static str;
|
|
|
|
}
|
2012-12-13 15:05:22 -06:00
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Trait for valid types that a type variable can be set to. Note that
|
|
|
|
/// this is typically not the end type that the value will take on, but
|
|
|
|
/// rather an `Option` wrapper (where `None` represents a variable
|
|
|
|
/// whose value is not yet set).
|
|
|
|
///
|
|
|
|
/// Implementations of this trait are at the end of this file.
|
2014-09-29 14:11:30 -05:00
|
|
|
pub trait UnifyValue<'tcx> : Clone + Repr<'tcx> + PartialEq {
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Value of a unification key. We implement Tarjan's union-find
|
|
|
|
/// algorithm: when two keys are unified, one of them is converted
|
|
|
|
/// into a "redirect" pointing at the other. These redirects form a
|
|
|
|
/// DAG: the roots of the DAG (nodes that are not redirected) are each
|
|
|
|
/// associated with a value of type `V` and a rank. The rank is used
|
|
|
|
/// to keep the DAG relatively balanced, which helps keep the running
|
|
|
|
/// time of the algorithm under control. For more information, see
|
|
|
|
/// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
|
2015-01-03 21:54:18 -06:00
|
|
|
#[derive(PartialEq,Clone)]
|
2014-06-20 05:35:06 -05:00
|
|
|
pub enum VarValue<K,V> {
|
|
|
|
Redirect(K),
|
|
|
|
Root(V, uint),
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Table of unification keys and their values.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub struct UnificationTable<K,V> {
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Indicates the current value of each key.
|
2014-07-22 06:40:51 -05:00
|
|
|
values: sv::SnapshotVec<VarValue<K,V>,(),Delegate>,
|
2014-05-28 14:36:05 -05:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// At any time, users may snapshot a unification table. The changes
|
|
|
|
/// made during the snapshot may either be *committed* or *rolled back*.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub struct Snapshot<K> {
|
2014-07-22 06:40:51 -05:00
|
|
|
// Link snapshot to the key type `K` of the table.
|
|
|
|
marker: marker::CovariantType<K>,
|
|
|
|
snapshot: sv::Snapshot,
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Internal type used to represent the result of a `get()` operation.
|
|
|
|
/// Conveys the current root and value of the key.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub struct Node<K,V> {
|
|
|
|
pub key: K,
|
|
|
|
pub value: V,
|
|
|
|
pub rank: uint,
|
2013-06-14 20:21:47 -05:00
|
|
|
}
|
|
|
|
|
2015-01-03 21:54:18 -06:00
|
|
|
#[derive(Copy)]
|
2014-07-22 06:40:51 -05:00
|
|
|
pub struct Delegate;
|
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
// We can't use V:LatticeValue, much as I would like to,
|
2014-07-22 06:46:36 -05:00
|
|
|
// because frequently the pattern is that V=Option<U> for some
|
2014-06-20 05:35:06 -05:00
|
|
|
// other type parameter U, and we have no way to say
|
2014-07-22 06:46:36 -05:00
|
|
|
// Option<U>:LatticeValue.
|
2014-06-20 05:35:06 -05:00
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K,V> {
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn new() -> UnificationTable<K,V> {
|
|
|
|
UnificationTable {
|
2014-07-22 06:40:51 -05:00
|
|
|
values: sv::SnapshotVec::new(Delegate),
|
2014-06-20 05:35:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Starts a new snapshot. Each snapshot must be either
|
|
|
|
/// rolled back or committed in a "LIFO" (stack) order.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn snapshot(&mut self) -> Snapshot<K> {
|
2014-07-22 06:40:51 -05:00
|
|
|
Snapshot { marker: marker::CovariantType::<K>,
|
|
|
|
snapshot: self.values.start_snapshot() }
|
2014-06-20 05:35:06 -05:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Reverses all changes since the last snapshot. Also
|
|
|
|
/// removes any keys that have been created since then.
|
2014-07-22 06:40:51 -05:00
|
|
|
pub fn rollback_to(&mut self, snapshot: Snapshot<K>) {
|
|
|
|
debug!("{}: rollback_to()", UnifyKey::tag(None::<K>));
|
|
|
|
self.values.rollback_to(snapshot.snapshot);
|
2014-06-20 05:35:06 -05:00
|
|
|
}
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Commits all changes since the last snapshot. Of course, they
|
|
|
|
/// can still be undone if there is a snapshot further out.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn commit(&mut self, snapshot: Snapshot<K>) {
|
2014-07-22 06:40:51 -05:00
|
|
|
debug!("{}: commit()", UnifyKey::tag(None::<K>));
|
|
|
|
self.values.commit(snapshot.snapshot);
|
2014-06-20 05:35:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_key(&mut self, value: V) -> K {
|
2014-07-22 06:40:51 -05:00
|
|
|
let index = self.values.push(Root(value, 0));
|
2014-06-20 05:35:06 -05:00
|
|
|
let k = UnifyKey::from_index(index);
|
2014-12-20 02:09:35 -06:00
|
|
|
debug!("{}: created new key: {:?}",
|
2014-06-20 05:35:06 -05:00
|
|
|
UnifyKey::tag(None::<K>),
|
|
|
|
k);
|
|
|
|
k
|
|
|
|
}
|
|
|
|
|
2014-11-25 20:17:11 -06:00
|
|
|
/// Find the root node for `vid`. This uses the standard union-find algorithm with path
|
|
|
|
/// compression: http://en.wikipedia.org/wiki/Disjoint-set_data_structure
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn get(&mut self, tcx: &ty::ctxt, vid: K) -> Node<K,V> {
|
|
|
|
let index = vid.index();
|
|
|
|
let value = (*self.values.get(index)).clone();
|
|
|
|
match value {
|
|
|
|
Redirect(redirect) => {
|
|
|
|
let node: Node<K,V> = self.get(tcx, redirect.clone());
|
|
|
|
if node.key != redirect {
|
|
|
|
// Path compression
|
2014-07-22 06:40:51 -05:00
|
|
|
self.values.set(index, Redirect(node.key.clone()));
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
2014-06-20 05:35:06 -05:00
|
|
|
node
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
2014-06-20 05:35:06 -05:00
|
|
|
Root(value, rank) => {
|
|
|
|
Node { key: vid, value: value, rank: rank }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_root(&self, key: &K) -> bool {
|
|
|
|
match *self.values.get(key.index()) {
|
|
|
|
Redirect(..) => false,
|
|
|
|
Root(..) => true,
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-25 20:17:11 -06:00
|
|
|
/// Sets the value for `vid` to `new_value`. `vid` MUST be a root node! Also, we must be in the
|
|
|
|
/// middle of a snapshot.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn set(&mut self,
|
2014-09-29 14:11:30 -05:00
|
|
|
tcx: &ty::ctxt<'tcx>,
|
2014-06-20 05:35:06 -05:00
|
|
|
key: K,
|
|
|
|
new_value: VarValue<K,V>)
|
|
|
|
{
|
|
|
|
assert!(self.is_root(&key));
|
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("Updating variable {} to {}",
|
2014-06-20 05:35:06 -05:00
|
|
|
key.repr(tcx),
|
|
|
|
new_value.repr(tcx));
|
2012-08-13 17:06:13 -05:00
|
|
|
|
2014-07-22 06:40:51 -05:00
|
|
|
self.values.set(key.index(), new_value);
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:17:11 -06:00
|
|
|
/// Either redirects node_a to node_b or vice versa, depending on the relative rank. Returns
|
|
|
|
/// the new root and rank. You should then update the value of the new root to something
|
|
|
|
/// suitable.
|
2014-06-20 05:35:06 -05:00
|
|
|
pub fn unify(&mut self,
|
2014-09-29 14:11:30 -05:00
|
|
|
tcx: &ty::ctxt<'tcx>,
|
2014-06-20 05:35:06 -05:00
|
|
|
node_a: &Node<K,V>,
|
|
|
|
node_b: &Node<K,V>)
|
|
|
|
-> (K, uint)
|
|
|
|
{
|
|
|
|
debug!("unify(node_a(id={}, rank={}), node_b(id={}, rank={}))",
|
|
|
|
node_a.key.repr(tcx),
|
|
|
|
node_a.rank,
|
|
|
|
node_b.key.repr(tcx),
|
|
|
|
node_b.rank);
|
2013-01-08 16:00:45 -06:00
|
|
|
|
|
|
|
if node_a.rank > node_b.rank {
|
2012-11-07 20:40:34 -06:00
|
|
|
// a has greater rank, so a should become b's parent,
|
|
|
|
// i.e., b should redirect to a.
|
2014-06-20 05:35:06 -05:00
|
|
|
self.set(tcx, node_b.key.clone(), Redirect(node_a.key.clone()));
|
|
|
|
(node_a.key.clone(), node_a.rank)
|
2013-01-08 16:00:45 -06:00
|
|
|
} else if node_a.rank < node_b.rank {
|
2012-11-07 20:40:34 -06:00
|
|
|
// b has greater rank, so a should redirect to b.
|
2014-06-20 05:35:06 -05:00
|
|
|
self.set(tcx, node_a.key.clone(), Redirect(node_b.key.clone()));
|
|
|
|
(node_b.key.clone(), node_b.rank)
|
2012-11-07 20:40:34 -06:00
|
|
|
} else {
|
2013-01-08 16:00:45 -06:00
|
|
|
// If equal, redirect one to the other and increment the
|
|
|
|
// other's rank.
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(node_a.rank, node_b.rank);
|
2014-06-20 05:35:06 -05:00
|
|
|
self.set(tcx, node_b.key.clone(), Redirect(node_a.key.clone()));
|
|
|
|
(node_a.key.clone(), node_a.rank + 1)
|
2012-08-13 17:06:13 -05:00
|
|
|
}
|
|
|
|
}
|
2012-09-07 20:53:14 -05:00
|
|
|
}
|
2012-11-07 20:40:34 -06:00
|
|
|
|
2014-07-22 06:40:51 -05:00
|
|
|
impl<K,V> sv::SnapshotVecDelegate<VarValue<K,V>,()> for Delegate {
|
|
|
|
fn reverse(&mut self, _: &mut Vec<VarValue<K,V>>, _: ()) {
|
2014-10-09 14:17:22 -05:00
|
|
|
panic!("Nothing to reverse");
|
2014-07-22 06:40:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Code to handle simple keys like ints, floats---anything that
|
2013-01-08 16:00:45 -06:00
|
|
|
// doesn't have a subtyping relationship we need to worry about.
|
|
|
|
|
2014-11-24 19:06:06 -06:00
|
|
|
/// Indicates a type that does not have any kind of subtyping
|
|
|
|
/// relationship.
|
2014-09-29 14:11:30 -05:00
|
|
|
pub trait SimplyUnifiable<'tcx> : Clone + PartialEq + Repr<'tcx> {
|
2014-12-25 06:20:48 -06:00
|
|
|
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
|
2014-09-29 14:11:30 -05:00
|
|
|
fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
pub fn err<'tcx, V:SimplyUnifiable<'tcx>>(a_is_expected: bool,
|
|
|
|
a_t: V,
|
|
|
|
b_t: V)
|
|
|
|
-> ures<'tcx> {
|
2013-01-22 09:02:40 -06:00
|
|
|
if a_is_expected {
|
|
|
|
Err(SimplyUnifiable::to_type_err(
|
|
|
|
ty::expected_found {expected: a_t, found: b_t}))
|
|
|
|
} else {
|
|
|
|
Err(SimplyUnifiable::to_type_err(
|
|
|
|
ty::expected_found {expected: b_t, found: a_t}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
pub trait InferCtxtMethodsForSimplyUnifiableTypes<'tcx, V:SimplyUnifiable<'tcx>,
|
|
|
|
K:UnifyKey<'tcx, Option<V>>> {
|
2014-06-20 05:35:06 -05:00
|
|
|
fn simple_vars(&self,
|
2013-06-14 20:21:47 -05:00
|
|
|
a_is_expected: bool,
|
2014-06-20 05:35:06 -05:00
|
|
|
a_id: K,
|
|
|
|
b_id: K)
|
2014-09-29 14:11:30 -05:00
|
|
|
-> ures<'tcx>;
|
2014-06-20 05:35:06 -05:00
|
|
|
fn simple_var_t(&self,
|
2013-06-14 20:21:47 -05:00
|
|
|
a_is_expected: bool,
|
2014-06-20 05:35:06 -05:00
|
|
|
a_id: K,
|
|
|
|
b: V)
|
2014-09-29 14:11:30 -05:00
|
|
|
-> ures<'tcx>;
|
|
|
|
fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>>;
|
2013-06-14 20:21:47 -05:00
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'a,'tcx,V:SimplyUnifiable<'tcx>,K:UnifyKey<'tcx, Option<V>>>
|
|
|
|
InferCtxtMethodsForSimplyUnifiableTypes<'tcx, V, K> for InferCtxt<'a, 'tcx>
|
2014-06-20 05:35:06 -05:00
|
|
|
{
|
2014-11-25 20:17:11 -06:00
|
|
|
/// Unifies two simple keys. Because simple keys do not have any subtyping relationships, if
|
|
|
|
/// both keys have already been associated with a value, then those two values must be the
|
|
|
|
/// same.
|
2014-06-20 05:35:06 -05:00
|
|
|
fn simple_vars(&self,
|
2013-06-14 20:21:47 -05:00
|
|
|
a_is_expected: bool,
|
2014-06-20 05:35:06 -05:00
|
|
|
a_id: K,
|
|
|
|
b_id: K)
|
2014-09-29 14:11:30 -05:00
|
|
|
-> ures<'tcx>
|
2014-06-20 05:35:06 -05:00
|
|
|
{
|
|
|
|
let tcx = self.tcx;
|
|
|
|
let table = UnifyKey::unification_table(self);
|
|
|
|
let node_a = table.borrow_mut().get(tcx, a_id);
|
|
|
|
let node_b = table.borrow_mut().get(tcx, b_id);
|
|
|
|
let a_id = node_a.key.clone();
|
|
|
|
let b_id = node_b.key.clone();
|
2012-11-07 20:40:34 -06:00
|
|
|
|
|
|
|
if a_id == b_id { return uok(); }
|
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
let combined = {
|
|
|
|
match (&node_a.value, &node_b.value) {
|
|
|
|
(&None, &None) => {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
(&Some(ref v), &None) | (&None, &Some(ref v)) => {
|
|
|
|
Some((*v).clone())
|
|
|
|
}
|
|
|
|
(&Some(ref v1), &Some(ref v2)) => {
|
|
|
|
if *v1 != *v2 {
|
|
|
|
return err(a_is_expected, (*v1).clone(), (*v2).clone())
|
|
|
|
}
|
|
|
|
Some((*v1).clone())
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
2013-01-08 16:00:45 -06:00
|
|
|
}
|
|
|
|
};
|
2012-11-07 20:40:34 -06:00
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
let (new_root, new_rank) = table.borrow_mut().unify(tcx,
|
|
|
|
&node_a,
|
|
|
|
&node_b);
|
|
|
|
table.borrow_mut().set(tcx, new_root, Root(combined, new_rank));
|
|
|
|
return Ok(())
|
2012-11-07 20:40:34 -06:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:17:11 -06:00
|
|
|
/// Sets the value of the key `a_id` to `b`. Because simple keys do not have any subtyping
|
|
|
|
/// relationships, if `a_id` already has a value, it must be the same as `b`.
|
2014-06-20 05:35:06 -05:00
|
|
|
fn simple_var_t(&self,
|
2013-06-14 20:21:47 -05:00
|
|
|
a_is_expected: bool,
|
2014-06-20 05:35:06 -05:00
|
|
|
a_id: K,
|
|
|
|
b: V)
|
2014-09-29 14:11:30 -05:00
|
|
|
-> ures<'tcx>
|
2014-06-20 05:35:06 -05:00
|
|
|
{
|
|
|
|
let tcx = self.tcx;
|
|
|
|
let table = UnifyKey::unification_table(self);
|
|
|
|
let node_a = table.borrow_mut().get(tcx, a_id);
|
|
|
|
let a_id = node_a.key.clone();
|
2013-01-08 16:00:45 -06:00
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
match node_a.value {
|
2013-01-22 09:02:40 -06:00
|
|
|
None => {
|
2014-06-20 05:35:06 -05:00
|
|
|
table.borrow_mut().set(tcx, a_id, Root(Some(b), node_a.rank));
|
|
|
|
return Ok(());
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
2012-11-07 20:40:34 -06:00
|
|
|
|
2013-01-22 09:02:40 -06:00
|
|
|
Some(ref a_t) => {
|
|
|
|
if *a_t == b {
|
2014-06-20 05:35:06 -05:00
|
|
|
return Ok(());
|
2013-01-22 09:02:40 -06:00
|
|
|
} else {
|
2014-06-20 05:35:06 -05:00
|
|
|
return err(a_is_expected, (*a_t).clone(), b);
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
}
|
2012-11-07 20:40:34 -06:00
|
|
|
}
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
2014-09-12 09:53:35 -05:00
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>> {
|
2014-09-12 09:53:35 -05:00
|
|
|
let tcx = self.tcx;
|
|
|
|
let table = UnifyKey::unification_table(self);
|
|
|
|
let node_a = table.borrow_mut().get(tcx, a_id);
|
|
|
|
match node_a.value {
|
|
|
|
None => None,
|
2014-12-25 06:20:48 -06:00
|
|
|
Some(ref a_t) => Some(a_t.to_type(tcx))
|
2014-09-12 09:53:35 -05:00
|
|
|
}
|
|
|
|
}
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
2013-01-08 16:00:45 -06:00
|
|
|
|
2014-06-20 05:35:06 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Integral type keys
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> UnifyKey<'tcx, Option<IntVarValue>> for ty::IntVid {
|
2014-12-04 14:06:42 -06:00
|
|
|
fn index(&self) -> uint { self.index as uint }
|
2014-06-20 05:35:06 -05:00
|
|
|
|
2014-12-04 14:06:42 -06:00
|
|
|
fn from_index(i: uint) -> ty::IntVid { ty::IntVid { index: i as u32 } }
|
2014-06-20 05:35:06 -05:00
|
|
|
|
|
|
|
fn unification_table<'v>(infcx: &'v InferCtxt)
|
|
|
|
-> &'v RefCell<UnificationTable<ty::IntVid, Option<IntVarValue>>>
|
|
|
|
{
|
|
|
|
return &infcx.int_unification_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tag(_: Option<ty::IntVid>) -> &'static str {
|
|
|
|
"IntVid"
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> SimplyUnifiable<'tcx> for IntVarValue {
|
2014-12-25 06:20:48 -06:00
|
|
|
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
|
2014-09-12 09:53:35 -05:00
|
|
|
match *self {
|
2014-12-25 06:20:48 -06:00
|
|
|
ty::IntType(i) => ty::mk_mach_int(tcx, i),
|
|
|
|
ty::UintType(i) => ty::mk_mach_uint(tcx, i),
|
2014-09-12 09:53:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
fn to_type_err(err: expected_found<IntVarValue>) -> ty::type_err<'tcx> {
|
2013-01-22 09:02:40 -06:00
|
|
|
return ty::terr_int_mismatch(err);
|
2012-11-07 20:40:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> UnifyValue<'tcx> for Option<IntVarValue> { }
|
2014-06-20 05:35:06 -05:00
|
|
|
|
|
|
|
// Floating point type keys
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> UnifyKey<'tcx, Option<ast::FloatTy>> for ty::FloatVid {
|
2014-12-04 14:06:42 -06:00
|
|
|
fn index(&self) -> uint { self.index as uint }
|
2014-06-20 05:35:06 -05:00
|
|
|
|
2014-12-04 14:06:42 -06:00
|
|
|
fn from_index(i: uint) -> ty::FloatVid { ty::FloatVid { index: i as u32 } }
|
2014-06-20 05:35:06 -05:00
|
|
|
|
|
|
|
fn unification_table<'v>(infcx: &'v InferCtxt)
|
|
|
|
-> &'v RefCell<UnificationTable<ty::FloatVid, Option<ast::FloatTy>>>
|
|
|
|
{
|
|
|
|
return &infcx.float_unification_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tag(_: Option<ty::FloatVid>) -> &'static str {
|
|
|
|
"FloatVid"
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> UnifyValue<'tcx> for Option<ast::FloatTy> {
|
2014-06-20 05:35:06 -05:00
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
|
2014-12-25 06:20:48 -06:00
|
|
|
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
|
|
|
|
ty::mk_mach_float(tcx, *self)
|
2014-09-12 09:53:35 -05:00
|
|
|
}
|
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
fn to_type_err(err: expected_found<ast::FloatTy>) -> ty::type_err<'tcx> {
|
|
|
|
ty::terr_float_mismatch(err)
|
2013-01-22 09:02:40 -06:00
|
|
|
}
|
|
|
|
}
|
2014-08-27 20:46:52 -05:00
|
|
|
|
2014-09-29 14:11:30 -05:00
|
|
|
impl<'tcx, K:Repr<'tcx>, V:Repr<'tcx>> Repr<'tcx> for VarValue<K,V> {
|
|
|
|
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
2014-08-27 20:46:52 -05:00
|
|
|
match *self {
|
|
|
|
Redirect(ref k) => format!("Redirect({})", k.repr(tcx)),
|
|
|
|
Root(ref v, r) => format!("Root({}, {})", v.repr(tcx), r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|