mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
Fix List.len monomorphization
This commit is contained in:
parent
750523ba5c
commit
f350c0ed52
@ -792,10 +792,7 @@ pub fn constrain_expr(
|
||||
let mut arg_types = Vec::with_capacity(args.len());
|
||||
let mut arg_cons = Vec::with_capacity(args.len());
|
||||
|
||||
let args_iter = args.iter();
|
||||
|
||||
for (index, (arg_var, arg)) in args_iter.enumerate() {
|
||||
let arg_type = Variable(*arg_var);
|
||||
let mut add_arg = |index, arg_type: Type, arg| {
|
||||
let reason = Reason::LowLevelOpArg {
|
||||
op: *op,
|
||||
arg_index: Index::zero_based(index),
|
||||
@ -803,9 +800,14 @@ pub fn constrain_expr(
|
||||
let expected_arg = ForReason(reason, arg_type.clone(), Region::zero());
|
||||
let arg_con = constrain_expr(env, Region::zero(), arg, expected_arg);
|
||||
|
||||
vars.push(*arg_var);
|
||||
arg_types.push(arg_type);
|
||||
arg_cons.push(arg_con);
|
||||
};
|
||||
|
||||
for (index, (arg_var, arg)) in args.iter().enumerate() {
|
||||
vars.push(*arg_var);
|
||||
|
||||
add_arg(index, Variable(*arg_var), arg);
|
||||
}
|
||||
|
||||
let category = Category::LowLevelOpResult(*op);
|
||||
|
@ -177,7 +177,7 @@ lazy_static! {
|
||||
std::sync::Mutex::new(roc_collections::all::MutMap::default());
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Interns {
|
||||
pub module_ids: ModuleIds,
|
||||
pub all_ident_ids: MutMap<ModuleId, IdentIds>,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::layout::{Builtin, Layout, LayoutCache};
|
||||
use crate::layout::{Builtin, Layout, LayoutCache, LayoutProblem};
|
||||
use crate::pattern::{Ctor, Guard, RenderAs, TagId};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
@ -789,8 +789,11 @@ fn from_can<'a>(
|
||||
Content::FlexVar(_) => Layout::Builtin(Builtin::EmptyList),
|
||||
_ => match layout_cache.from_var(arena, elem_var, env.subs, env.pointer_size) {
|
||||
Ok(layout) => layout.clone(),
|
||||
Err(()) => {
|
||||
panic!("TODO gracefully handle List with invalid element layout");
|
||||
Err(problem) => {
|
||||
todo!(
|
||||
"gracefully handle List with element layout problem: {:?}",
|
||||
problem
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -1300,7 +1303,7 @@ fn call_by_name<'a>(
|
||||
Ok(layout) => {
|
||||
args.push((from_can(env, loc_arg.value, procs, layout_cache), layout));
|
||||
}
|
||||
Err(()) => {
|
||||
Err(_) => {
|
||||
// One of this function's arguments code gens to a runtime error,
|
||||
// so attempting to call it will immediately crash.
|
||||
return Expr::RuntimeError("");
|
||||
@ -1323,7 +1326,7 @@ fn call_by_name<'a>(
|
||||
args: args.into_bump_slice(),
|
||||
}
|
||||
}
|
||||
Err(()) => {
|
||||
Err(_) => {
|
||||
// This function code gens to a runtime error,
|
||||
// so attempting to call it will immediately crash.
|
||||
Expr::RuntimeError("")
|
||||
@ -1376,7 +1379,7 @@ pub fn specialize_all<'a>(
|
||||
Ok(proc) => {
|
||||
answer.insert((name, layout), proc);
|
||||
}
|
||||
Err(()) => {
|
||||
Err(_) => {
|
||||
runtime_errors.insert(name);
|
||||
}
|
||||
}
|
||||
@ -1397,7 +1400,7 @@ fn specialize<'a>(
|
||||
layout_cache: &mut LayoutCache<'a>,
|
||||
pending: PendingSpecialization<'a>,
|
||||
partial_proc: PartialProc<'a>,
|
||||
) -> Result<Proc<'a>, ()> {
|
||||
) -> Result<Proc<'a>, LayoutProblem> {
|
||||
let PendingSpecialization {
|
||||
ret_var,
|
||||
fn_var,
|
||||
|
@ -47,13 +47,11 @@ impl<'a> Layout<'a> {
|
||||
content: Content,
|
||||
subs: &Subs,
|
||||
pointer_size: u32,
|
||||
) -> Result<Self, ()> {
|
||||
) -> Result<Self, LayoutProblem> {
|
||||
use roc_types::subs::Content::*;
|
||||
|
||||
match content {
|
||||
var @ FlexVar(_) | var @ RigidVar(_) => {
|
||||
panic!("Layout::new encountered an unresolved {:?}", var);
|
||||
}
|
||||
FlexVar(_) | RigidVar(_) => Err(LayoutProblem::UnboundVar),
|
||||
Structure(flat_type) => layout_from_flat_type(arena, flat_type, subs, pointer_size),
|
||||
|
||||
Alias(Symbol::NUM_INT, args, _) => {
|
||||
@ -70,7 +68,7 @@ impl<'a> Layout<'a> {
|
||||
subs,
|
||||
pointer_size,
|
||||
),
|
||||
Error => Err(()),
|
||||
Error => Err(LayoutProblem::Erroneous),
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +80,7 @@ impl<'a> Layout<'a> {
|
||||
var: Variable,
|
||||
subs: &Subs,
|
||||
pointer_size: u32,
|
||||
) -> Result<Self, ()> {
|
||||
) -> Result<Self, LayoutProblem> {
|
||||
let content = subs.get_without_compacting(var).content;
|
||||
|
||||
Self::new(arena, content, subs, pointer_size)
|
||||
@ -143,7 +141,7 @@ impl<'a> Layout<'a> {
|
||||
/// Avoid recomputing Layout from Variable multiple times.
|
||||
#[derive(Default)]
|
||||
pub struct LayoutCache<'a> {
|
||||
layouts: MutMap<Variable, Result<Layout<'a>, ()>>,
|
||||
layouts: MutMap<Variable, Result<Layout<'a>, LayoutProblem>>,
|
||||
}
|
||||
|
||||
impl<'a> LayoutCache<'a> {
|
||||
@ -156,7 +154,7 @@ impl<'a> LayoutCache<'a> {
|
||||
var: Variable,
|
||||
subs: &Subs,
|
||||
pointer_size: u32,
|
||||
) -> Result<Layout<'a>, ()> {
|
||||
) -> Result<Layout<'a>, LayoutProblem> {
|
||||
// Store things according to the root Variable, to avoid duplicate work.
|
||||
let var = subs.get_root_key_without_compacting(var);
|
||||
|
||||
@ -228,12 +226,23 @@ impl<'a> Builtin<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LayoutProblem {
|
||||
/// We get this error when, after unwrapping all the Attr wrappers,
|
||||
/// we ultimately end up with an unresolved FlexVar. This can happen
|
||||
/// legitimately, for example when resolving a layout for a `List (Attr * *)` -
|
||||
/// which should be an empty list. However, if we get all the way back to
|
||||
/// the top and it's still this error, that's a compiler bug.
|
||||
UnboundVar,
|
||||
Erroneous,
|
||||
}
|
||||
|
||||
fn layout_from_flat_type<'a>(
|
||||
arena: &'a Bump,
|
||||
flat_type: FlatType,
|
||||
subs: &Subs,
|
||||
pointer_size: u32,
|
||||
) -> Result<Layout<'a>, ()> {
|
||||
) -> Result<Layout<'a>, LayoutProblem> {
|
||||
use roc_types::subs::FlatType::*;
|
||||
|
||||
match flat_type {
|
||||
@ -258,19 +267,24 @@ fn layout_from_flat_type<'a>(
|
||||
}
|
||||
Symbol::STR_STR => Ok(Layout::Builtin(Builtin::Str)),
|
||||
Symbol::LIST_LIST => {
|
||||
use roc_types::subs::Content::*;
|
||||
use LayoutProblem::*;
|
||||
|
||||
match subs.get_without_compacting(args[0]).content {
|
||||
FlexVar(_) | RigidVar(_) => Ok(Layout::Builtin(Builtin::EmptyList)),
|
||||
content => {
|
||||
let elem_layout = Layout::new(arena, content, subs, pointer_size)?;
|
||||
let content = subs.get_without_compacting(args[0]).content;
|
||||
|
||||
match Layout::new(arena, content, subs, pointer_size) {
|
||||
Ok(elem_layout) => {
|
||||
// This is a normal list.
|
||||
Ok(Layout::Builtin(Builtin::List(arena.alloc(elem_layout))))
|
||||
}
|
||||
Err(UnboundVar) => {
|
||||
// This is an empty list. That's fine!
|
||||
Ok(Layout::Builtin(Builtin::EmptyList))
|
||||
}
|
||||
Err(Erroneous) => Err(Erroneous),
|
||||
}
|
||||
}
|
||||
Symbol::ATTR_ATTR => {
|
||||
debug_assert!(args.len() == 2);
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
// The first argument is the uniqueness info;
|
||||
// that doesn't affect layout, so we don't need it here.
|
||||
@ -316,7 +330,7 @@ fn layout_from_flat_type<'a>(
|
||||
let field_content = subs.get_without_compacting(field_var).content;
|
||||
let field_layout = match Layout::new(arena, field_content, subs, pointer_size) {
|
||||
Ok(layout) => layout,
|
||||
Err(()) => {
|
||||
Err(_) => {
|
||||
// Invalid field!
|
||||
panic!("TODO gracefully handle record with invalid field.var");
|
||||
}
|
||||
@ -341,7 +355,7 @@ fn layout_from_flat_type<'a>(
|
||||
Boolean(_) => {
|
||||
panic!("TODO make Layout for Boolean");
|
||||
}
|
||||
Erroneous(_) => Err(()),
|
||||
Erroneous(_) => Err(LayoutProblem::Erroneous),
|
||||
EmptyRecord => Ok(Layout::Struct(&[])),
|
||||
}
|
||||
}
|
||||
@ -538,7 +552,7 @@ fn ext_var_is_empty_record(subs: &Subs, ext_var: Variable) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn layout_from_num_content<'a>(content: Content) -> Result<Layout<'a>, ()> {
|
||||
fn layout_from_num_content<'a>(content: Content) -> Result<Layout<'a>, LayoutProblem> {
|
||||
use roc_types::subs::Content::*;
|
||||
use roc_types::subs::FlatType::*;
|
||||
|
||||
@ -566,11 +580,11 @@ fn layout_from_num_content<'a>(content: Content) -> Result<Layout<'a>, ()> {
|
||||
Structure(_) => {
|
||||
panic!("Invalid Num.Num type application: {:?}", content);
|
||||
}
|
||||
Error => Err(()),
|
||||
Error => Err(LayoutProblem::Erroneous),
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, ()> {
|
||||
fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutProblem> {
|
||||
match subs.get_without_compacting(var).content {
|
||||
Content::Structure(flat_type) => match flat_type {
|
||||
FlatType::Apply(Symbol::ATTR_ATTR, args) => {
|
||||
|
@ -132,10 +132,7 @@ pub fn can_expr_with(
|
||||
let loc_expr = match parse_loc_with(&arena, expr_str) {
|
||||
Ok(e) => e,
|
||||
Err(fail) => {
|
||||
let interns = Interns {
|
||||
module_ids: ModuleIds::default(),
|
||||
all_ident_ids: MutMap::default(),
|
||||
};
|
||||
let interns = Interns::default();
|
||||
|
||||
return Err(ParseErrOut {
|
||||
fail,
|
||||
|
@ -544,6 +544,22 @@ impl Content {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[allow(dead_code)]
|
||||
pub fn dbg(self, subs: &Subs) -> Self {
|
||||
let home = roc_module::symbol::ModuleIds::default().get_or_insert(&"#Dbg".into());
|
||||
let mut interns = roc_module::symbol::Interns::default();
|
||||
|
||||
interns.all_ident_ids = roc_module::symbol::IdentIds::exposed_builtins(0);
|
||||
|
||||
eprintln!(
|
||||
"{}",
|
||||
crate::pretty_print::content_to_string(self.clone(), subs, home, &interns)
|
||||
);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
Loading…
Reference in New Issue
Block a user