update pair to handle alias
This commit is contained in:
parent
d05d8e7de6
commit
61a021f9e3
|
@ -970,6 +970,11 @@ pub enum Annotation {
|
||||||
location: Span,
|
location: Span,
|
||||||
elems: Vec<Self>,
|
elems: Vec<Self>,
|
||||||
},
|
},
|
||||||
|
Pair {
|
||||||
|
location: Span,
|
||||||
|
fst: Box<Self>,
|
||||||
|
snd: Box<Self>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Annotation {
|
impl Annotation {
|
||||||
|
@ -979,7 +984,8 @@ impl Annotation {
|
||||||
| Annotation::Tuple { location, .. }
|
| Annotation::Tuple { location, .. }
|
||||||
| Annotation::Var { location, .. }
|
| Annotation::Var { location, .. }
|
||||||
| Annotation::Hole { location, .. }
|
| Annotation::Hole { location, .. }
|
||||||
| Annotation::Constructor { location, .. } => *location,
|
| Annotation::Constructor { location, .. }
|
||||||
|
| Annotation::Pair { location, .. } => *location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,6 +1087,18 @@ impl Annotation {
|
||||||
} => name == o_name,
|
} => name == o_name,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
Annotation::Pair { fst, snd, .. } => {
|
||||||
|
if let Annotation::Pair {
|
||||||
|
fst: o_fst,
|
||||||
|
snd: o_snd,
|
||||||
|
..
|
||||||
|
} = other
|
||||||
|
{
|
||||||
|
fst.is_logically_equal(o_fst) && snd.is_logically_equal(o_snd)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1335,7 +1335,11 @@ pub fn tuple(elems: Vec<Rc<Type>>) -> Rc<Type> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pair(fst: Rc<Type>, snd: Rc<Type>) -> Rc<Type> {
|
pub fn pair(fst: Rc<Type>, snd: Rc<Type>) -> Rc<Type> {
|
||||||
Rc::new(Type::Pair { fst, snd })
|
Rc::new(Type::Pair {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
alias: None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bool() -> Rc<Type> {
|
pub fn bool() -> Rc<Type> {
|
||||||
|
|
|
@ -424,6 +424,7 @@ impl<'comments> Formatter<'comments> {
|
||||||
Annotation::Tuple { elems, .. } => {
|
Annotation::Tuple { elems, .. } => {
|
||||||
wrap_args(elems.iter().map(|t| (self.annotation(t), false)))
|
wrap_args(elems.iter().map(|t| (self.annotation(t), false)))
|
||||||
}
|
}
|
||||||
|
Annotation::Pair { .. } => todo!(),
|
||||||
}
|
}
|
||||||
.group()
|
.group()
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ pub enum Type {
|
||||||
Pair {
|
Pair {
|
||||||
fst: Rc<Type>,
|
fst: Rc<Type>,
|
||||||
snd: Rc<Type>,
|
snd: Rc<Type>,
|
||||||
|
alias: Option<Rc<TypeAliasAnnotation>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +144,18 @@ impl PartialEq for Type {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Type::Pair { fst, snd, .. } => {
|
||||||
|
if let Type::Pair {
|
||||||
|
fst: fst2,
|
||||||
|
snd: snd2,
|
||||||
|
..
|
||||||
|
} = other
|
||||||
|
{
|
||||||
|
fst == fst2 && snd == snd2
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +166,8 @@ impl Type {
|
||||||
Type::App { alias, .. }
|
Type::App { alias, .. }
|
||||||
| Type::Fn { alias, .. }
|
| Type::Fn { alias, .. }
|
||||||
| Type::Var { alias, .. }
|
| Type::Var { alias, .. }
|
||||||
| Type::Tuple { alias, .. } => alias.clone(),
|
| Type::Tuple { alias, .. }
|
||||||
|
| Type::Pair { alias, .. } => alias.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +202,7 @@ impl Type {
|
||||||
} => Type::Fn { args, ret, alias },
|
} => Type::Fn { args, ret, alias },
|
||||||
Type::Var { tipo, alias: _ } => Type::Var { tipo, alias },
|
Type::Var { tipo, alias: _ } => Type::Var { tipo, alias },
|
||||||
Type::Tuple { elems, alias: _ } => Type::Tuple { elems, alias },
|
Type::Tuple { elems, alias: _ } => Type::Tuple { elems, alias },
|
||||||
|
Type::Pair { fst, snd, alias: _ } => Type::Pair { fst, snd, alias },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +215,7 @@ impl Type {
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Type::Tuple { .. } => Some((String::new(), "Tuple".to_string())),
|
Type::Tuple { .. } => Some((String::new(), "Tuple".to_string())),
|
||||||
|
Type::Pair { .. } => Some((String::new(), "Pair".to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,14 +366,14 @@ impl Type {
|
||||||
.first()
|
.first()
|
||||||
.expect("unreachable: List should have an inner type")
|
.expect("unreachable: List should have an inner type")
|
||||||
.is_pair(),
|
.is_pair(),
|
||||||
Self::Var { tipo } => tipo.borrow().is_map(),
|
Self::Var { tipo, .. } => tipo.borrow().is_map(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_tuple(&self) -> bool {
|
pub fn is_tuple(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Var { tipo } => tipo.borrow().is_tuple(),
|
Self::Var { tipo, .. } => tipo.borrow().is_tuple(),
|
||||||
Self::Tuple { .. } => true,
|
Self::Tuple { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -365,7 +381,7 @@ impl Type {
|
||||||
|
|
||||||
pub fn is_pair(&self) -> bool {
|
pub fn is_pair(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Var { tipo } => tipo.borrow().is_pair(),
|
Self::Var { tipo, .. } => tipo.borrow().is_pair(),
|
||||||
Self::Pair { .. } => true,
|
Self::Pair { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -389,22 +405,22 @@ impl Type {
|
||||||
is_a_generic
|
is_a_generic
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Var { tipo } => tipo.borrow().is_generic(),
|
Self::Var { tipo, .. } => tipo.borrow().is_generic(),
|
||||||
Self::Tuple { elems } => {
|
Self::Tuple { elems, .. } => {
|
||||||
let mut is_a_generic = false;
|
let mut is_a_generic = false;
|
||||||
for elem in elems {
|
for elem in elems {
|
||||||
is_a_generic = is_a_generic || elem.is_generic();
|
is_a_generic = is_a_generic || elem.is_generic();
|
||||||
}
|
}
|
||||||
is_a_generic
|
is_a_generic
|
||||||
}
|
}
|
||||||
Self::Fn { args, ret } => {
|
Self::Fn { args, ret, .. } => {
|
||||||
let mut is_a_generic = false;
|
let mut is_a_generic = false;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
is_a_generic = is_a_generic || arg.is_generic();
|
is_a_generic = is_a_generic || arg.is_generic();
|
||||||
}
|
}
|
||||||
is_a_generic || ret.is_generic()
|
is_a_generic || ret.is_generic()
|
||||||
}
|
}
|
||||||
Self::Pair { fst, snd } => fst.is_generic() || snd.is_generic(),
|
Self::Pair { fst, snd, .. } => fst.is_generic() || snd.is_generic(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +435,7 @@ impl Type {
|
||||||
|
|
||||||
pub fn get_generic(&self) -> Option<u64> {
|
pub fn get_generic(&self) -> Option<u64> {
|
||||||
match self {
|
match self {
|
||||||
Self::Var { tipo } => tipo.borrow().get_generic(),
|
Self::Var { tipo, .. } => tipo.borrow().get_generic(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +486,7 @@ impl Type {
|
||||||
} else if self.is_tuple() {
|
} else if self.is_tuple() {
|
||||||
match self {
|
match self {
|
||||||
Self::Tuple { .. } => UplcType::List(UplcType::Data.into()),
|
Self::Tuple { .. } => UplcType::List(UplcType::Data.into()),
|
||||||
Self::Var { tipo } => tipo.borrow().get_uplc_type().unwrap(),
|
Self::Var { tipo, .. } => tipo.borrow().get_uplc_type().unwrap(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
} else if self.is_pair() {
|
} else if self.is_pair() {
|
||||||
|
@ -563,7 +579,7 @@ impl Type {
|
||||||
|
|
||||||
TypeVar::Link { tipo, .. } => tipo.find_private_type(),
|
TypeVar::Link { tipo, .. } => tipo.find_private_type(),
|
||||||
},
|
},
|
||||||
Self::Pair { fst, snd } => {
|
Self::Pair { fst, snd, .. } => {
|
||||||
if let Some(private_type) = fst.find_private_type() {
|
if let Some(private_type) = fst.find_private_type() {
|
||||||
Some(private_type)
|
Some(private_type)
|
||||||
} else {
|
} else {
|
||||||
|
@ -749,6 +765,16 @@ pub fn convert_opaque_type(
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
Type::Pair { fst, snd, alias } => {
|
||||||
|
let fst = convert_opaque_type(fst, data_types, deep);
|
||||||
|
let snd = convert_opaque_type(snd, data_types, deep);
|
||||||
|
Type::Pair {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
alias: alias.clone(),
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -838,6 +864,16 @@ pub fn find_and_replace_generics(
|
||||||
TypeVar::Generic { .. } | TypeVar::Unbound { .. } => unreachable!(),
|
TypeVar::Generic { .. } | TypeVar::Unbound { .. } => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Type::Pair { fst, snd, alias } => {
|
||||||
|
let fst = find_and_replace_generics(fst, mono_types);
|
||||||
|
let snd = find_and_replace_generics(snd, mono_types);
|
||||||
|
Type::Pair {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
alias: alias.clone(),
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tipo.clone()
|
tipo.clone()
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedPattern,
|
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedPattern,
|
||||||
UnqualifiedImport, UntypedArg, UntypedDefinition, Use, Validator, PIPE_VARIABLE,
|
UnqualifiedImport, UntypedArg, UntypedDefinition, Use, Validator, PIPE_VARIABLE,
|
||||||
},
|
},
|
||||||
builtins::{function, generic_var, tuple, unbound_var},
|
builtins::{function, generic_var, pair, tuple, unbound_var},
|
||||||
tipo::{fields::FieldMap, TypeAliasAnnotation},
|
tipo::{fields::FieldMap, TypeAliasAnnotation},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
@ -644,6 +644,13 @@ impl<'a> Environment<'a> {
|
||||||
),
|
),
|
||||||
alias.clone(),
|
alias.clone(),
|
||||||
),
|
),
|
||||||
|
Type::Pair { fst, snd, alias } => Type::with_alias(
|
||||||
|
pair(
|
||||||
|
self.instantiate(fst.clone(), ids, hydrator),
|
||||||
|
self.instantiate(snd.clone(), ids, hydrator),
|
||||||
|
),
|
||||||
|
alias.clone(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1794,7 +1801,7 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Type::Pair { fst, snd } => {
|
Type::Pair { fst, snd, .. } => {
|
||||||
unify_unbound_type(fst.clone(), own_id, location)?;
|
unify_unbound_type(fst.clone(), own_id, location)?;
|
||||||
unify_unbound_type(snd.clone(), own_id, location)?;
|
unify_unbound_type(snd.clone(), own_id, location)?;
|
||||||
|
|
||||||
|
@ -1976,5 +1983,12 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
),
|
),
|
||||||
alias.clone(),
|
alias.clone(),
|
||||||
),
|
),
|
||||||
|
Type::Pair { fst, snd, alias } => Type::with_alias(
|
||||||
|
pair(
|
||||||
|
generalise(fst.clone(), ctx_level),
|
||||||
|
generalise(snd.clone(), ctx_level),
|
||||||
|
),
|
||||||
|
alias.clone(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2442,5 +2442,9 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
||||||
location,
|
location,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
Type::Pair { fst, snd, .. } => {
|
||||||
|
ensure_serialisable(false, fst.clone(), location)?;
|
||||||
|
ensure_serialisable(false, snd.clone(), location)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::Annotation,
|
ast::Annotation,
|
||||||
builtins::{function, tuple},
|
builtins::{function, pair, tuple},
|
||||||
tipo::Span,
|
tipo::Span,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
@ -246,6 +246,12 @@ impl Hydrator {
|
||||||
|
|
||||||
Ok(tuple(typed_elems))
|
Ok(tuple(typed_elems))
|
||||||
}
|
}
|
||||||
|
Annotation::Pair { fst, snd, .. } => {
|
||||||
|
let fst = self.do_type_from_annotation(fst, environment, unbounds)?;
|
||||||
|
let snd = self.do_type_from_annotation(snd, environment, unbounds)?;
|
||||||
|
|
||||||
|
Ok(pair(fst, snd))
|
||||||
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
Ok(environment.annotate(return_type, annotation))
|
Ok(environment.annotate(return_type, annotation))
|
||||||
|
|
|
@ -843,7 +843,7 @@ fn infer_fuzzer(
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
Type::App { .. } | Type::Tuple { .. } => Err(could_not_unify()),
|
Type::App { .. } | Type::Tuple { .. } | Type::Pair { .. } => Err(could_not_unify()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,5 +894,14 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
location: *location,
|
location: *location,
|
||||||
tipo: Rc::new(tipo.clone()),
|
tipo: Rc::new(tipo.clone()),
|
||||||
}),
|
}),
|
||||||
|
Type::Pair { fst, snd, .. } => {
|
||||||
|
let fst = annotate_fuzzer(fst, location)?;
|
||||||
|
let snd = annotate_fuzzer(snd, location)?;
|
||||||
|
Ok(Annotation::Pair {
|
||||||
|
fst: Box::new(fst),
|
||||||
|
snd: Box::new(snd),
|
||||||
|
location: *location,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl Printer {
|
||||||
Type::Var { tipo: typ, .. } => self.type_var_doc(&typ.borrow()),
|
Type::Var { tipo: typ, .. } => self.type_var_doc(&typ.borrow()),
|
||||||
|
|
||||||
Type::Tuple { elems, .. } => self.args_to_aiken_doc(elems).surround("(", ")"),
|
Type::Tuple { elems, .. } => self.args_to_aiken_doc(elems).surround("(", ")"),
|
||||||
Type::Pair { fst, snd } => self
|
Type::Pair { fst, snd, .. } => self
|
||||||
.args_to_aiken_doc(&[fst.clone(), snd.clone()])
|
.args_to_aiken_doc(&[fst.clone(), snd.clone()])
|
||||||
.surround("Pair<", ">"),
|
.surround("Pair<", ">"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl Reference {
|
||||||
elems = Self::from_types(elems, type_parameters)
|
elems = Self::from_types(elems, type_parameters)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Type::Pair { fst, snd } => Self {
|
Type::Pair { fst, snd, .. } => Self {
|
||||||
inner: format!(
|
inner: format!(
|
||||||
"Pair{fst}{snd}",
|
"Pair{fst}{snd}",
|
||||||
fst = Self::from_type(fst, type_parameters),
|
fst = Self::from_type(fst, type_parameters),
|
||||||
|
|
Loading…
Reference in New Issue