mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Merge remote-tracking branch 'origin/main' into expect-print-values
This commit is contained in:
commit
7c6cc97cd4
6 changed files with 49 additions and 69 deletions
|
@ -11,7 +11,6 @@ use crate::annotation::OwnedNamedOrAble;
|
|||
use crate::derive;
|
||||
use crate::env::Env;
|
||||
use crate::expr::get_lookup_symbols;
|
||||
use crate::expr::AccessorData;
|
||||
use crate::expr::AnnotatedMark;
|
||||
use crate::expr::ClosureData;
|
||||
use crate::expr::Declarations;
|
||||
|
@ -2256,36 +2255,6 @@ fn canonicalize_pending_body<'a>(
|
|||
(loc_can_expr, def_references)
|
||||
}
|
||||
|
||||
// Turn f = .foo into f = \rcd -[f]-> rcd.foo
|
||||
(
|
||||
Pattern::Identifier(defined_symbol)
|
||||
| Pattern::AbilityMemberSpecialization {
|
||||
ident: defined_symbol,
|
||||
..
|
||||
},
|
||||
ast::Expr::RecordAccessorFunction(field),
|
||||
) => {
|
||||
let (loc_can_expr, can_output) = (
|
||||
Loc::at(
|
||||
loc_expr.region,
|
||||
Accessor(AccessorData {
|
||||
name: *defined_symbol,
|
||||
function_var: var_store.fresh(),
|
||||
record_var: var_store.fresh(),
|
||||
ext_var: var_store.fresh(),
|
||||
closure_var: var_store.fresh(),
|
||||
field_var: var_store.fresh(),
|
||||
field: (*field).into(),
|
||||
}),
|
||||
),
|
||||
Output::default(),
|
||||
);
|
||||
let def_references = DefReferences::Value(can_output.references.clone());
|
||||
output.union(can_output);
|
||||
|
||||
(loc_can_expr, def_references)
|
||||
}
|
||||
|
||||
_ => {
|
||||
let (loc_can_expr, can_output) =
|
||||
canonicalize_expr(env, var_store, scope, loc_expr.region, &loc_expr.value);
|
||||
|
|
|
@ -132,11 +132,6 @@ pub struct PartialProcs<'a> {
|
|||
/// maps a function name (symbol) to an index
|
||||
symbols: Vec<'a, Symbol>,
|
||||
|
||||
/// An entry (a, b) means `a` directly references the lambda value of `b`,
|
||||
/// i.e. this came from a `let a = b in ...` where `b` was defined as a
|
||||
/// lambda earlier.
|
||||
references: Vec<'a, (Symbol, Symbol)>,
|
||||
|
||||
partial_procs: Vec<'a, PartialProc<'a>>,
|
||||
}
|
||||
|
||||
|
@ -144,7 +139,6 @@ impl<'a> PartialProcs<'a> {
|
|||
fn new_in(arena: &'a Bump) -> Self {
|
||||
Self {
|
||||
symbols: Vec::new_in(arena),
|
||||
references: Vec::new_in(arena),
|
||||
partial_procs: Vec::new_in(arena),
|
||||
}
|
||||
}
|
||||
|
@ -152,16 +146,7 @@ impl<'a> PartialProcs<'a> {
|
|||
self.symbol_to_id(symbol).is_some()
|
||||
}
|
||||
|
||||
fn symbol_to_id(&self, mut symbol: Symbol) -> Option<PartialProcId> {
|
||||
while let Some(real_symbol) = self
|
||||
.references
|
||||
.iter()
|
||||
.find(|(alias, _)| *alias == symbol)
|
||||
.map(|(_, real)| real)
|
||||
{
|
||||
symbol = *real_symbol;
|
||||
}
|
||||
|
||||
fn symbol_to_id(&self, symbol: Symbol) -> Option<PartialProcId> {
|
||||
self.symbols
|
||||
.iter()
|
||||
.position(|s| *s == symbol)
|
||||
|
@ -193,21 +178,6 @@ impl<'a> PartialProcs<'a> {
|
|||
id
|
||||
}
|
||||
|
||||
pub fn insert_alias(&mut self, alias: Symbol, real_symbol: Symbol) {
|
||||
debug_assert!(
|
||||
!self.contains_key(alias),
|
||||
"{:?} is inserted as a partial proc twice: that's a bug!",
|
||||
alias,
|
||||
);
|
||||
debug_assert!(
|
||||
self.contains_key(real_symbol),
|
||||
"{:?} is not a partial proc or another alias: that's a bug!",
|
||||
real_symbol,
|
||||
);
|
||||
|
||||
self.references.push((alias, real_symbol));
|
||||
}
|
||||
|
||||
pub fn drain(self) -> impl Iterator<Item = (Symbol, PartialProc<'a>)> {
|
||||
debug_assert_eq!(self.symbols.len(), self.partial_procs.len());
|
||||
|
||||
|
@ -4146,13 +4116,7 @@ fn specialize_naked_symbol<'a>(
|
|||
std::vec::Vec::new(),
|
||||
layout_cache,
|
||||
assigned,
|
||||
match hole {
|
||||
Stmt::Jump(id, _) => env
|
||||
.arena
|
||||
.alloc(Stmt::Jump(*id, env.arena.alloc([assigned]))),
|
||||
Stmt::Ret(_) => env.arena.alloc(Stmt::Ret(assigned)),
|
||||
hole => hole,
|
||||
},
|
||||
hole,
|
||||
);
|
||||
|
||||
return result;
|
||||
|
|
|
@ -1092,3 +1092,22 @@ fn update_record_that_is_a_thunk_single_field() {
|
|||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn toplevel_accessor_fn_thunk() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
ra = .field
|
||||
|
||||
main =
|
||||
ra { field : 15u8 }
|
||||
"#
|
||||
),
|
||||
15u8,
|
||||
u8
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
procedure Test.1 ():
|
||||
let Test.6 : {} = Struct {};
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.2 (Test.7):
|
||||
ret Test.7;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.9 : U8 = 15i64;
|
||||
let Test.4 : {} = CallByName Test.1;
|
||||
let Test.3 : U8 = CallByName Test.2 Test.9;
|
||||
ret Test.3;
|
|
@ -2082,3 +2082,17 @@ fn anonymous_closure_lifted_to_named_issue_2403() {
|
|||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn toplevel_accessor_fn_thunk() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
ra = .field
|
||||
|
||||
main =
|
||||
ra { field : 15u8 }
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2135,6 +2135,8 @@ impl Subs {
|
|||
is_inhabited(self, var)
|
||||
}
|
||||
|
||||
/// Is the ground constructor (in the layout-determination sense) of this type a function?
|
||||
/// That is, is this a function modulo aliases and opaques?
|
||||
pub fn is_function(&self, mut var: Variable) -> bool {
|
||||
loop {
|
||||
match self.get_content_without_compacting(var) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue