Merge branch 'main' into clippy-1.74

This commit is contained in:
Ayaz 2023-12-02 20:09:06 -06:00 committed by GitHub
commit aaba3f4d82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
320 changed files with 11155 additions and 18862 deletions

View file

@ -670,12 +670,12 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
},
Dbg {
loc_condition,
loc_message,
loc_continuation,
variable,
symbol,
} => Dbg {
loc_condition: Box::new(loc_condition.map(|e| go_help!(e))),
loc_message: Box::new(loc_message.map(|e| go_help!(e))),
loc_continuation: Box::new(loc_continuation.map(|e| go_help!(e))),
variable: sub!(*variable),
symbol: *symbol,

View file

@ -718,6 +718,7 @@ fn canonicalize_opaque<'a>(
let ability_region = ability.region;
// Op := {} has [Eq]
let (ability, members) = match ability.value {
ast::TypeAnnotation::Apply(module_name, ident, []) => {
match make_apply_symbol(env, region, scope, module_name, ident) {

View file

@ -213,6 +213,48 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
)
}
fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
let alloc_pat = |it| env.arena.alloc(Loc::at(DERIVED_REGION, it));
let alloc_expr = |it| env.arena.alloc(Loc::at(DERIVED_REGION, it));
let payload = "#payload";
// \@Opaq payload
let opaque_ref = alloc_pat(ast::Pattern::OpaqueRef(at_opaque));
let opaque_apply_pattern = ast::Pattern::Apply(
opaque_ref,
&*env
.arena
.alloc([Loc::at(DERIVED_REGION, ast::Pattern::Identifier(payload))]),
);
// Inspect.toInspector payload
let call_member = alloc_expr(ast::Expr::Apply(
alloc_expr(ast::Expr::Var {
module_name: "Inspect",
ident: "toInspector",
}),
&*env.arena.alloc([&*alloc_expr(ast::Expr::Var {
module_name: "",
ident: payload,
})]),
roc_module::called_via::CalledVia::Space,
));
// TODO: change the derived implementation to be something that includes the opaque symbol in
// the derivation, e.g. something like
//
// \@Opaq payload ->
// Inspect.opaqueWrapper "toString symbol" payload
// \@Opaq payload -> Inspect.toInspector payload
ast::Expr::Closure(
env.arena
.alloc([Loc::at(DERIVED_REGION, opaque_apply_pattern)]),
call_member,
)
}
pub const DERIVED_REGION: Region = Region::zero();
pub(crate) fn synthesize_member_impl<'a>(
@ -232,6 +274,10 @@ pub(crate) fn synthesize_member_impl<'a>(
Symbol::DECODE_DECODER => (format!("#{opaque_name}_decoder"), decoder(env, at_opaque)),
Symbol::HASH_HASH => (format!("#{opaque_name}_hash"), hash(env, at_opaque)),
Symbol::BOOL_IS_EQ => (format!("#{opaque_name}_isEq"), is_eq(env, at_opaque)),
Symbol::INSPECT_TO_INSPECTOR => (
format!("#{opaque_name}_toInspector"),
to_inspector(env, at_opaque),
),
other => internal_error!("{:?} is not a derivable ability member!", other),
};

View file

@ -269,7 +269,7 @@ pub enum Expr {
},
Dbg {
loc_condition: Box<Loc<Expr>>,
loc_message: Box<Loc<Expr>>,
loc_continuation: Box<Loc<Expr>>,
variable: Variable,
symbol: Symbol,
@ -1062,10 +1062,10 @@ pub fn canonicalize_expr<'a>(
})
}
ast::Expr::RecordBuilder(_) => {
unreachable!("RecordBuilder should have been desugared by now")
internal_error!("RecordBuilder should have been desugared by now")
}
ast::Expr::Backpassing(_, _, _) => {
unreachable!("Backpassing should have been desugared by now")
internal_error!("Backpassing should have been desugared by now")
}
ast::Expr::Closure(loc_arg_patterns, loc_body_expr) => {
let (closure_data, output) =
@ -1246,11 +1246,14 @@ pub fn canonicalize_expr<'a>(
output,
)
}
ast::Expr::Dbg(condition, continuation) => {
ast::Expr::Dbg(_, _) => {
internal_error!("Dbg should have been desugared by now")
}
ast::Expr::LowLevelDbg(message, continuation) => {
let mut output = Output::default();
let (loc_condition, output1) =
canonicalize_expr(env, var_store, scope, condition.region, &condition.value);
let (loc_message, output1) =
canonicalize_expr(env, var_store, scope, message.region, &message.value);
let (loc_continuation, output2) = canonicalize_expr(
env,
@ -1263,17 +1266,17 @@ pub fn canonicalize_expr<'a>(
output.union(output1);
output.union(output2);
// the symbol is used to bind the condition `x = condition`, and identify this `dbg`.
// the symbol is used to bind the message `x = message`, and identify this `dbg`.
// That would cause issues if we dbg a variable, like `dbg y`, because in the IR we
// cannot alias variables. Hence, we make the dbg use that same variable `y`
let symbol = match &loc_condition.value {
let symbol = match &loc_message.value {
Expr::Var(symbol, _) => *symbol,
_ => scope.gen_unique_symbol(),
};
(
Dbg {
loc_condition: Box::new(loc_condition),
loc_message: Box::new(loc_message),
loc_continuation: Box::new(loc_continuation),
variable: var_store.fresh(),
symbol,
@ -2094,14 +2097,14 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
}
Dbg {
loc_condition,
loc_message,
loc_continuation,
variable,
symbol,
} => {
let loc_condition = Loc {
region: loc_condition.region,
value: inline_calls(var_store, loc_condition.value),
let loc_message = Loc {
region: loc_message.region,
value: inline_calls(var_store, loc_message.value),
};
let loc_continuation = Loc {
@ -2110,7 +2113,7 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
};
Dbg {
loc_condition: Box::new(loc_condition),
loc_message: Box::new(loc_message),
loc_continuation: Box::new(loc_continuation),
variable,
symbol,
@ -2338,10 +2341,10 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
loc_answer.value
}
Some(_) => {
unreachable!("Tried to inline a non-function");
internal_error!("Tried to inline a non-function");
}
None => {
unreachable!(
internal_error!(
"Tried to inline a builtin that wasn't registered: {:?}",
symbol
);
@ -2395,6 +2398,7 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
| ast::Expr::MalformedClosure => true,
// Newlines are disallowed inside interpolation, and these all require newlines
ast::Expr::Dbg(_, _)
| ast::Expr::LowLevelDbg(_, _)
| ast::Expr::Defs(_, _)
| ast::Expr::Expect(_, _)
| ast::Expr::When(_, _)
@ -3328,7 +3332,7 @@ impl crate::traverse::Visitor for ExpectCollector {
.insert(loc_condition.region, lookups_in_cond.to_vec());
}
Expr::Dbg {
loc_condition,
loc_message,
variable,
symbol,
..
@ -3336,7 +3340,7 @@ impl crate::traverse::Visitor for ExpectCollector {
let lookup = DbgLookup {
symbol: *symbol,
var: *variable,
region: loc_condition.region,
region: loc_message.region,
ability_info: None,
};

View file

@ -996,7 +996,7 @@ fn fix_values_captured_in_closure_expr(
..
}
| Dbg {
loc_condition,
loc_message: loc_condition,
loc_continuation,
..
} => {

View file

@ -8,7 +8,8 @@ use roc_module::called_via::{BinOp, CalledVia};
use roc_module::ident::ModuleName;
use roc_parse::ast::Expr::{self, *};
use roc_parse::ast::{
AssignedField, Collection, RecordBuilderField, StrLiteral, StrSegment, ValueDef, WhenBranch,
AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef,
WhenBranch,
};
use roc_region::all::{Loc, Region};
@ -70,7 +71,10 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
use ValueDef::*;
match def {
Body(loc_pattern, loc_expr) => Body(loc_pattern, desugar_expr(arena, loc_expr)),
Body(loc_pattern, loc_expr) => Body(
desugar_loc_pattern(arena, loc_pattern),
desugar_expr(arena, loc_expr),
),
ann @ Annotation(_, _) => *ann,
AnnotatedBody {
ann_pattern,
@ -238,7 +242,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
}
Closure(loc_patterns, loc_ret) => arena.alloc(Loc {
region: loc_expr.region,
value: Closure(loc_patterns, desugar_expr(arena, loc_ret)),
value: Closure(
desugar_loc_patterns(arena, loc_patterns),
desugar_expr(arena, loc_ret),
),
}),
Backpassing(loc_patterns, loc_body, loc_ret) => {
// loc_patterns <- loc_body
@ -249,7 +256,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
let desugared_body = desugar_expr(arena, loc_body);
let desugared_ret = desugar_expr(arena, loc_ret);
let closure = Expr::Closure(loc_patterns, desugared_ret);
let desugared_loc_patterns = desugar_loc_patterns(arena, loc_patterns);
let closure = Expr::Closure(desugared_loc_patterns, desugared_ret);
let loc_closure = Loc::at(loc_expr.region, closure);
match &desugared_body.value {
@ -352,10 +360,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
for branch in branches.iter() {
let desugared = desugar_expr(arena, &branch.value);
let mut alternatives = Vec::with_capacity_in(branch.patterns.len(), arena);
alternatives.extend(branch.patterns.iter().copied());
let desugared_expr = desugar_expr(arena, &branch.value);
let desugared_patterns = desugar_loc_patterns(arena, branch.patterns);
let desugared_guard = if let Some(guard) = &branch.guard {
Some(*desugar_expr(arena, guard))
@ -363,11 +369,9 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
None
};
let alternatives = alternatives.into_bump_slice();
desugared_branches.push(&*arena.alloc(WhenBranch {
patterns: alternatives,
value: *desugared,
patterns: desugared_patterns,
value: *desugared_expr,
guard: desugared_guard,
}));
}
@ -457,13 +461,48 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
})
}
Dbg(condition, continuation) => {
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
// Desugars a `dbg x` statement into
// `roc_dbg (Inspect.toDbgStr (Inspect.inspect x))`
let desugared_continuation = &*arena.alloc(desugar_expr(arena, continuation));
let region = condition.region;
// TODO desugar this in canonicalization instead, so we can work
// in terms of integers exclusively and not need to create strings
// which canonicalization then needs to look up, check if they're exposed, etc
let inspect = Var {
module_name: ModuleName::INSPECT,
ident: "inspect",
};
let loc_inspect_fn_var = arena.alloc(Loc {
value: inspect,
region,
});
let desugared_inspect_args = arena.alloc([desugar_expr(arena, condition)]);
let inspector = arena.alloc(Loc {
value: Apply(loc_inspect_fn_var, desugared_inspect_args, CalledVia::Space),
region,
});
let to_dbg_str = Var {
module_name: ModuleName::INSPECT,
ident: "toDbgStr",
};
let loc_to_dbg_str_fn_var = arena.alloc(Loc {
value: to_dbg_str,
region,
});
let to_dbg_str_args = arena.alloc([&*inspector]);
let dbg_str = arena.alloc(Loc {
value: Apply(loc_to_dbg_str_fn_var, to_dbg_str_args, CalledVia::Space),
region,
});
arena.alloc(Loc {
value: Dbg(desugared_condition, desugared_continuation),
value: LowLevelDbg(dbg_str, desugared_continuation),
region: loc_expr.region,
})
}
LowLevelDbg(_, _) => unreachable!("Only exists after desugaring"),
}
}
@ -544,6 +583,85 @@ fn desugar_field<'a>(
}
}
fn desugar_loc_patterns<'a>(
arena: &'a Bump,
loc_patterns: &'a [Loc<Pattern<'a>>],
) -> &'a [Loc<Pattern<'a>>] {
Vec::from_iter_in(
loc_patterns.iter().map(|loc_pattern| Loc {
region: loc_pattern.region,
value: desugar_pattern(arena, loc_pattern.value),
}),
arena,
)
.into_bump_slice()
}
fn desugar_loc_pattern<'a>(
arena: &'a Bump,
loc_pattern: &'a Loc<Pattern<'a>>,
) -> &'a Loc<Pattern<'a>> {
arena.alloc(Loc {
region: loc_pattern.region,
value: desugar_pattern(arena, loc_pattern.value),
})
}
fn desugar_pattern<'a>(arena: &'a Bump, pattern: Pattern<'a>) -> Pattern<'a> {
use roc_parse::ast::Pattern::*;
match pattern {
Identifier(_)
| Tag(_)
| OpaqueRef(_)
| NumLiteral(_)
| NonBase10Literal { .. }
| FloatLiteral(_)
| StrLiteral(_)
| Underscore(_)
| SingleQuote(_)
| ListRest(_)
| Malformed(_)
| MalformedIdent(_, _)
| QualifiedIdentifier { .. } => pattern,
Apply(tag, arg_patterns) => {
// Skip desugaring the tag, it should either be a Tag or OpaqueRef
let desugared_arg_patterns = Vec::from_iter_in(
arg_patterns.iter().map(|arg_pattern| Loc {
region: arg_pattern.region,
value: desugar_pattern(arena, arg_pattern.value),
}),
arena,
)
.into_bump_slice();
Apply(tag, desugared_arg_patterns)
}
RecordDestructure(field_patterns) => {
RecordDestructure(field_patterns.map_items(arena, |field_pattern| Loc {
region: field_pattern.region,
value: desugar_pattern(arena, field_pattern.value),
}))
}
RequiredField(name, field_pattern) => {
RequiredField(name, desugar_loc_pattern(arena, field_pattern))
}
OptionalField(name, expr) => OptionalField(name, desugar_expr(arena, expr)),
Tuple(patterns) => Tuple(patterns.map_items(arena, |elem_pattern| Loc {
region: elem_pattern.region,
value: desugar_pattern(arena, elem_pattern.value),
})),
List(patterns) => List(patterns.map_items(arena, |elem_pattern| Loc {
region: elem_pattern.region,
value: desugar_pattern(arena, elem_pattern.value),
})),
As(sub_pattern, symbol) => As(desugar_loc_pattern(arena, sub_pattern), symbol),
SpaceBefore(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
SpaceAfter(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
}
}
struct RecordBuilderArg<'a> {
closure: &'a Loc<Expr<'a>>,
apply_exprs: Vec<'a, &'a Loc<Expr<'a>>>,

View file

@ -387,11 +387,11 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
}
Expr::Dbg {
variable,
loc_condition,
loc_message,
loc_continuation,
symbol: _,
} => {
visitor.visit_expr(&loc_condition.value, loc_condition.region, *variable);
visitor.visit_expr(&loc_message.value, loc_message.region, *variable);
visitor.visit_expr(
&loc_continuation.value,
loc_continuation.region,