Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing values into dbg with the pipe operator #7058

Merged
merged 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,123 changes: 291 additions & 832 deletions crates/compiler/can/src/desugar.rs

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion crates/compiler/can/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use roc_collections::{MutMap, VecSet};
use roc_module::ident::{Ident, ModuleName};
use roc_module::symbol::{IdentIdsByModule, ModuleId, PQModuleName, PackageModuleIds, Symbol};
use roc_problem::can::{Problem, RuntimeError};
use roc_region::all::{Loc, Region};
use roc_region::all::{LineInfo, Loc, Region};
use roc_types::subs::Variable;

/// The canonicalization environment for a particular module.
Expand Down Expand Up @@ -44,11 +44,19 @@ pub struct Env<'a> {
pub arena: &'a Bump,

pub opt_shorthand: Option<&'a str>,

pub src: &'a str,

/// Lazily calculated line info. This data is only needed if the code contains calls to `dbg`,
/// otherwise we can leave it as `None` and never pay the cost of scanning the source an extra
/// time.
line_info: &'a mut Option<LineInfo>,
}

impl<'a> Env<'a> {
pub fn new(
arena: &'a Bump,
src: &'a str,
home: ModuleId,
module_path: &'a Path,
dep_idents: &'a IdentIdsByModule,
Expand All @@ -57,6 +65,7 @@ impl<'a> Env<'a> {
) -> Env<'a> {
Env {
arena,
src,
home,
module_path,
dep_idents,
Expand All @@ -69,6 +78,7 @@ impl<'a> Env<'a> {
top_level_symbols: VecSet::default(),
home_params_record: None,
opt_shorthand,
line_info: arena.alloc(None),
}
}

Expand Down Expand Up @@ -219,4 +229,11 @@ impl<'a> Env<'a> {
pub fn problem(&mut self, problem: Problem) {
self.problems.push(problem)
}

pub fn line_info(&mut self) -> &LineInfo {
if self.line_info.is_none() {
*self.line_info = Some(LineInfo::new(self.src));
}
self.line_info.as_ref().unwrap()
}
}
16 changes: 14 additions & 2 deletions crates/compiler/can/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,8 +1209,20 @@ pub fn canonicalize_expr<'a>(
output,
)
}
ast::Expr::Dbg | ast::Expr::DbgStmt(_, _) => {
internal_error!("Dbg should have been desugared by now")
ast::Expr::Dbg => {
// Dbg was not desugared as either part of an `Apply` or a `Pizza` binop, so it's
// invalid.
env.problem(Problem::UnappliedDbg { region });

let invalid_dbg_expr = crate::desugar::desugar_invalid_dbg_expr(env, scope, region);

let (loc_expr, output) =
canonicalize_expr(env, var_store, scope, region, invalid_dbg_expr);

(loc_expr.value, output)
}
ast::Expr::DbgStmt(_, _) => {
internal_error!("DbgStmt should have been desugared by now")
}
ast::Expr::LowLevelDbg((source_location, source), message, continuation) => {
let mut output = Output::default();
Expand Down
12 changes: 2 additions & 10 deletions crates/compiler/can/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ pub fn canonicalize_module_defs<'a>(
);
let mut env = Env::new(
arena,
src,
home,
arena.alloc(Path::new(module_path)),
dep_idents,
Expand All @@ -266,16 +267,7 @@ pub fn canonicalize_module_defs<'a>(
// operators, and then again on *their* nested operators, ultimately applying the
// rules multiple times unnecessarily.

crate::desugar::desugar_defs_node_values(
arena,
&mut scope,
loc_defs,
src,
&mut None,
module_path,
true,
&mut env.problems,
);
crate::desugar::desugar_defs_node_values(&mut env, &mut scope, loc_defs, true);

let mut rigid_variables = RigidVariables::default();

Expand Down
30 changes: 12 additions & 18 deletions crates/compiler/can/tests/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,25 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
Default::default(),
);

let dep_idents = IdentIds::exposed_builtins(0);
let mut env = Env::new(
arena,
expr_str,
home,
Path::new("Test.roc"),
&dep_idents,
&qualified_module_ids,
None,
);

// Desugar operators (convert them to Apply calls, taking into account
// operator precedence and associativity rules), before doing other canonicalization.
//
// If we did this *during* canonicalization, then each time we
// visited a BinOp node we'd recursively try to apply this to each of its nested
// operators, and then again on *their* nested operators, ultimately applying the
// rules multiple times unnecessarily.
let loc_expr = desugar::desugar_expr(
arena,
&mut scope,
&loc_expr,
expr_str,
&mut None,
arena.alloc("TestPath"),
&mut Default::default(),
);
let loc_expr = desugar::desugar_expr(&mut env, &mut scope, &loc_expr);

scope.add_alias(
Symbol::NUM_INT,
Expand All @@ -82,15 +85,6 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
roc_types::types::AliasKind::Structural,
);

let dep_idents = IdentIds::exposed_builtins(0);
let mut env = Env::new(
arena,
home,
Path::new("Test.roc"),
&dep_idents,
&qualified_module_ids,
None,
);
let (loc_expr, output) = canonicalize_expr(
&mut env,
&mut var_store,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
source: crates/compiler/can/tests/test_suffixed.rs
assertion_line: 459
assertion_line: 473
Copy link
Contributor Author

@mulias mulias Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was accidentally committed early as part of a previous PR. I've updated the source code for the test, so the contents of the snapshot have updated, even though it looks like it should be a new test case.

expression: snapshot
---
Defs {
tags: [
Index(2147483648),
],
regions: [
@0-19,
@0-51,
],
space_before: [
Slice(start = 0, length = 0),
Expand All @@ -25,13 +25,13 @@ Defs {
@0-4 Identifier {
ident: "main",
},
@11-19 Defs(
@11-51 Defs(
Defs {
tags: [
Index(2147483648),
],
regions: [
@11-12,
@11-40,
],
space_before: [
Slice(start = 0, length = 0),
Expand All @@ -43,36 +43,98 @@ Defs {
type_defs: [],
value_defs: [
Body(
@11-12 Identifier {
ident: "63",
@11-40 Identifier {
ident: "1",
},
@11-12 Num(
"1",
@11-40 Apply(
@31-38 Var {
module_name: "Num",
ident: "add",
},
[
@11-23 Defs(
Defs {
tags: [
Index(2147483648),
],
regions: [
@11-12,
],
space_before: [
Slice(start = 0, length = 0),
],
space_after: [
Slice(start = 0, length = 0),
],
spaces: [],
type_defs: [],
value_defs: [
Body(
@11-12 Identifier {
ident: "0",
},
@11-12 Num(
"1",
),
),
],
},
@11-23 LowLevelDbg(
(
"test.roc:2",
" ",
),
@11-12 Apply(
@11-12 Var {
module_name: "Inspect",
ident: "toStr",
},
[
@11-12 Var {
module_name: "",
ident: "0",
},
],
Space,
),
@11-12 Var {
module_name: "",
ident: "0",
},
),
),
@39-40 Num(
"2",
),
],
BinOp(
Pizza,
),
),
),
],
},
@11-19 LowLevelDbg(
@11-51 LowLevelDbg(
(
"test.roc:2",
" ",
" main =\n 1\n ",
),
@11-12 Apply(
@11-12 Var {
@11-40 Apply(
@11-40 Var {
module_name: "Inspect",
ident: "toStr",
},
[
@11-12 Var {
@11-40 Var {
module_name: "",
ident: "63",
ident: "1",
},
],
Space,
),
@11-12 Var {
@11-40 Var {
module_name: "",
ident: "63",
ident: "1",
},
),
),
Expand Down
38 changes: 29 additions & 9 deletions crates/compiler/can/tests/test_suffixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,39 @@ mod suffixed_tests {
use bumpalo::Bump;
use insta::assert_snapshot;
use roc_can::desugar::desugar_defs_node_values;
use roc_can::env::Env;
use roc_can::scope::Scope;
use roc_module::symbol::{IdentIds, ModuleIds};
use roc_module::symbol::{IdentIds, ModuleIds, PackageModuleIds};
use roc_parse::test_helpers::parse_defs_with;
use std::path::Path;

macro_rules! run_test {
($src:expr) => {{
let arena = &Bump::new();
let home = ModuleIds::default().get_or_insert(&"Test".into());

let mut scope = Scope::new(
home,
"TestPath".into(),
IdentIds::default(),
Default::default(),
);
let mut defs = parse_defs_with(arena, indoc!($src)).unwrap();
desugar_defs_node_values(

let dep_idents = IdentIds::exposed_builtins(0);
let qualified_module_ids = PackageModuleIds::default();
let mut env = Env::new(
arena,
&mut scope,
&mut defs,
$src,
&mut None,
"test.roc",
true,
&mut Default::default(),
home,
Path::new("test.roc"),
&dep_idents,
&qualified_module_ids,
None,
);

let mut defs = parse_defs_with(arena, indoc!($src)).unwrap();
desugar_defs_node_values(&mut env, &mut scope, &mut defs, true);

let snapshot = format!("{:#?}", &defs);
println!("{}", snapshot);
assert_snapshot!(snapshot);
Expand Down Expand Up @@ -461,6 +468,19 @@ mod suffixed_tests {
);
}

#[test]
fn pizza_dbg() {
run_test!(
r#"
main =
1
|> dbg
|> Num.add 2
|> dbg
"#
)
}

#[test]
fn apply_argument_single() {
run_test!(
Expand Down
Loading