1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
use crate::cast::UpcastFrom;
use crate::term::CoreTerm;
use crate::variable::{CoreBoundVar, CoreExistentialVar, CoreUniversalVar, CoreVariable};
use std::fmt::Debug;
use std::hash::Hash;
/// The definition of a "language"
pub trait Language: 'static + Copy + Ord + Hash + Debug + Default {
/// Name of the language, e.g., `"Rust"`
const NAME: &'static str;
/// An enum defining the *kinds* of generic parameters (e.g., for Rust,
/// types, lifetimes, and constants).
type Kind: Copy + CoreTerm<Self>;
/// An enum defining the *value* of a generic parameter (e.g., a
/// type, a lifetime, etc)
type Parameter: HasKind<Self>
+ CoreTerm<Self>
+ UpcastFrom<CoreVariable<Self>>
+ UpcastFrom<CoreUniversalVar<Self>>
+ UpcastFrom<CoreExistentialVar<Self>>
+ UpcastFrom<CoreBoundVar<Self>>;
/// The character (typically `<`) used to open binders.
const BINDING_OPEN: char;
/// The character (typically `>`) used to open binders.
const BINDING_CLOSE: char;
}
/// For consistency with types like `CoreVariable<L>`, we write `CoreKind<L>` instead of `Kind<L>`.
pub type CoreKind<L: Language> = L::Kind;
/// For consistency with types like `CoreVariable<L>`, we write `CoreParameter<L>` instead of `Parameter<L>`.
pub type CoreParameter<L: Language> = L::Parameter;
pub trait HasKind<L: Language> {
fn kind(&self) -> CoreKind<L>;
}