From 4fae99d767411ec09548cce6f75a34d06c36e267 Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Tue, 7 May 2024 15:27:05 +0800 Subject: [PATCH] fix: simplify all substructure (#248) --- crates/tinymist-query/src/analysis/ty.rs | 47 ++++++++++++------- crates/tinymist-query/src/analysis/ty/def.rs | 23 ++++----- .../src/fixtures/type_check/external.typ | 10 ++++ .../snaps/test@control_flow.typ.snap | 2 +- .../type_check/snaps/test@external.typ.snap | 14 ++++++ 5 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 crates/tinymist-query/src/fixtures/type_check/external.typ create mode 100644 crates/tinymist-query/src/fixtures/type_check/snaps/test@external.typ.snap diff --git a/crates/tinymist-query/src/analysis/ty.rs b/crates/tinymist-query/src/analysis/ty.rs index 7b43edd9..89b5f1f1 100644 --- a/crates/tinymist-query/src/analysis/ty.rs +++ b/crates/tinymist-query/src/analysis/ty.rs @@ -385,14 +385,14 @@ impl<'a, 'w> TypeChecker<'a, 'w> { let op = unary.op(); - let expr = Box::new(self.check_expr_in(unary.expr().span(), root)); - let ty = match op { - ast::UnOp::Pos => FlowUnaryType::Pos(expr), - ast::UnOp::Neg => FlowUnaryType::Neg(expr), - ast::UnOp::Not => FlowUnaryType::Not(expr), + let lhs = Box::new(self.check_expr_in(unary.expr().span(), root)); + let op = match op { + ast::UnOp::Pos => UnaryOp::Pos, + ast::UnOp::Neg => UnaryOp::Neg, + ast::UnOp::Not => UnaryOp::Not, }; - Some(FlowType::Unary(ty)) + Some(FlowType::Unary(FlowUnaryType { op, lhs })) } fn check_binary(&mut self, root: LinkedNode<'_>) -> Option { @@ -635,7 +635,10 @@ impl<'a, 'w> TypeChecker<'a, 'w> { let body = self.check_expr_in(contextual.body().span(), root); - Some(FlowType::Unary(FlowUnaryType::Context(Box::new(body)))) + Some(FlowType::Unary(FlowUnaryType { + op: UnaryOp::Context, + lhs: Box::new(body), + })) } fn check_conditional(&mut self, root: LinkedNode<'_>) -> Option { @@ -1640,19 +1643,30 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> { })) } FlowType::Unary(u) => { - let u2 = u.clone(); - - FlowType::Unary(u2) + let lhs = self.transform(u.lhs(), pol); + FlowType::Unary(FlowUnaryType { + op: u.op, + lhs: Box::new(lhs), + }) } FlowType::Binary(b) => { - let b2 = b.clone(); + let (lhs, rhs) = b.repr(); + let lhs = self.transform(lhs, pol); + let rhs = self.transform(rhs, pol); - FlowType::Binary(b2) + FlowType::Binary(FlowBinaryType { + op: b.op, + operands: Box::new((lhs, rhs)), + }) } FlowType::If(i) => { - let i2 = i.clone(); + let i2 = *i.clone(); - FlowType::If(i2) + FlowType::If(Box::new(FlowIfType { + cond: self.transform(&i2.cond, pol), + then: self.transform(&i2.then, pol), + else_: self.transform(&i2.else_, pol), + })) } FlowType::Union(v) => { let v2 = v.iter().map(|ty| self.transform(ty, pol)).collect(); @@ -1665,9 +1679,10 @@ impl<'a, 'b> TypeSimplifier<'a, 'b> { FlowType::Field(Box::new((x, self.transform(&y, pol), z))) } FlowType::At(a) => { - let a2 = a.clone(); + let FlowAt(at) = a.clone(); + let atee = self.transform(&at.0, pol); - FlowType::At(a2) + FlowType::At(FlowAt(Box::new((atee, at.1)))) } FlowType::Value(v) => FlowType::Value(v.clone()), diff --git a/crates/tinymist-query/src/analysis/ty/def.rs b/crates/tinymist-query/src/analysis/ty/def.rs index 900c4b45..81b48ff9 100644 --- a/crates/tinymist-query/src/analysis/ty/def.rs +++ b/crates/tinymist-query/src/analysis/ty/def.rs @@ -214,22 +214,23 @@ impl<'a> Iterator for UnionIter<'a> { } } +#[derive(Debug, Clone, Copy, Hash)] +pub(crate) enum UnaryOp { + Pos, + Neg, + Not, + Context, +} + #[derive(Debug, Clone, Hash)] -pub(crate) enum FlowUnaryType { - Pos(Box), - Neg(Box), - Not(Box), - Context(Box), +pub(crate) struct FlowUnaryType { + pub op: UnaryOp, + pub lhs: Box, } impl FlowUnaryType { pub fn lhs(&self) -> &FlowType { - match self { - FlowUnaryType::Pos(e) => e, - FlowUnaryType::Neg(e) => e, - FlowUnaryType::Not(e) => e, - FlowUnaryType::Context(e) => e, - } + &self.lhs } } diff --git a/crates/tinymist-query/src/fixtures/type_check/external.typ b/crates/tinymist-query/src/fixtures/type_check/external.typ new file mode 100644 index 00000000..81733688 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/type_check/external.typ @@ -0,0 +1,10 @@ +// path: base.typ +#let bad-instantiate(x) = { + let y; let z; let w; + x + y + z + w +}; +----- +#import "base.typ": * +#let prefix(title: none) = { + bad-instantiate(title) +} \ No newline at end of file diff --git a/crates/tinymist-query/src/fixtures/type_check/snaps/test@control_flow.typ.snap b/crates/tinymist-query/src/fixtures/type_check/snaps/test@control_flow.typ.snap index 96953fa8..d7730235 100644 --- a/crates/tinymist-query/src/fixtures/type_check/snaps/test@control_flow.typ.snap +++ b/crates/tinymist-query/src/fixtures/type_check/snaps/test@control_flow.typ.snap @@ -5,7 +5,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/control_flow.typ --- "x0" = FlowIfType { cond: true, then: 1, else_: None } "x1" = FlowIfType { cond: false, then: 2, else_: None } -"x2" = Context(FlowIfType { cond: FlowBinaryType { op: Gt, operands: (Any, 0) }, then: 1, else_: 2 }) +"x2" = FlowUnaryType { op: Context, lhs: FlowIfType { cond: FlowBinaryType { op: Gt, operands: (Any, 0) }, then: 1, else_: 2 } } --- 5..7 -> @x0 31..33 -> @x1 diff --git a/crates/tinymist-query/src/fixtures/type_check/snaps/test@external.typ.snap b/crates/tinymist-query/src/fixtures/type_check/snaps/test@external.typ.snap new file mode 100644 index 00000000..490bdb55 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/type_check/snaps/test@external.typ.snap @@ -0,0 +1,14 @@ +--- +source: crates/tinymist-query/src/analysis.rs +expression: result +input_file: crates/tinymist-query/src/fixtures/type_check/external.typ +--- +"bad-instantiate" = Any +"prefix" = (, title: ( ⪯ Any)) -> FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (Any, Infer) }, Infer) }, Infer) } +"title" = None +--- +27..33 -> @prefix +34..39 -> @title +53..68 -> (@bad-instantiate | (Any) -> FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (Any, Infer) }, Infer) }, Infer) }) +53..75 -> FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (FlowBinaryType { op: Add, operands: (Any, Infer) }, Infer) }, Infer) } +69..74 -> @title