Merge pull request #7310 from joshuawarner32/test_syntax_can

Extend test_syntax to check that canonicalization doesn't panic on the input
This commit is contained in:
Luke Boswell 2024-12-08 21:26:42 +11:00 committed by GitHub
commit a4fd57e54f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
387 changed files with 558 additions and 393 deletions

View file

@ -12,13 +12,16 @@ version.workspace = true
[dependencies]
bumpalo.workspace = true
roc_can.workspace = true
roc_collections.workspace = true
roc_error_macros.workspace = true
roc_fmt.workspace = true
roc_module.workspace = true
roc_parse.workspace = true
roc_region.workspace = true
roc_test_utils.workspace = true
roc_test_utils_dir.workspace = true
roc_types.workspace = true
[dev-dependencies]
indoc.workspace = true

View file

@ -11,7 +11,7 @@ fuzz_target!(|data: &[u8]| {
let ast = input.parse_in(&arena);
if let Ok(ast) = ast {
if !ast.is_malformed() {
input.check_invariants(|_| (), true);
input.check_invariants(|_| (), true, None);
}
}
}

View file

@ -1,14 +1,30 @@
use std::path::Path;
use bumpalo::Bump;
use roc_can::desugar;
use roc_can::env::Env;
use roc_can::expr::canonicalize_expr;
use roc_can::scope::Scope;
use roc_error_macros::set_panic_not_exit;
use roc_fmt::{annotation::Formattable, header::fmt_header, MigrationFlags};
use roc_module::symbol::{IdentIds, Interns, ModuleIds, PackageModuleIds, Symbol};
use roc_parse::header::parse_module_defs;
use roc_parse::parser::Parser;
use roc_parse::parser::SyntaxError;
use roc_parse::state::State;
use roc_parse::test_helpers::parse_loc_with;
use roc_parse::{ast::Malformed, normalize::Normalize};
use roc_parse::{
ast::{Defs, Expr, FullAst, Header, Malformed, SpacesBefore},
header::parse_module_defs,
normalize::Normalize,
parser::{Parser, SyntaxError},
state::State,
test_helpers::{parse_defs_with, parse_expr_with, parse_header_with},
ast::{Defs, Expr, FullAst, Header, SpacesBefore},
test_helpers::{parse_defs_with, parse_header_with},
};
use roc_region::all::Loc;
use roc_region::all::Region;
use roc_test_utils::assert_multiline_str_eq;
use roc_types::{
subs::{VarStore, Variable},
types::{AliasVar, Type},
};
use roc_fmt::Buf;
@ -74,7 +90,7 @@ pub enum Output<'a> {
ModuleDefs(Defs<'a>),
Expr(Expr<'a>),
Expr(Loc<Expr<'a>>),
Full(FullAst<'a>),
}
@ -116,6 +132,81 @@ impl<'a> Output<'a> {
Output::Full { .. } => format!("{self:#?}\n"),
}
}
pub fn canonicalize(&self, arena: &Bump, src: &str) {
set_panic_not_exit(true); // can has a bunch of internal_error! calls
match self {
Output::Header(_) => {}
Output::ModuleDefs(_) => {
// TODO: canonicalize module defs
}
Output::Full(_) => {
// TODO: canonicalize full ast
}
Output::Expr(loc_expr) => {
let mut var_store = VarStore::default();
let qualified_module_ids = PackageModuleIds::default();
let home = ModuleIds::default().get_or_insert(&"Test".into());
let mut scope = Scope::new(
home,
"TestPath".into(),
IdentIds::default(),
Default::default(),
);
let dep_idents = IdentIds::exposed_builtins(0);
let mut env = Env::new(
arena,
src,
home,
Path::new("Test.roc"),
&dep_idents,
&qualified_module_ids,
None,
roc_can::env::FxMode::PurityInference,
);
// 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(&mut env, &mut scope, loc_expr);
scope.add_alias(
Symbol::NUM_INT,
Region::zero(),
vec![Loc::at_zero(AliasVar::unbound(
"a".into(),
Variable::EMPTY_RECORD,
))],
vec![],
Type::EmptyRec,
roc_types::types::AliasKind::Structural,
);
let (_loc_expr, _output) = canonicalize_expr(
&mut env,
&mut var_store,
&mut scope,
Region::zero(),
&loc_expr.value,
);
let mut all_ident_ids = IdentIds::exposed_builtins(1);
all_ident_ids.insert(home, scope.locals.ident_ids);
let _interns = Interns {
module_ids: env.qualified_module_ids.clone().into_module_ids(),
all_ident_ids,
};
}
}
}
}
impl<'a> Malformed for Output<'a> {
@ -163,7 +254,7 @@ impl<'a> Input<'a> {
}
Input::Expr(input) => {
let expr = parse_expr_with(arena, input)?;
let expr = parse_loc_with(arena, input).map_err(|e| e.problem)?;
Ok(Output::Expr(expr))
}
@ -197,6 +288,7 @@ impl<'a> Input<'a> {
&self,
handle_formatted_output: impl Fn(Input),
check_idempotency: bool,
canonicalize_mode: Option<bool>,
) {
let arena = Bump::new();
@ -259,5 +351,27 @@ impl<'a> Input<'a> {
assert_multiline_str_eq!(output.as_ref().as_str(), reformatted.as_ref().as_str());
}
}
if let Some(expect_panic) = canonicalize_mode {
if expect_panic {
let text = self.as_str();
let res = std::panic::catch_unwind(|| {
let new_arena = Bump::new();
actual.canonicalize(&new_arena, text);
});
assert!(
res.is_err(),
"Canonicalize was expected to panic, but it did not. \
If you're running test_snapshots, you may need to remove this test from \
the list of tests that are expected to panic (great!), \
in `fn expect_canonicalize_panics`"
);
} else {
// TODO grab the output here and assert things about it.
// For now we just make sure that it doesn't crash on this input
actual.canonicalize(&arena, self.as_str());
}
}
}
}

View file

@ -1,4 +1,4 @@
Apply(
@0-2 Apply(
@0-1 Tag(
"I",
),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-37 SpaceAfter(
When(
@5-6 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-37 SpaceAfter(
When(
@5-6 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
MalformedIdent(
@0-3 MalformedIdent(
"I.5",
QualifiedTupleAccessor(
@1,

View file

@ -1,4 +1,4 @@
MalformedIdent(
@0-12 MalformedIdent(
"One.Two.Whee",
QualifiedTag(
@12,

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-46 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-55 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-58 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-107 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-22 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
BinOps(
@0-5 BinOps(
[
(
@0-1 Var {

View file

@ -1,4 +1,4 @@
BinOps(
@0-8 BinOps(
[
(
@0-1 Num(

View file

@ -1,4 +1,4 @@
Defs(
@0-8 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
Defs(
@0-9 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
Defs(
@0-9 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-11 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-8 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-42 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-105 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-43 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-13 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-11 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-12 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-16 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-10 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-52 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-49 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-44 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-9 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
Defs(
@0-12 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
Defs(
@0-13 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-10 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-12 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-72 SpaceAfter(
BinOps(
[
(

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-8 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-71 SpaceAfter(
BinOps(
[
(

View file

@ -1,4 +1,4 @@
Apply(
@0-14 Apply(
@0-4 Tag(
"Whee",
),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-10 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Apply(
@0-10 Apply(
@0-4 Tag(
"Whee",
),

View file

@ -1,4 +1,4 @@
Apply(
@0-7 Apply(
@0-1 Var {
module_name: "",
ident: "a",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-12 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Apply(
@0-12 Apply(
@0-4 Var {
module_name: "",
ident: "whee",

View file

@ -1,4 +1,4 @@
Apply(
@0-13 Apply(
@0-5 UnaryOp(
@1-5 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
Apply(
@0-13 Apply(
@0-5 UnaryOp(
@1-5 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-64 SpaceAfter(
Closure(
[
@2-19 As(

View file

@ -1,4 +1,4 @@
SpaceBefore(
@1-18 SpaceBefore(
Backpassing(
[
@1-3 Identifier {

View file

@ -1,4 +1,4 @@
Tuple(
@0-14 Tuple(
[
@1-2 SpaceAfter(
Var {

View file

@ -1,4 +1,4 @@
Defs(
@0-9 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Apply(
@0-6 Apply(
@0-4 Var {
module_name: "",
ident: "whee",

View file

@ -1,4 +1,4 @@
SpaceBefore(
@107-116 SpaceBefore(
SpaceAfter(
Defs(
Defs {

View file

@ -1,4 +1,4 @@
RecordAccess(
@0-9 RecordAccess(
Var {
module_name: "",
ident: "rec",

View file

@ -1,3 +1,3 @@
Tag(
@0-4 Tag(
"Whee",
)

View file

@ -1,4 +1,4 @@
Tuple(
@0-9 Tuple(
[
@1-2 Num(
"1",

View file

@ -1,4 +1,4 @@
Var {
@0-4 Var {
module_name: "",
ident: "whee",
}

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-8 SpaceAfter(
BinOps(
[
(

View file

@ -1,4 +1,4 @@
BinOps(
@0-16 BinOps(
[
(
@0-1 Num(

View file

@ -1,4 +1,4 @@
BinOps(
@0-12 BinOps(
[
(
@0-1 Var {

View file

@ -1,4 +1,4 @@
BinOps(
@0-11 BinOps(
[
(
@0-1 Var {

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-14 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-14 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-8 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-19 SpaceAfter(
Apply(
@0-15 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-8 SpaceAfter(
Apply(
@0-5 Var {
module_name: "",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-10 SpaceAfter(
Closure(
[
@1-2 Tag(

View file

@ -1,4 +1,4 @@
BinOps(
@0-12 BinOps(
[
(
@0-9 SpaceAfter(

View file

@ -1,4 +1,4 @@
Defs(
@0-10 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Closure(
@0-11 Closure(
[
@1-8 RecordDestructure(
[

View file

@ -1,4 +1,4 @@
Closure(
@0-15 Closure(
[
@1-2 Underscore(
"",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-167 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-8 Defs(
Defs {
tags: [
EitherIndex(0),

View file

@ -1,4 +1,4 @@
Defs(
@0-11 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
ParensAround(
@0-8 ParensAround(
SpaceAfter(
Var {
module_name: "",

View file

@ -1,4 +1,4 @@
BinOps(
@0-17 BinOps(
[
(
@0-2 Num(

View file

@ -1,4 +1,4 @@
Defs(
@0-7 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-18 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-7 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
BinOps(
@0-14 BinOps(
[
(
@0-1 SpaceAfter(

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-10 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Backpassing(
@0-11 Backpassing(
[
@0-1 Identifier {
ident: "a",

View file

@ -1,4 +1,4 @@
Closure(
@0-10 Closure(
[
@1-6 Apply(
@1-2 Tag(

View file

@ -1,4 +1,4 @@
Closure(
@0-12 Closure(
[
@1-2 Tag(
"L",

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-13 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-15 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
List(
@0-11 List(
Collection {
items: [],
final_comments: [

View file

@ -1,4 +1,4 @@
BinOps(
@0-15 BinOps(
[
(
@0-1 SpaceAfter(

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-10 SpaceAfter(
BinOps(
[
(

View file

@ -1,3 +1,3 @@
SingleQuote(
@0-3 SingleQuote(
"\u{7}",
)

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-118 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-17 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
Defs(
@0-22 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
Defs(
@0-15 Defs(
Defs {
tags: [
EitherIndex(2147483648),

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-17 SpaceAfter(
Defs(
Defs {
tags: [

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-5 SpaceAfter(
Apply(
@0-3 Dbg,
[

View file

@ -1,4 +1,4 @@
Apply(
@0-9 Apply(
@0-3 Dbg,
[
@3-9 UnaryOp(

View file

@ -1,4 +1,4 @@
SpaceAfter(
@0-11 SpaceAfter(
Apply(
@0-3 Dbg,
[

View file

@ -1,4 +1,4 @@
Apply(
@0-12 Apply(
@0-3 Dbg,
[
@4-7 Dbg,

View file

@ -1,4 +1,4 @@
Defs(
@0-14 Defs(
Defs {
tags: [
EitherIndex(2147483648),

Some files were not shown because too many files have changed in this diff Show more