Skip to content

Commit

Permalink
fix!: Add serde tag to TypeParam enum (#722)
Browse files Browse the repository at this point in the history
Needed for Pydantic serialisation.

BREAKING_CHANGES: Turn the `TypeParam` enum variants into struct
variants
  • Loading branch information
mark-koch authored Nov 27, 2023
1 parent b9b7edf commit d00dc3f
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 62 deletions.
10 changes: 5 additions & 5 deletions src/extension/op_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ mod test {
fn op_def_with_type_scheme() -> Result<(), Box<dyn std::error::Error>> {
let list_def = EXTENSION.get_type(&LIST_TYPENAME).unwrap();
let mut e = Extension::new(EXT_ID);
const TP: TypeParam = TypeParam::Type(TypeBound::Any);
const TP: TypeParam = TypeParam::Type { b: TypeBound::Any };
let list_of_var =
Type::new_extension(list_def.instantiate(vec![TypeArg::new_var_use(0, TP)])?);
const OP_NAME: SmolStr = SmolStr::new_inline("Reverse");
Expand Down Expand Up @@ -501,7 +501,7 @@ mod test {
&self,
arg_values: &[TypeArg],
) -> Result<PolyFuncType, SignatureError> {
const TP: TypeParam = TypeParam::Type(TypeBound::Any);
const TP: TypeParam = TypeParam::Type { b: TypeBound::Any };
let [TypeArg::BoundedNat { n }] = arg_values else {
return Err(SignatureError::InvalidTypeArgs);
};
Expand Down Expand Up @@ -546,12 +546,12 @@ mod test {
vec![Type::new_tuple(tyvars)]
))
);
def.validate_args(&args, &PRELUDE_REGISTRY, &[TypeParam::Type(TypeBound::Eq)])
def.validate_args(&args, &PRELUDE_REGISTRY, &[TypeBound::Eq.into()])
.unwrap();

// quick sanity check that we are validating the args - note changed bound:
assert_eq!(
def.validate_args(&args, &PRELUDE_REGISTRY, &[TypeParam::Type(TypeBound::Any)]),
def.validate_args(&args, &PRELUDE_REGISTRY, &[TypeBound::Any.into()]),
Err(SignatureError::TypeVarDoesNotMatchDeclaration {
actual: TypeBound::Any.into(),
cached: TypeBound::Eq.into()
Expand Down Expand Up @@ -587,7 +587,7 @@ mod test {
"SimpleOp".into(),
"".into(),
PolyFuncType::new(
vec![TypeParam::Type(TypeBound::Any)],
vec![TypeBound::Any.into()],
FunctionType::new_endo(vec![Type::new_var_use(0, TypeBound::Any)]),
),
)?;
Expand Down
4 changes: 2 additions & 2 deletions src/extension/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl SignatureFromArgs for ArrayOpCustom {
let other_row = vec![array_type(TypeArg::BoundedNat { n }, elem_ty_var.clone())];

Ok(PolyFuncType::new(
vec![TypeParam::Type(TypeBound::Any)],
vec![TypeBound::Any.into()],
FunctionType::new(var_arg_row, other_row),
))
}
Expand Down Expand Up @@ -57,7 +57,7 @@ lazy_static! {
prelude
.add_type(
SmolStr::new_inline("array"),
vec![ TypeParam::max_nat(),TypeParam::Type(TypeBound::Any)],
vec![ TypeParam::max_nat(), TypeBound::Any.into()],
"array".into(),
TypeDefBound::FromParams(vec![1]),
)
Expand Down
6 changes: 4 additions & 2 deletions src/extension/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ mod test {
fn test_instantiate_typedef() {
let def = TypeDef {
name: "MyType".into(),
params: vec![TypeParam::Type(TypeBound::Copyable)],
params: vec![TypeParam::Type {
b: TypeBound::Copyable,
}],
extension: "MyRsrc".try_into().unwrap(),
description: "Some parameterised type".into(),
bound: TypeDefBound::FromParams(vec![0]),
Expand All @@ -200,7 +202,7 @@ mod test {
Err(SignatureError::TypeArgMismatch(
TypeArgError::TypeMismatch {
arg: TypeArg::Type { ty: QB_T },
param: TypeParam::Type(TypeBound::Copyable)
param: TypeBound::Copyable.into()
}
))
);
Expand Down
14 changes: 8 additions & 6 deletions src/hugr/validate/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ fn invalid_types() {
let mut e = Extension::new(name.clone());
e.add_type(
"MyContainer".into(),
vec![TypeParam::Type(TypeBound::Copyable)],
vec![TypeBound::Copyable.into()],
"".into(),
TypeDefBound::Explicit(TypeBound::Any),
)
Expand Down Expand Up @@ -709,7 +709,7 @@ fn invalid_types() {
assert_eq!(
validate_to_sig_error(element_outside_bound),
SignatureError::TypeArgMismatch(TypeArgError::TypeMismatch {
param: TypeParam::Type(TypeBound::Copyable),
param: TypeBound::Copyable.into(),
arg: TypeArg::Type { ty: valid }
})
);
Expand Down Expand Up @@ -813,7 +813,7 @@ fn typevars_declared() -> Result<(), Box<dyn std::error::Error>> {
let f = FunctionBuilder::new(
"myfunc",
PolyFuncType::new(
[TypeParam::Type(TypeBound::Any)],
[TypeBound::Any.into()],
FunctionType::new_endo(vec![Type::new_var_use(0, TypeBound::Any)]),
),
)?;
Expand All @@ -823,7 +823,7 @@ fn typevars_declared() -> Result<(), Box<dyn std::error::Error>> {
let f = FunctionBuilder::new(
"myfunc",
PolyFuncType::new(
[TypeParam::Type(TypeBound::Any)],
[TypeBound::Any.into()],
FunctionType::new_endo(vec![Type::new_var_use(1, TypeBound::Any)]),
),
)?;
Expand All @@ -833,7 +833,7 @@ fn typevars_declared() -> Result<(), Box<dyn std::error::Error>> {
let f = FunctionBuilder::new(
"myfunc",
PolyFuncType::new(
[TypeParam::Type(TypeBound::Any)],
[TypeBound::Any.into()],
FunctionType::new_endo(vec![Type::new_var_use(1, TypeBound::Copyable)]),
),
)?;
Expand Down Expand Up @@ -884,7 +884,9 @@ fn nested_typevars() -> Result<(), Box<dyn std::error::Error>> {
#[test]
fn no_polymorphic_consts() -> Result<(), Box<dyn std::error::Error>> {
use crate::std_extensions::collections;
const BOUND: TypeParam = TypeParam::Type(TypeBound::Copyable);
const BOUND: TypeParam = TypeParam::Type {
b: TypeBound::Copyable,
};
let list_of_var = Type::new_extension(
collections::EXTENSION
.get_type(&collections::LIST_TYPENAME)
Expand Down
2 changes: 1 addition & 1 deletion src/std_extensions/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl CustomConst for ListValue {
crate::values::downcast_equal_consts(self, other)
}
}
const TP: TypeParam = TypeParam::Type(TypeBound::Any);
const TP: TypeParam = TypeParam::Type { b: TypeBound::Any };

fn extension() -> Extension {
let mut extension = Extension::new(EXTENSION_NAME);
Expand Down
6 changes: 2 additions & 4 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,7 @@ impl Type {
TypeEnum::Alias(_) => Ok(()),
TypeEnum::Extension(custy) => custy.validate(extension_registry, var_decls),
TypeEnum::Function(ft) => ft.validate(extension_registry, var_decls),
TypeEnum::Variable(idx, bound) => {
check_typevar_decl(var_decls, *idx, &TypeParam::Type(*bound))
}
TypeEnum::Variable(idx, bound) => check_typevar_decl(var_decls, *idx, &(*bound).into()),
}
}

Expand All @@ -337,7 +335,7 @@ impl Type {
pub(crate) trait Substitution {
/// Apply to a variable of kind [TypeParam::Type]
fn apply_typevar(&self, idx: usize, bound: TypeBound) -> Type {
let TypeArg::Type { ty } = self.apply_var(idx, &TypeParam::Type(bound)) else {
let TypeArg::Type { ty } = self.apply_var(idx, &bound.into()) else {
panic!("Variable was not a type - try validate() first")
};
ty
Expand Down
47 changes: 25 additions & 22 deletions src/types/poly_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ pub(crate) mod test {
#[test]
fn test_opaque() -> Result<(), SignatureError> {
let list_def = EXTENSION.get_type(&LIST_TYPENAME).unwrap();
let tyvar = TypeArg::new_var_use(0, TypeParam::Type(TypeBound::Any));
let tyvar = TypeArg::new_var_use(0, TypeBound::Any.into());
let list_of_var = Type::new_extension(list_def.instantiate([tyvar.clone()])?);
let list_len = PolyFuncType::new_validated(
[TypeParam::Type(TypeBound::Any)],
[TypeBound::Any.into()],
FunctionType::new(vec![list_of_var], vec![USIZE_T]),
&REGISTRY,
)?;
Expand Down Expand Up @@ -278,7 +278,7 @@ pub(crate) mod test {
#[test]
fn test_mismatched_args() -> Result<(), SignatureError> {
let ar_def = PRELUDE.get_type("array").unwrap();
let typarams = [TypeParam::max_nat(), TypeParam::Type(TypeBound::Any)];
let typarams = [TypeParam::max_nat(), TypeBound::Any.into()];
let [tyvar, szvar] =
[0, 1].map(|i| TypeArg::new_var_use(i, typarams.get(i).unwrap().clone()));

Expand Down Expand Up @@ -333,21 +333,25 @@ pub(crate) mod test {
#[test]
fn test_misused_variables() -> Result<(), SignatureError> {
// Variables in args have different bounds from variable declaration
let tv = TypeArg::new_var_use(0, TypeParam::Type(TypeBound::Copyable));
let tv = TypeArg::new_var_use(0, TypeBound::Copyable.into());
let list_def = EXTENSION.get_type(&LIST_TYPENAME).unwrap();
let body_type = id_fn(Type::new_extension(list_def.instantiate([tv])?));
for decl in [
TypeParam::Extensions,
TypeParam::List(Box::new(TypeParam::max_nat())),
TypeParam::Opaque(USIZE_CUSTOM_T),
TypeParam::Tuple(vec![TypeParam::Type(TypeBound::Any), TypeParam::max_nat()]),
TypeParam::List {
param: Box::new(TypeParam::max_nat()),
},
TypeParam::Opaque { ty: USIZE_CUSTOM_T },
TypeParam::Tuple {
params: vec![TypeBound::Any.into(), TypeParam::max_nat()],
},
] {
let invalid_ts =
PolyFuncType::new_validated([decl.clone()], body_type.clone(), &REGISTRY);
assert_eq!(
invalid_ts.err(),
Some(SignatureError::TypeVarDoesNotMatchDeclaration {
cached: TypeParam::Type(TypeBound::Copyable),
cached: TypeBound::Copyable.into(),
actual: decl
})
);
Expand Down Expand Up @@ -416,15 +420,14 @@ pub(crate) mod test {
#[test]
fn test_bound_covariance() -> Result<(), SignatureError> {
decl_accepts_rejects_var(
TypeParam::Type(TypeBound::Copyable),
&[
TypeParam::Type(TypeBound::Copyable),
TypeParam::Type(TypeBound::Eq),
],
&[TypeParam::Type(TypeBound::Any)],
TypeBound::Copyable.into(),
&[TypeBound::Copyable.into(), TypeBound::Eq.into()],
&[TypeBound::Any.into()],
)?;

let list_of_tys = |b| TypeParam::List(Box::new(TypeParam::Type(b)));
let list_of_tys = |b: TypeBound| TypeParam::List {
param: Box::new(b.into()),
};
decl_accepts_rejects_var(
list_of_tys(TypeBound::Copyable),
&[list_of_tys(TypeBound::Copyable), list_of_tys(TypeBound::Eq)],
Expand Down Expand Up @@ -457,7 +460,7 @@ pub(crate) mod test {
fn partial_instantiate() -> Result<(), SignatureError> {
// forall A,N.(Array<A,N> -> A)
let array_max = PolyFuncType::new_validated(
vec![TypeParam::Type(TypeBound::Any), TypeParam::max_nat()],
vec![TypeBound::Any.into(), TypeParam::max_nat()],
FunctionType::new(
vec![array_type(
TypeArg::new_var_use(1, TypeParam::max_nat()),
Expand Down Expand Up @@ -509,11 +512,11 @@ pub(crate) mod test {
// forall A. A -> (forall C. C -> List(Tuple(C, A))
pub(crate) fn nested_func() -> PolyFuncType {
PolyFuncType::new_validated(
vec![TypeParam::Type(TypeBound::Any)],
vec![TypeBound::Any.into()],
FunctionType::new(
vec![Type::new_var_use(0, TypeBound::Any)],
vec![Type::new_function(new_pf1(
TypeParam::Type(TypeBound::Copyable),
TypeBound::Copyable.into(),
Type::new_var_use(0, TypeBound::Copyable),
list_of_tup(
Type::new_var_use(0, TypeBound::Copyable),
Expand All @@ -535,7 +538,7 @@ pub(crate) mod test {
let outer_applied = FunctionType::new(
vec![arg.clone()], // This had index 0, but is replaced
vec![Type::new_function(new_pf1(
TypeParam::Type(TypeBound::Copyable),
TypeBound::Copyable.into(),
// We are checking that the substitution has been applied to the right var
// - NOT to the inner_var which has index 0 here
Type::new_var_use(0, TypeBound::Copyable),
Expand All @@ -557,7 +560,7 @@ pub(crate) mod test {

// Now substitute in a free var from further outside
const FREE: usize = 3;
const TP_EQ: TypeParam = TypeParam::Type(TypeBound::Eq);
const TP_EQ: TypeParam = TypeParam::Type { b: TypeBound::Eq };
let res = outer
.instantiate(&[TypeArg::new_var_use(FREE, TP_EQ)], &REGISTRY)
.unwrap();
Expand All @@ -567,7 +570,7 @@ pub(crate) mod test {
FunctionType::new(
vec![Type::new_var_use(FREE, TypeBound::Eq)],
vec![Type::new_function(new_pf1(
TypeParam::Type(TypeBound::Copyable),
TypeBound::Copyable.into(),
Type::new_var_use(0, TypeBound::Copyable), // unchanged
list_of_tup(
Type::new_var_use(0, TypeBound::Copyable),
Expand Down Expand Up @@ -600,7 +603,7 @@ pub(crate) mod test {
vec![rhs(FREE)], // Input: forall TEQ. (TEQ -> Array(TEQ, FREE))
// Output: forall C. C -> List(Tuple(C, Input))
vec![Type::new_function(new_pf1(
TypeParam::Type(TypeBound::Copyable),
TypeBound::Copyable.into(),
Type::new_var_use(0, TypeBound::Copyable),
list_of_tup(
Type::new_var_use(0, TypeBound::Copyable), // not renumbered...
Expand Down
Loading

0 comments on commit d00dc3f

Please sign in to comment.