Fix pairs not being unwrapped when wrapped as fields
This commit is contained in:
parent
25e4b42cd0
commit
27bf40260e
|
@ -5371,6 +5371,11 @@ impl<'a> CodeGenerator<'a> {
|
|||
))
|
||||
}
|
||||
}
|
||||
Air::ExtractField { tipo } => {
|
||||
let arg = arg_stack.pop().unwrap();
|
||||
|
||||
Some(known_data_to_type(Term::head_list().apply(arg), &tipo))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,13 +211,16 @@ pub enum Air {
|
|||
tipo: Rc<Type>,
|
||||
is_expect: bool,
|
||||
},
|
||||
// Tuple Access
|
||||
// Pair Access
|
||||
PairAccessor {
|
||||
fst: Option<String>,
|
||||
snd: Option<String>,
|
||||
tipo: Rc<Type>,
|
||||
is_expect: bool,
|
||||
},
|
||||
ExtractField {
|
||||
tipo: Rc<Type>,
|
||||
},
|
||||
// Misc.
|
||||
ErrorTerm {
|
||||
tipo: Rc<Type>,
|
||||
|
|
|
@ -27,6 +27,7 @@ pub enum Path {
|
|||
Pair(usize),
|
||||
Tuple(usize),
|
||||
Constr(Rc<Type>, usize),
|
||||
OpaqueConstr(Rc<Type>),
|
||||
List(usize),
|
||||
ListTail(usize),
|
||||
}
|
||||
|
@ -43,6 +44,7 @@ impl ToString for Path {
|
|||
Path::Constr(_, i) => {
|
||||
format!("constr_{}", i)
|
||||
}
|
||||
Path::OpaqueConstr(_) => "opaqueconstr".to_string(),
|
||||
Path::List(i) => {
|
||||
format!("list_{}", i)
|
||||
}
|
||||
|
@ -61,6 +63,7 @@ impl PartialEq for Path {
|
|||
| (Path::Constr(_, a), Path::Constr(_, b))
|
||||
| (Path::List(a), Path::List(b))
|
||||
| (Path::ListTail(a), Path::ListTail(b)) => a == b,
|
||||
(Path::OpaqueConstr(_), Path::OpaqueConstr(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1094,6 +1097,9 @@ impl<'a, 'b> TreeGen<'a, 'b> {
|
|||
} => {
|
||||
let data_type = lookup_data_type_by_tipo(self.data_types, ¤t_tipo).unwrap();
|
||||
|
||||
let is_transparent =
|
||||
data_type.opaque && data_type.constructors[0].arguments.len() == 1;
|
||||
|
||||
if data_type.constructors.len() == 1 || data_type.is_never() {
|
||||
arguments
|
||||
.iter()
|
||||
|
@ -1103,7 +1109,11 @@ impl<'a, 'b> TreeGen<'a, 'b> {
|
|||
|
||||
let mut item_path = path.clone();
|
||||
|
||||
item_path.push(Path::Constr(tipo.clone(), index));
|
||||
if is_transparent {
|
||||
item_path.push(Path::OpaqueConstr(tipo.clone()));
|
||||
} else {
|
||||
item_path.push(Path::Constr(tipo.clone(), index));
|
||||
}
|
||||
|
||||
let (assigns, patts) =
|
||||
self.map_pattern_to_row(arg_value, subject_tipo, item_path);
|
||||
|
@ -1199,6 +1209,10 @@ pub fn get_tipo_by_path(mut subject_tipo: Rc<Type>, mut path: &[Path]) -> Rc<Typ
|
|||
Path::List(_) => subject_tipo.get_inner_types().swap_remove(0),
|
||||
Path::ListTail(_) => subject_tipo,
|
||||
Path::Constr(tipo, index) => tipo.arg_types().unwrap().swap_remove(*index),
|
||||
Path::OpaqueConstr(tipo) => {
|
||||
let x = tipo.arg_types().unwrap().swap_remove(0);
|
||||
x
|
||||
}
|
||||
};
|
||||
|
||||
path = rest
|
||||
|
|
|
@ -14,6 +14,7 @@ use super::{
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum Builtin {
|
||||
HeadList(Rc<Type>),
|
||||
ExtractField(Rc<Type>),
|
||||
TailList,
|
||||
UnConstrFields,
|
||||
FstPair(Rc<Type>),
|
||||
|
@ -24,6 +25,7 @@ impl PartialEq for Builtin {
|
|||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Builtin::HeadList(_), Builtin::HeadList(_))
|
||||
| (Builtin::ExtractField(_), Builtin::ExtractField(_))
|
||||
| (Builtin::TailList, Builtin::TailList)
|
||||
| (Builtin::UnConstrFields, Builtin::UnConstrFields)
|
||||
| (Builtin::FstPair(_), Builtin::FstPair(_))
|
||||
|
@ -39,6 +41,7 @@ impl Builtin {
|
|||
fn to_air_call(self, special_funcs: &mut CodeGenSpecialFuncs, arg: AirTree) -> AirTree {
|
||||
match self {
|
||||
Builtin::HeadList(t) => AirTree::builtin(DefaultFunction::HeadList, t, vec![arg]),
|
||||
Builtin::ExtractField(t) => AirTree::extract_field(t, arg),
|
||||
Builtin::TailList => AirTree::builtin(
|
||||
DefaultFunction::TailList,
|
||||
Type::list(Type::data()),
|
||||
|
@ -58,10 +61,9 @@ impl Builtin {
|
|||
pub fn tipo(&self) -> Rc<Type> {
|
||||
match self {
|
||||
Builtin::HeadList(t) => t.clone(),
|
||||
Builtin::ExtractField(t) => t.clone(),
|
||||
Builtin::TailList => Type::list(Type::data()),
|
||||
|
||||
Builtin::UnConstrFields => Type::list(Type::data()),
|
||||
|
||||
Builtin::FstPair(t) => t.clone(),
|
||||
Builtin::SndPair(t) => t.clone(),
|
||||
}
|
||||
|
@ -72,6 +74,7 @@ impl ToString for Builtin {
|
|||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Builtin::HeadList(_) => "head".to_string(),
|
||||
Builtin::ExtractField(_) => "extractfield".to_string(),
|
||||
Builtin::TailList => "tail".to_string(),
|
||||
Builtin::UnConstrFields => "unconstrfields".to_string(),
|
||||
Builtin::FstPair(_) => "fst".to_string(),
|
||||
|
@ -110,6 +113,8 @@ impl Builtins {
|
|||
.into_iter()
|
||||
.fold((vec![], vec![]), |(mut builtins, mut rebuilt_path), i| {
|
||||
rebuilt_path.push(i.clone());
|
||||
let is_list = matches!(i, Path::List(_));
|
||||
|
||||
match i {
|
||||
Path::Pair(i) => {
|
||||
if i == 0 {
|
||||
|
@ -133,10 +138,17 @@ impl Builtins {
|
|||
builtins.push(Builtin::TailList);
|
||||
}
|
||||
|
||||
builtins.push(Builtin::HeadList(get_tipo_by_path(
|
||||
subject_tipo.clone(),
|
||||
&rebuilt_path,
|
||||
)));
|
||||
if is_list {
|
||||
builtins.push(Builtin::HeadList(get_tipo_by_path(
|
||||
subject_tipo.clone(),
|
||||
&rebuilt_path,
|
||||
)));
|
||||
} else {
|
||||
builtins.push(Builtin::ExtractField(get_tipo_by_path(
|
||||
subject_tipo.clone(),
|
||||
&rebuilt_path,
|
||||
)));
|
||||
}
|
||||
|
||||
(builtins, rebuilt_path)
|
||||
}
|
||||
|
@ -147,7 +159,7 @@ impl Builtins {
|
|||
builtins.push(Builtin::TailList);
|
||||
}
|
||||
|
||||
builtins.push(Builtin::HeadList(get_tipo_by_path(
|
||||
builtins.push(Builtin::ExtractField(get_tipo_by_path(
|
||||
subject_tipo.clone(),
|
||||
&rebuilt_path,
|
||||
)));
|
||||
|
@ -162,6 +174,7 @@ impl Builtins {
|
|||
|
||||
(builtins, rebuilt_path)
|
||||
}
|
||||
Path::OpaqueConstr(_) => (builtins, rebuilt_path),
|
||||
}
|
||||
})
|
||||
.0,
|
||||
|
|
|
@ -235,6 +235,10 @@ pub enum AirTree {
|
|||
then: Box<AirTree>,
|
||||
otherwise: Box<AirTree>,
|
||||
},
|
||||
ExtractField {
|
||||
tipo: Rc<Type>,
|
||||
arg: Box<AirTree>,
|
||||
},
|
||||
// Misc.
|
||||
FieldsEmpty {
|
||||
constr: Box<AirTree>,
|
||||
|
@ -970,6 +974,13 @@ impl AirTree {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn extract_field(tipo: Rc<Type>, arg: AirTree) -> AirTree {
|
||||
AirTree::ExtractField {
|
||||
tipo,
|
||||
arg: arg.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pair_index(index: usize, tipo: Rc<Type>, tuple: AirTree) -> AirTree {
|
||||
AirTree::cast_from_data(
|
||||
AirTree::builtin(
|
||||
|
@ -1651,6 +1662,13 @@ impl AirTree {
|
|||
msg.create_air_vec(air_vec);
|
||||
then.create_air_vec(air_vec);
|
||||
}
|
||||
AirTree::ExtractField {
|
||||
tipo,
|
||||
arg: args_list,
|
||||
} => {
|
||||
air_vec.push(Air::ExtractField { tipo: tipo.clone() });
|
||||
args_list.create_air_vec(air_vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1666,6 +1684,7 @@ impl AirTree {
|
|||
| AirTree::Pair { tipo, .. }
|
||||
| AirTree::Call { tipo, .. }
|
||||
| AirTree::Builtin { tipo, .. }
|
||||
| AirTree::ExtractField { tipo, .. }
|
||||
| AirTree::BinOp { tipo, .. }
|
||||
| AirTree::CastFromData { tipo, .. }
|
||||
| AirTree::When { tipo, .. }
|
||||
|
@ -1728,6 +1747,7 @@ impl AirTree {
|
|||
| AirTree::Tuple { tipo, .. }
|
||||
| AirTree::Call { tipo, .. }
|
||||
| AirTree::Builtin { tipo, .. }
|
||||
| AirTree::ExtractField { tipo, .. }
|
||||
| AirTree::CastFromData { tipo, .. }
|
||||
| AirTree::CastToData { tipo, .. }
|
||||
| AirTree::If { tipo, .. }
|
||||
|
@ -2077,7 +2097,8 @@ impl AirTree {
|
|||
| AirTree::Constr { .. }
|
||||
| AirTree::RecordUpdate { .. }
|
||||
| AirTree::ErrorTerm { .. }
|
||||
| AirTree::Trace { .. } => {}
|
||||
| AirTree::Trace { .. }
|
||||
| AirTree::ExtractField { .. } => {}
|
||||
}
|
||||
|
||||
match self {
|
||||
|
@ -2191,6 +2212,9 @@ impl AirTree {
|
|||
);
|
||||
}
|
||||
}
|
||||
AirTree::ExtractField { tipo: _, arg } => {
|
||||
arg.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
|
||||
}
|
||||
AirTree::BinOp {
|
||||
name: _,
|
||||
tipo: _,
|
||||
|
@ -2735,6 +2759,10 @@ impl AirTree {
|
|||
.do_find_air_tree_node(tree_path_iter),
|
||||
_ => panic!("Tree Path index outside tree children nodes"),
|
||||
},
|
||||
AirTree::ExtractField { tipo: _, arg } => match field {
|
||||
Fields::SecondField => arg.as_mut().do_find_air_tree_node(tree_path_iter),
|
||||
_ => panic!("Tree Path index outside tree children nodes"),
|
||||
},
|
||||
AirTree::Pair { tipo: _, fst, snd } => match field {
|
||||
Fields::SecondField => fst.as_mut().do_find_air_tree_node(tree_path_iter),
|
||||
Fields::ThirdField => snd.as_mut().do_find_air_tree_node(tree_path_iter),
|
||||
|
|
Loading…
Reference in New Issue