Skip to content

Commit 3962e45

Browse files
committed
Type of constants in core Terms.
1 parent 939912a commit 3962e45

File tree

13 files changed

+145
-4
lines changed

13 files changed

+145
-4
lines changed

hugr-core/src/export.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,10 @@ impl<'a> Context<'a> {
996996
}
997997
Term::Variable(v) => self.export_type_arg_var(v),
998998
Term::StaticType => self.make_term_apply(model::CORE_STATIC, &[]),
999+
Term::Const(ty) => {
1000+
let ty = self.export_type(ty);
1001+
self.make_term_apply(model::CORE_CONST, &[ty])
1002+
}
9991003
}
10001004
}
10011005

hugr-core/src/extension/resolution/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ pub(super) fn collect_term_exts(
217217
) {
218218
match term {
219219
Term::Runtime(ty) => collect_type_exts(ty, used_extensions, missing_extensions),
220+
Term::Const(ty) => collect_type_exts(ty, used_extensions, missing_extensions),
220221
Term::List(elems) => {
221222
for elem in elems.iter() {
222223
collect_term_exts(elem, used_extensions, missing_extensions);

hugr-core/src/extension/resolution/types_mut.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ pub(super) fn resolve_term_exts(
222222
) -> Result<(), ExtensionResolutionError> {
223223
match term {
224224
Term::Runtime(ty) => resolve_type_exts(node, ty, extensions, used_extensions)?,
225+
Term::Const(ty) => resolve_type_exts(node, ty, extensions, used_extensions)?,
225226
Term::List(children)
226227
| Term::ListConcat(children)
227228
| Term::Tuple(children)

hugr-core/src/import.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,8 +1240,11 @@ impl<'a> Context<'a> {
12401240
return Ok(Term::StaticType);
12411241
}
12421242

1243-
if let Some([]) = self.match_symbol(term_id, model::CORE_CONST)? {
1244-
return Err(error_unsupported!("`{}`", model::CORE_CONST));
1243+
if let Some([ty]) = self.match_symbol(term_id, model::CORE_CONST)? {
1244+
let ty = self
1245+
.import_type(ty)
1246+
.map_err(|err| error_context!(err, "type of a constant"))?;
1247+
return Ok(TypeParam::new_const(ty));
12451248
}
12461249

12471250
if let Some([item_type]) = self.match_symbol(term_id, model::CORE_LIST_TYPE)? {

hugr-core/src/types/serialize.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub(super) enum TypeParamSer {
7979
StaticType,
8080
List { param: Box<Term> },
8181
Tuple { params: ArrayOrTermSer },
82+
Const { ty: Type },
8283
}
8384

8485
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@@ -136,6 +137,7 @@ impl From<Term> for TermSer {
136137
Term::BytesType => TermSer::TypeParam(TypeParamSer::Bytes),
137138
Term::FloatType => TermSer::TypeParam(TypeParamSer::Float),
138139
Term::ListType(param) => TermSer::TypeParam(TypeParamSer::List { param }),
140+
Term::Const(ty) => TermSer::TypeParam(TypeParamSer::Const { ty: *ty }),
139141
Term::Runtime(ty) => TermSer::TypeArg(TypeArgSer::Type { ty }),
140142
Term::TupleType(params) => TermSer::TypeParam(TypeParamSer::Tuple {
141143
params: (*params).into(),
@@ -165,6 +167,7 @@ impl From<TermSer> for Term {
165167
TypeParamSer::Float => Term::FloatType,
166168
TypeParamSer::List { param } => Term::ListType(param),
167169
TypeParamSer::Tuple { params } => Term::TupleType(Box::new(params.into())),
170+
TypeParamSer::Const { ty } => Term::Const(Box::new(ty)),
168171
},
169172
TermSer::TypeArg(arg) => match arg {
170173
TypeArgSer::Type { ty } => Term::Runtime(ty),

hugr-core/src/types/type_param.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ pub enum Term {
139139
/// - see [`Term::new_var_use`]
140140
#[display("{_0}")]
141141
Variable(TermVar),
142+
143+
/// The type of constants for a runtime type.
144+
Const(Box<Type>),
142145
}
143146

144147
impl Term {
@@ -169,6 +172,11 @@ impl Term {
169172
Self::TupleType(Box::new(item_types.into()))
170173
}
171174

175+
/// Creates a new [`Term::Const`] from a runtime type.
176+
pub fn new_const(ty: impl Into<Type>) -> Self {
177+
Self::Const(Box::new(ty.into()))
178+
}
179+
172180
/// Checks if this term is a supertype of another.
173181
///
174182
/// The subtyping relation applies primarily to terms that represent static
@@ -369,6 +377,7 @@ impl Term {
369377
Term::ListType(item_type) => item_type.validate(var_decls),
370378
Term::TupleType(item_types) => item_types.validate(var_decls),
371379
Term::StaticType => Ok(()),
380+
Term::Const(ty) => ty.validate(var_decls),
372381
}
373382
}
374383

@@ -432,6 +441,7 @@ impl Term {
432441
Term::ListType(item_type) => Term::new_list_type(item_type.substitute(t)),
433442
Term::TupleType(item_types) => Term::new_list_type(item_types.substitute(t)),
434443
Term::StaticType => self.clone(),
444+
Term::Const(ty) => Term::new_const(ty.substitute1(t)),
435445
}
436446
}
437447

@@ -593,6 +603,7 @@ impl Transformable for Term {
593603
Term::StaticType => Ok(false),
594604
TypeArg::ListConcat(lists) => lists.transform(tr),
595605
TypeArg::TupleConcat(tuples) => tuples.transform(tr),
606+
Term::Const(ty) => ty.transform(tr),
596607
}
597608
}
598609
}

hugr-py/src/hugr/_serialization/tys.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,14 @@ def deserialize(self) -> tys.TupleParam:
125125
return tys.TupleParam(params=deser_it(self.params))
126126

127127

128+
class ConstParam(BaseTypeParam):
129+
tp: Literal["Const"] = "Const"
130+
ty: Type
131+
132+
def deserialize(self) -> tys.ConstParam:
133+
return tys.ConstParam(ty=self.ty.deserialize())
134+
135+
128136
class TypeParam(RootModel):
129137
"""A type parameter."""
130138

@@ -135,7 +143,8 @@ class TypeParam(RootModel):
135143
| FloatParam
136144
| BytesParam
137145
| ListParam
138-
| TupleParam,
146+
| TupleParam
147+
| ConstParam,
139148
WrapValidator(_json_custom_error_validator),
140149
] = Field(discriminator="tp")
141150

hugr-py/src/hugr/tys.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,23 @@ def to_model(self) -> model.Term:
217217
return model.Apply("core.tuple", [item_types])
218218

219219

220+
@dataclass(frozen=True)
221+
class ConstParam(TypeParam):
222+
"""Type parameter which requires a constant value."""
223+
224+
ty: Type
225+
226+
def _to_serial(self) -> stys.ConstParam:
227+
return stys.ConstParam(ty=self.ty._to_serial_root())
228+
229+
def __str__(self) -> str:
230+
return f"Const({self.ty!s})"
231+
232+
def to_model(self) -> model.Term:
233+
ty = cast(model.Term, self.ty.to_model())
234+
return model.Apply("core.const", [ty])
235+
236+
220237
# ------------------------------------------
221238
# --------------- TypeArg ------------------
222239
# ------------------------------------------

specification/schema/hugr_schema_live.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,25 @@
345345
"title": "Const",
346346
"type": "object"
347347
},
348+
"ConstParam": {
349+
"additionalProperties": true,
350+
"properties": {
351+
"tp": {
352+
"const": "Const",
353+
"default": "Const",
354+
"title": "Tp",
355+
"type": "string"
356+
},
357+
"ty": {
358+
"$ref": "#/$defs/Type"
359+
}
360+
},
361+
"required": [
362+
"ty"
363+
],
364+
"title": "ConstParam",
365+
"type": "object"
366+
},
348367
"CustomConst": {
349368
"additionalProperties": true,
350369
"properties": {
@@ -1781,6 +1800,7 @@
17811800
"mapping": {
17821801
"BoundedNat": "#/$defs/BoundedNatParam",
17831802
"Bytes": "#/$defs/BytesParam",
1803+
"Const": "#/$defs/ConstParam",
17841804
"Float": "#/$defs/FloatParam",
17851805
"List": "#/$defs/ListParam",
17861806
"String": "#/$defs/StringParam",
@@ -1810,6 +1830,9 @@
18101830
},
18111831
{
18121832
"$ref": "#/$defs/TupleParam"
1833+
},
1834+
{
1835+
"$ref": "#/$defs/ConstParam"
18131836
}
18141837
],
18151838
"required": [

specification/schema/hugr_schema_strict_live.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,25 @@
345345
"title": "Const",
346346
"type": "object"
347347
},
348+
"ConstParam": {
349+
"additionalProperties": false,
350+
"properties": {
351+
"tp": {
352+
"const": "Const",
353+
"default": "Const",
354+
"title": "Tp",
355+
"type": "string"
356+
},
357+
"ty": {
358+
"$ref": "#/$defs/Type"
359+
}
360+
},
361+
"required": [
362+
"ty"
363+
],
364+
"title": "ConstParam",
365+
"type": "object"
366+
},
348367
"CustomConst": {
349368
"additionalProperties": false,
350369
"properties": {
@@ -1781,6 +1800,7 @@
17811800
"mapping": {
17821801
"BoundedNat": "#/$defs/BoundedNatParam",
17831802
"Bytes": "#/$defs/BytesParam",
1803+
"Const": "#/$defs/ConstParam",
17841804
"Float": "#/$defs/FloatParam",
17851805
"List": "#/$defs/ListParam",
17861806
"String": "#/$defs/StringParam",
@@ -1810,6 +1830,9 @@
18101830
},
18111831
{
18121832
"$ref": "#/$defs/TupleParam"
1833+
},
1834+
{
1835+
"$ref": "#/$defs/ConstParam"
18131836
}
18141837
],
18151838
"required": [

0 commit comments

Comments
 (0)