Skip to content

Commit 88210fe

Browse files
Added delayed constraint
1 parent 9ea5a21 commit 88210fe

File tree

2 files changed

+121
-3
lines changed

2 files changed

+121
-3
lines changed

src/instantiation/concrete_typecheck.rs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::ops::Deref;
22

3-
use crate::alloc::{zip_eq, zip_eq3};
3+
use sus_proc_macro::get_builtin_type;
4+
5+
use crate::alloc::{zip_eq, zip_eq3, UUID};
46
use crate::errors::ErrorInfoObject;
57
use crate::flattening::{DeclarationKind, ExpressionSource, WireReferenceRoot, WrittenType};
68
use crate::linker::LinkInfo;
@@ -52,7 +54,7 @@ impl InstantiationContext<'_, '_> {
5254
)))
5355
}
5456

55-
fn typecheck_all_wires(&self) {
57+
fn typecheck_all_wires(&self, delayed_constraints: &mut DelayedConstraintsList<Self>) {
5658
for this_wire_id in self.wires.id_range() {
5759
let this_wire = &self.wires[this_wire_id];
5860
let span = self.md.get_instruction_span(this_wire.original_instruction);
@@ -104,6 +106,14 @@ impl InstantiationContext<'_, '_> {
104106
}
105107
&RealWireDataSource::BinaryOp { op, left, right } => {
106108
// TODO overloading
109+
// Typecheck generic INT
110+
delayed_constraints.push(BinaryOpTypecheckConstraint::new(
111+
op,
112+
left,
113+
right,
114+
this_wire_id,
115+
span,
116+
));
107117
let ((in_left, in_right), out) = match op {
108118
BinaryOperator::And => {
109119
((BOOL_CONCRETE_TYPE, BOOL_CONCRETE_TYPE), BOOL_CONCRETE_TYPE)
@@ -249,7 +259,7 @@ impl InstantiationContext<'_, '_> {
249259
delayed_constraints.push(SubmoduleTypecheckConstraint { sm_id });
250260
}
251261

252-
self.typecheck_all_wires();
262+
self.typecheck_all_wires(&mut delayed_constraints);
253263

254264
delayed_constraints.resolve_delayed_constraints(self);
255265

@@ -500,3 +510,79 @@ impl DelayedConstraint<InstantiationContext<'_, '_>> for SubmoduleTypecheckConst
500510
.error(submod_instr.get_most_relevant_span(), message);
501511
}
502512
}
513+
514+
#[derive(Debug)]
515+
struct BinaryOpTypecheckConstraint {
516+
_op: BinaryOperator,
517+
left: UUID<WireIDMarker>,
518+
right: UUID<WireIDMarker>,
519+
out: UUID<WireIDMarker>,
520+
span: Span,
521+
}
522+
523+
impl BinaryOpTypecheckConstraint {
524+
fn new(
525+
_op: BinaryOperator,
526+
left: UUID<WireIDMarker>,
527+
right: UUID<WireIDMarker>,
528+
out: UUID<WireIDMarker>,
529+
span: Span,
530+
) -> Self {
531+
Self {
532+
_op,
533+
left,
534+
right,
535+
out,
536+
span,
537+
}
538+
}
539+
}
540+
541+
impl DelayedConstraint<InstantiationContext<'_, '_>> for BinaryOpTypecheckConstraint {
542+
fn try_apply(&mut self, context: &mut InstantiationContext<'_, '_>) -> DelayedConstraintStatus {
543+
if context.wires[self.out].typ.contains_unknown()
544+
|| context.wires[self.left].typ.contains_unknown()
545+
|| context.wires[self.right].typ.contains_unknown()
546+
{
547+
return DelayedConstraintStatus::NoProgress;
548+
}
549+
let left_size = context.wires[self.left]
550+
.typ
551+
.try_fully_substitute(&context.type_substitutor)
552+
.unwrap()
553+
.unwrap_named()
554+
.template_args[UUID::from_hidden_value(0)]
555+
.unwrap_value()
556+
.unwrap_integer()
557+
.clone();
558+
let right_size = context.wires[self.right]
559+
.typ
560+
.try_fully_substitute(&context.type_substitutor)
561+
.unwrap()
562+
.unwrap_named()
563+
.template_args[UUID::from_hidden_value(0)]
564+
.unwrap_value()
565+
.unwrap_integer()
566+
.clone();
567+
let out_size = left_size + right_size;
568+
let mut template_args: FlatAlloc<ConcreteType, TemplateIDMarker> = FlatAlloc::new();
569+
template_args.alloc(ConcreteType::new_int(out_size));
570+
let expected_out = ConcreteType::Named(ConcreteGlobalReference {
571+
id: get_builtin_type!("int"),
572+
template_args,
573+
});
574+
575+
context.type_substitutor.unify_report_error(
576+
&context.wires[self.out].typ,
577+
&expected_out,
578+
self.span,
579+
"binary output",
580+
);
581+
582+
DelayedConstraintStatus::Resolved
583+
}
584+
585+
fn report_could_not_resolve_error(&self, _context: &InstantiationContext<'_, '_>) {
586+
todo!()
587+
}
588+
}

src/typing/concrete_type.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use crate::value::Value;
99
use super::template::TVec;
1010

1111
use super::type_inference::ConcreteTypeVariableID;
12+
use super::type_inference::ConcreteTypeVariableIDMarker;
13+
use super::type_inference::HindleyMilner;
14+
use super::type_inference::TypeSubstitutor;
1215

1316
pub const BOOL_CONCRETE_TYPE: ConcreteType = ConcreteType::Named(ConcreteGlobalReference {
1417
id: get_builtin_type!("bool"),
@@ -47,13 +50,30 @@ pub enum ConcreteType {
4750
}
4851

4952
impl ConcreteType {
53+
pub fn new_int(int: BigInt) -> Self {
54+
Self::Value(Value::Integer(int))
55+
}
5056
#[track_caller]
5157
pub fn unwrap_value(&self) -> &Value {
5258
let ConcreteType::Value(v) = self else {
5359
unreachable!("unwrap_value on {self:?}")
5460
};
5561
v
5662
}
63+
#[track_caller]
64+
pub fn unwrap_named(&self) -> &ConcreteGlobalReference<TypeUUID> {
65+
let ConcreteType::Named(v) = self else {
66+
unreachable!("unwrap_named")
67+
};
68+
v
69+
}
70+
pub fn down_array(&self) -> &ConcreteType {
71+
let ConcreteType::Array(arr_box) = self else {
72+
unreachable!("Must be an array!")
73+
};
74+
let (sub, _sz) = arr_box.deref();
75+
sub
76+
}
5777
pub fn contains_unknown(&self) -> bool {
5878
match self {
5979
ConcreteType::Named(global_ref) => global_ref
@@ -103,4 +123,16 @@ impl ConcreteType {
103123
1 // todo!() // Named structs are not implemented yet
104124
}
105125
}
126+
pub fn try_fully_substitute(
127+
&self,
128+
substitutor: &TypeSubstitutor<Self, ConcreteTypeVariableIDMarker>,
129+
) -> Option<Self> {
130+
if self.contains_unknown() {
131+
None
132+
} else {
133+
let mut self_clone = self.clone();
134+
self_clone.fully_substitute(substitutor);
135+
Some(self_clone)
136+
}
137+
}
106138
}

0 commit comments

Comments
 (0)