Fix castfromData in record access cases

This commit is contained in:
microproofs 2024-06-13 14:06:11 -04:00 committed by Lucas
parent 00d1927dad
commit 41b941e0e3
3 changed files with 33 additions and 7 deletions

View File

@ -901,7 +901,7 @@ impl<'a> CodeGenerator<'a> {
// Cast value to or from data so we don't have to worry from this point onward // Cast value to or from data so we don't have to worry from this point onward
if props.value_type.is_data() && props.kind.is_expect() && !tipo.is_data() { if props.value_type.is_data() && props.kind.is_expect() && !tipo.is_data() {
value = AirTree::cast_from_data(value, tipo.clone(), props.otherwise.clone()); value = AirTree::cast_from_data(value, tipo.clone(), props.otherwise.clone(), true);
} else if !props.value_type.is_data() && tipo.is_data() { } else if !props.value_type.is_data() && tipo.is_data() {
value = AirTree::cast_to_data(value, props.value_type.clone()); value = AirTree::cast_to_data(value, props.value_type.clone());
} }
@ -1648,6 +1648,7 @@ impl<'a> CodeGenerator<'a> {
AirTree::local_var(&item_name, data()), AirTree::local_var(&item_name, data()),
inner_list_type.clone(), inner_list_type.clone(),
otherwise.clone(), otherwise.clone(),
true,
), ),
defined_data_types, defined_data_types,
location, location,
@ -4766,11 +4767,20 @@ impl<'a> CodeGenerator<'a> {
Some(term) Some(term)
} }
Air::CastFromData { tipo, .. } => { Air::CastFromData { tipo, full_cast } => {
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
let otherwise = arg_stack.pop().unwrap();
term = convert_data_to_type(term, &tipo, otherwise); let otherwise = if full_cast {
arg_stack.pop().unwrap()
} else {
Term::Error
};
term = if full_cast {
convert_data_to_type(term, &tipo, otherwise)
} else {
known_data_to_type(term, &tipo)
};
if extract_constant(&term).is_some() { if extract_constant(&term).is_some() {
let mut program: Program<Name> = Program { let mut program: Program<Name> = Program {

View File

@ -102,6 +102,7 @@ pub enum Air {
}, },
CastFromData { CastFromData {
tipo: Rc<Type>, tipo: Rc<Type>,
full_cast: bool,
}, },
CastToData { CastToData {
tipo: Rc<Type>, tipo: Rc<Type>,

View File

@ -298,6 +298,7 @@ pub enum AirTree {
tipo: Rc<Type>, tipo: Rc<Type>,
value: Box<AirTree>, value: Box<AirTree>,
otherwise: Box<AirTree>, otherwise: Box<AirTree>,
full_cast: bool,
}, },
CastToData { CastToData {
tipo: Rc<Type>, tipo: Rc<Type>,
@ -566,11 +567,17 @@ impl AirTree {
} }
} }
pub fn cast_from_data(value: AirTree, tipo: Rc<Type>, otherwise: AirTree) -> AirTree { pub fn cast_from_data(
value: AirTree,
tipo: Rc<Type>,
otherwise: AirTree,
full_cast: bool,
) -> AirTree {
AirTree::CastFromData { AirTree::CastFromData {
tipo, tipo,
value: value.into(), value: value.into(),
otherwise: otherwise.into(), otherwise: otherwise.into(),
full_cast,
} }
} }
@ -837,6 +844,7 @@ impl AirTree {
), ),
tipo.clone(), tipo.clone(),
AirTree::error(void(), false), AirTree::error(void(), false),
false,
) )
} }
@ -942,6 +950,7 @@ impl AirTree {
), ),
tipo.clone(), tipo.clone(),
AirTree::error(void(), false), AirTree::error(void(), false),
false,
) )
} }
@ -1406,12 +1415,18 @@ impl AirTree {
tipo, tipo,
value, value,
otherwise, otherwise,
full_cast,
} => { } => {
air_vec.push(Air::CastFromData { tipo: tipo.clone() }); air_vec.push(Air::CastFromData {
tipo: tipo.clone(),
full_cast: *full_cast,
});
value.create_air_vec(air_vec); value.create_air_vec(air_vec);
if *full_cast {
otherwise.create_air_vec(air_vec); otherwise.create_air_vec(air_vec);
} }
}
AirTree::CastToData { tipo, value } => { AirTree::CastToData { tipo, value } => {
air_vec.push(Air::CastToData { tipo: tipo.clone() }); air_vec.push(Air::CastToData { tipo: tipo.clone() });
value.create_air_vec(air_vec); value.create_air_vec(air_vec);