Skip to content

Commit

Permalink
Experiment: make substitute consume the receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
acl-cqc committed Sep 5, 2023
1 parent 2a7d49b commit dd00c63
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl ExtensionSet {
Ok(())
}

pub(crate) fn substitute(&self, args: &[TypeArg]) -> Self {
pub(crate) fn substitute(self, args: &[TypeArg]) -> Self {
Self::from_iter(self.0.iter().flat_map(|e| match as_typevar(e) {
None => vec![e.clone()].into_iter(),
Some(i) => match args.get(i) {
Expand Down
2 changes: 1 addition & 1 deletion src/extension/type_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ impl<'a> CustomSignatureFunc for OpDefTypeScheme<'a> {
_misc: &std::collections::HashMap<String, serde_yaml::Value>,
) -> Result<FunctionType, SignatureError> {
check_type_args(args, &self.params).map_err(SignatureError::TypeArgMismatch)?;
Ok(self.body.substitute(self.exts, args))
Ok(self.body.clone().substitute(self.exts, args))
}
}
11 changes: 6 additions & 5 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,12 @@ impl Type {
/// contains a type with an incorrect [TypeBound], or there are not enough `args`.
/// These conditions can be detected ahead of time by [Type::validate]ing against the [TypeParam]s
/// and [check_type_args]ing the [TypeArg]s against the [TypeParam]s.
pub(crate) fn substitute(&self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
match &self.0 {
pub(crate) fn substitute(self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
match self.0 {
TypeEnum::Prim(PrimType::Alias(_)) | TypeEnum::Sum(SumType::Simple { .. }) => {
self.clone()
}
TypeEnum::Prim(PrimType::Variable(idx, bound)) => match args.get(*idx) {
TypeEnum::Prim(PrimType::Variable(idx, bound)) => match args.get(idx) {
Some(TypeArg::Type(t)) => t.clone(),
Some(v) => panic!(
"Value of variable {:?} did not match cached param {}",
Expand All @@ -335,8 +335,9 @@ impl Type {
}
}

fn subst_row(row: &TypeRow, exts: &ExtensionRegistry, args: &[TypeArg]) -> TypeRow {
row.iter()
fn subst_row(row: TypeRow, exts: &ExtensionRegistry, args: &[TypeArg]) -> TypeRow {
row.into_owned()
.into_iter()
.map(|t| t.substitute(exts, args))
.collect::<Vec<_>>()
.into()
Expand Down
6 changes: 3 additions & 3 deletions src/types/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl CustomType {
})
}

pub(super) fn substitute(&self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
pub(super) fn substitute(self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
let bound = self
.get_type_def(exts)
.expect("validate should rule this out")
Expand All @@ -97,11 +97,11 @@ impl CustomType {
Self {
args: self
.args
.iter()
.into_iter()
.map(|arg| arg.substitute(exts, args))
.collect(),
bound,
..self.clone()
..self
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ impl FunctionType {
self.extension_reqs.validate(type_vars)
}

pub(crate) fn substitute(&self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
pub(crate) fn substitute(self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
FunctionType {
input: subst_row(&self.input, exts, args),
output: subst_row(&self.output, exts, args),
input: subst_row(self.input, exts, args),
output: subst_row(self.output, exts, args),
extension_reqs: self.extension_reqs.substitute(args),
}
}
Expand Down
22 changes: 13 additions & 9 deletions src/types/type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,22 +153,26 @@ impl TypeArg {
}
}

pub(super) fn substitute(&self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
pub(super) fn substitute(self, exts: &ExtensionRegistry, args: &[TypeArg]) -> Self {
match self {
TypeArg::Type(t) => TypeArg::Type(t.substitute(exts, args)),
TypeArg::BoundedNat(_) => self.clone(), // We do not allow variables as bounds on BoundedNat's
TypeArg::Opaque(CustomTypeArg { typ, .. }) => {
TypeArg::BoundedNat(_) => self, // We do not allow variables as bounds on BoundedNat's
TypeArg::Opaque(cta) => {
let typ = &cta.typ;
// The type must be equal to that declared (in a TypeParam) by the instantiated TypeDef,
// so cannot contain variables declared by the instantiator (providing the TypeArgs)
debug_assert_eq!(&typ.substitute(exts, args), typ);
self.clone()
}
TypeArg::Sequence(elems) => {
TypeArg::Sequence(elems.iter().map(|ta| ta.substitute(exts, args)).collect())
debug_assert_eq!(&typ.clone().substitute(exts, args), typ);
TypeArg::Opaque(cta)
}
TypeArg::Sequence(elems) => TypeArg::Sequence(
elems
.into_iter()
.map(|ta| ta.substitute(exts, args))
.collect(),
),
TypeArg::Extensions(es) => TypeArg::Extensions(es.substitute(args)),
TypeArg::Variable(TypeArgVariable { idx, .. }) => args
.get(*idx)
.get(idx)
.expect("validate + check_type_args should rule this out")
.clone(),
}
Expand Down

0 comments on commit dd00c63

Please sign in to comment.